Skip to content

Modernize NetLib: Python 3.10+, type hints, Pydantic, and Poetry - #24

Merged
jtdub merged 5 commits into
masterfrom
claude/modernize-python-ci-EnwcK
Jan 29, 2026
Merged

Modernize NetLib: Python 3.10+, type hints, Pydantic, and Poetry#24
jtdub merged 5 commits into
masterfrom
claude/modernize-python-ci-EnwcK

Conversation

@jtdub

@jtdub jtdub commented Jan 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR modernizes the NetLib project by upgrading to Python 3.10+, adding comprehensive type hints, implementing Pydantic validation, migrating to Poetry for dependency management, and setting up a modern CI/CD pipeline with GitHub Actions.

Key Changes

Core Library Updates

  • Python 3.10+ Only: Removed Python 2.x and 3.5-3.9 support; updated all code to use modern Python features (type unions with |, f-strings, etc.)
  • Type Hints: Added complete type annotations to all functions and methods for better IDE support and type safety
  • Pydantic Models: Created netlib/models.py with validation models for:
    • SSH and Telnet connection configurations
    • Command responses and enable mode responses
    • Credential data validation
  • Input Validation: All connection parameters now validated through Pydantic models with proper constraints (port ranges, buffer sizes, delays)

Dependency Management

  • Poetry Migration: Replaced setup.py and requirements.txt with pyproject.toml
  • Updated Dependencies:
    • paramiko ^3.5.0
    • keyring ^25.5.0
    • pydantic ^2.10.5
    • Added dev dependencies: pytest, ruff, mypy, pylint with type stubs

Code Quality & Linting

  • Ruff Configuration: Added .ruff.toml with comprehensive linting rules (100 char line length, import sorting, naming conventions, etc.)
  • Type Checking: Configured mypy with strict settings in pyproject.toml
  • Pylint Integration: Added pylint configuration with sensible defaults for the project
  • Code Formatting: All code reformatted to follow ruff standards

CI/CD Pipeline

  • GitHub Actions: Created .github/workflows/ci.yml with:
    • Lint job: ruff format check, ruff lint, mypy, pylint
    • Test job: pytest on Python 3.10, 3.11, 3.12 with coverage reporting to Codecov
    • Dependency caching for faster builds
  • Removed Travis CI: Deleted .travis.yml (outdated Python 2.7, 3.5, 3.6 support)

Documentation

  • Comprehensive README: Completely rewritten with:
    • Modern badges (CI status, Python version, code style)
    • Feature highlights
    • Installation instructions (pip, Poetry, from source)
    • Quick start examples for SSH, Telnet, and KeyRing
    • Full API reference
    • Development setup and testing instructions
    • Migration guide from v0.1.x
    • Contributing guidelines

Project Structure

  • Package Exports: Updated netlib/__init__.py to export main classes (SSH, Telnet, KeyRing)
  • PEP 561 Support: Added py.typed marker file for type checking support
  • .gitignore: Expanded with comprehensive Python, IDE, and OS-specific patterns

Backward Compatibility

  • API remains largely compatible with v0.1.x
  • String parameters (e.g., buffer="8192") are automatically converted to proper types
  • Pydantic validation provides clear error messages for invalid inputs

Notable Implementation Details

  • Connection classes now use proper type hints with union types (int | str | float)
  • Telnet and SSH classes properly handle None states for connections
  • KeyRing class uses Pydantic validation for credential data
  • All imports are properly organized and documented
  • Comprehensive docstrings added to all public methods
  • Test suite structure created with pytest fixtures and configuration

Version

Bumped from v0.1.0 to v0.2.0 to reflect the significant modernization and breaking changes (Python 3.10+ requirement).

https://claude.ai/code/session_019D1TUrg1xPGse1HsS8pgqQ

This major update modernizes the netlib codebase to align with current Python best practices:

## Core Changes
- Upgrade minimum Python version to 3.10+
- Remove all Python 2.x support and legacy code
- Add full type hints throughout the codebase (PEP 484)
- Implement Pydantic v2 for robust input/output validation

## Package Management
- Migrate from setuptools to Poetry
- Remove setup.py and requirements.txt
- Add pyproject.toml with complete project configuration
- Include py.typed marker for PEP 561 compliance

## Testing & Quality Assurance
- Replace unittest with pytest framework
- Add comprehensive test suite with 7 test modules
- Implement pytest-cov for coverage reporting
- Add pytest-mock for better mocking support

## Linting & Type Checking
- Add ruff for fast, modern linting and formatting
- Configure mypy for strict type checking
- Add pylint for additional code quality checks
- Create .ruff.toml configuration file

## CI/CD
- Remove Travis CI (.travis.yml)
- Implement GitHub Actions workflow
- Add multi-version testing (Python 3.10, 3.11, 3.12)
- Include automated linting, type checking, and testing
- Add codecov integration for coverage reporting

## Code Improvements
- Add Pydantic models for connection configurations
- Modernize class syntax (remove explicit object inheritance)
- Use modern string formatting (f-strings)
- Add comprehensive docstrings
- Improve error handling and type safety

## Documentation
- Complete README.md rewrite with modern badges
- Add detailed API reference
- Include migration guide from v0.1.x
- Add development setup instructions
- Document all new features and tools

Version bumped to 0.2.0 to reflect breaking changes.

https://claude.ai/code/session_019D1TUrg1xPGse1HsS8pgqQ
## Security Enhancement - SecretStr for Passwords
- Update all password fields to use Pydantic SecretStr type
- Models updated:
  - ConnectionConfig.password now SecretStr
  - CredentialsData.password and .enable now SecretStr
- Classes updated to handle SecretStr:
  - SSH class stores password as _password (SecretStr)
  - Telnet class stores password as _password (SecretStr)
  - Both classes use .get_secret_value() when using passwords
  - set_enable() methods accept str | SecretStr for flexibility
  - KeyRing.get_creds() returns plain strings (for backward compatibility)
  - Internal validation ensures passwords aren't empty
- Benefits:
  - Passwords not exposed in logs or repr()
  - Better security for credential handling
  - IDE autocomplete won't leak password values

## Dynamic Version Management
- __version__ now reads from pyproject.toml
- Uses importlib.metadata when package is installed
- Falls back to reading pyproject.toml during development
- Added tomli dependency for Python <3.11 (Python 3.11+ uses built-in tomllib)
- Graceful fallback to "0.2.0-dev" if neither method works

## Test Updates
- Updated all tests to use .get_secret_value() for password assertions
- Tests now properly validate SecretStr behavior
- Maintained backward compatibility in test patterns

https://claude.ai/code/session_019D1TUrg1xPGse1HsS8pgqQ
## Code Quality Improvements
- Run ruff format to apply consistent code formatting
- Fix all ruff linting issues automatically
- Remove unused imports (typing.Any, pytest, MagicMock)
- Fix import sorting across all modules
- Sort __all__ exports alphabetically

## Manual Fixes
- Remove unnecessary variable assignment before return in SSH.set_enable()
- Add noqa comment for intentional function-level imports in test_imports.py
- Update pyproject.toml per-file-ignores configuration

## Results
- All ruff format checks pass ✓
- All ruff linting checks pass ✓
- Code follows consistent style guidelines
- Improved code maintainability and readability

https://claude.ai/code/session_019D1TUrg1xPGse1HsS8pgqQ
## Type Checking Fixes (mypy)
- Add SecretStr() wrapper when creating Pydantic models
- Import SecretStr in user_keyring.py
- Convert passwords to SecretStr in SSH/Telnet constructors
- Add explicit type annotations for recv() calls to satisfy mypy
- Replace deprecated --strict-concatenate with --extra-checks
- Fix unused type: ignore comments in __init__.py

## Code Quality Fixes
- Fix sendall() to accept bytes instead of strings (encode strings)
- Remove unnecessary UTF-8 encoding argument (ruff UP012)
- Update pylint configuration to disable false positives:
  - no-member (Pydantic SecretStr false positives)
  - deprecated-module (telnetlib is needed despite deprecation)
  - broad-exception-caught (acceptable for version fallback)
  - possibly-used-before-assignment (false positive with while loops)
  - too-many-positional-arguments
  - redefined-builtin (__name__ is intentional)

## Test Fixes
- Update SSH tests to expect bytes in sendall() assertions
- Fix test_get_creds_creates_new_when_none_exist mock side_effect
  (added extra values for nested get_creds() call)
- All 54 tests now passing ✓

## Python 3.13 Support
- Add Python 3.13 to pyproject.toml classifiers
- Add Python 3.13 to GitHub Actions test matrix
- Note: telnetlib deprecated warning expected (removal in 3.13)

## Verification Results
✓ ruff format --check: All files properly formatted
✓ ruff check: All checks passed
✓ mypy netlib: Success, no issues found
✓ pylint netlib: 10.00/10 rating
✓ pytest: 54 tests passed, 82.52% coverage

https://claude.ai/code/session_019D1TUrg1xPGse1HsS8pgqQ
Python 3.13 removed the telnetlib module from the standard library,
which is a core dependency for the Telnet class in this package.

Until telnetlib is replaced with an alternative implementation,
Python 3.13 cannot be supported.

Changes:
- Remove Python 3.13 from pyproject.toml classifiers
- Remove Python 3.13 from GitHub Actions test matrix
- Maximum supported Python version is now 3.12

https://claude.ai/code/session_019D1TUrg1xPGse1HsS8pgqQ
@jtdub
jtdub merged commit da0b410 into master Jan 29, 2026
4 checks passed
@jtdub
jtdub deleted the claude/modernize-python-ci-EnwcK branch January 29, 2026 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants