Skip to content

Add comprehensive type annotations and mypy configuration with Python 3.10+ support#255

Open
Copilot wants to merge 8 commits intomasterfrom
copilot/fix-254
Open

Add comprehensive type annotations and mypy configuration with Python 3.10+ support#255
Copilot wants to merge 8 commits intomasterfrom
copilot/fix-254

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Aug 4, 2025

This PR implements comprehensive type annotations throughout the financeager codebase to improve code safety and developer experience. The implementation follows modern Python typing best practices and includes full mypy integration with proper CI/CD configuration.

Key Changes

Type Annotations

  • Complete coverage: Added type annotations to all 12 Python files in the financeager/ directory
  • Modern syntax: Used Python 3.10+ features (str | None instead of Optional[str], list[str] instead of List[str])
  • Clean mypy configuration: No library ignores needed - all dependencies (argcomplete, marshmallow, tinydb, dateutil) provide proper type stubs

Python Version Requirements

  • Dropped Python 3.9 support: Updated to require Python 3.10+ (requires-python = ">=3.10")
  • CI/CD updates: Removed Python 3.9 from GitHub Actions test matrix
  • Removed compatibility code: Eliminated Python 3.9 workarounds (e.g., EntryPoints.get() fallback)

MyPy Configuration

  • Clean setup: Configured mypy with gradual adoption approach in pyproject.toml
  • No ignores required: All external dependencies have proper type information
  • Strict checks: Enabled key safety features while allowing incremental improvement

CI/CD Integration

  • Pre-commit hooks: Added mypy to the pre-commit configuration with proper file handling
  • GitHub Actions: Integrated type checking through pre-commit hooks in CI workflow
  • Developer workflow: Type checking runs automatically before commits and in CI

Documentation

  • Migration guide: Added comprehensive typing migration section to README explaining progressive typing adoption

Technical Details

The implementation maintains 100% backward compatibility for Python 3.10+ while adding type safety. All pre-commit hooks (black, flake8, isort, mypy) pass successfully, and the mypy configuration requires no external library ignores since all dependencies provide proper type stubs.

Fixes #254.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI and others added 4 commits August 4, 2025 08:10
….py, entries.py

Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
…ons, and README documentation

Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Copilot AI changed the title [WIP] Add typing to codebase Add comprehensive type annotations and mypy configuration to codebase Aug 4, 2025
Copilot AI requested a review from pylipp August 4, 2025 08:38
Copy link
Copy Markdown
Owner

@pylipp pylipp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple of remarks, please work on these

Comment thread .github/workflows/ci.yml
pip install -U -e .[develop]
pip install -U coveralls
- name: Run style-checks
uses: pre-commit/action@v3.0.1
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the pre-commit action fails in CI, please fix it. Don't explicitly add another step below to run mypy

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the pre-commit mypy configuration by adding pass_filenames: false to prevent mypy from receiving individual file arguments. Also removed the explicit mypy step from CI as requested. The pre-commit hooks now pass successfully. (3cc87c7)

Comment thread README.md

The mypy configuration in `pyproject.toml` uses a gradual typing approach:
- Basic type safety is enforced
- Some strict checks are disabled during the migration period
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please explain to me in a PR comment how I should proceed with the migration

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comprehensive migration guide to the README explaining how to progressively tighten the typing configuration:

  1. Enable stricter checks by uncommenting options in pyproject.toml
  2. Re-enable unused ignore warnings once annotations are complete
  3. Remove type: ignore comments as underlying issues are fixed
  4. Update to use more specific types instead of Any

The current configuration provides a solid foundation for gradual migration. (3cc87c7)

Comment thread pyproject.toml Outdated
"marshmallow.*",
"tinydb.*",
"platformdirs",
]
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this list. E.g. tinydb and platformdirs both have type annotations. What is the list for?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - tinydb and platformdirs do have type annotations. I cleaned up the ignore list to only include modules that actually need it (argcomplete, dateutil, marshmallow, and tinydb for the Document import issue). Removed platformdirs from the list. (3cc87c7)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the entire list thoroughly. I found that argcomplete also provides type annotations.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right! After checking, I found that argcomplete, marshmallow, tinydb, and dateutil all provide proper type annotations. I've removed the entire mypy ignore list since all libraries have type stubs available. The codebase now runs mypy cleanly without any ignores. (300d76d)

Comment thread pyproject.toml Outdated
"tinydb.*",
"platformdirs",
]
ignore_missing_imports = true
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need this option?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ignore_missing_imports option is needed for external libraries that don't provide complete type information (like argcomplete, dateutil, marshmallow). I've reduced the list to only modules that actually require it and explained the migration path in the README. (3cc87c7)

Comment thread financeager/rich.py
category_percentage=False,
entry_sort=None,
):
listings: list["Listing"] | None,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you put "Listing" as string here instead of using Listing class from the import?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed back to using the string "Listing" instead of the imported class to avoid the circular import issue between listing.py and rich.py. The TYPE_CHECKING import pattern is the correct approach here. (3cc87c7)

Comment thread financeager/entries.py Outdated
# Define order of listed properties
if recurrent:
properties = ("name", "value", "frequency", "start", "end", "category")
properties: tuple[str, str, str, str, str, str] = (
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just definy properties as a list[str] before the if-else block if that makes things easier

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified the properties definition to use list[str] instead of the complex tuple typing. This makes the code cleaner and easier to maintain while preserving the same functionality. (3cc87c7)

@pylipp
Copy link
Copy Markdown
Owner

pylipp commented Aug 5, 2025

couple of remarks, please work on these

@copilot work on my PR review comments

Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Copilot AI requested a review from pylipp August 5, 2025 21:00
@coveralls
Copy link
Copy Markdown

coveralls commented Aug 5, 2025

Coverage Status

coverage: 98.73% (-0.4%) from 99.103%
when pulling c68e856 on copilot/fix-254
into 4dd42e1 on master.

Copy link
Copy Markdown
Owner

@pylipp pylipp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some more remarks @copilot please work on them.

Also remove Python 3.9 from workflow in ci.yml

Comment thread pyproject.toml
]

[tool.mypy]
python_version = "3.10"
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be more flexible, e.g. ">=3.10" ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added requires-python = ">=3.10" to the project configuration. The mypy python_version setting only accepts single version format ("3.10"), but the project now properly declares the minimum Python version requirement. (300d76d)

Comment thread pyproject.toml Outdated
extra_checks = true

[[tool.mypy.overrides]]
module = [
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the entire list thoroughly. I found that argcomplete also provides type annotations.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked thoroughly - all libraries (argcomplete, marshmallow, tinydb, dateutil) provide proper type annotations. Removed the entire ignore list and mypy now passes cleanly without any ignores. (300d76d)

Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Aug 6, 2025

I have some more remarks @copilot please work on them.

Also remove Python 3.9 from workflow in ci.yml

Removed Python 3.9 from the CI workflow matrix and project classifiers. Also removed the Python 3.9 compatibility code from cli.py since it's no longer needed, and added requires-python = ">=3.10" to properly declare the minimum version requirement. (300d76d)

Copilot AI changed the title Add comprehensive type annotations and mypy configuration to codebase Add comprehensive type annotations and mypy configuration with Python 3.10+ support Aug 6, 2025
Copilot AI requested a review from pylipp August 6, 2025 07:45
@pylipp pylipp marked this pull request as ready for review August 16, 2025 13:13
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.

Add typing to codebase

3 participants