Skip to content

Drop python 3.9 support#988

Merged
spoorcc merged 1 commit intomainfrom
drop-py39-support
Feb 9, 2026
Merged

Drop python 3.9 support#988
spoorcc merged 1 commit intomainfrom
drop-py39-support

Conversation

@spoorcc
Copy link
Contributor

@spoorcc spoorcc commented Feb 9, 2026

Summary by CodeRabbit

Release Notes

  • Chores

    • Dropped Python 3.9 support; minimum version is now 3.10.
    • Updated CI/CD pipelines to test Python 3.10–3.14.
    • Updated development tools to align with Python 3.10+ standards.
  • Refactor

    • Modernized type annotations across the codebase to use Python 3.10+ union syntax for improved code clarity.

@coderabbitai
Copy link

coderabbitai bot commented Feb 9, 2026

Walkthrough

This PR drops Python 3.9 support and modernizes type annotations throughout the codebase to use PEP 604 union syntax. Updates include CI/CD workflows (Python 3.10–3.14 test matrix), tool configurations (pyupgrade, Pyright), minimum Python version requirement in pyproject.toml, and type hints across all modules (replacing Optional[T]/Union[A, B] with T | None/A | B).

Changes

Cohort / File(s) Summary
CI/CD & Tooling Configuration
.github/workflows/run.yml, .github/workflows/test.yml, .pre-commit-config.yaml, pyproject.toml
Updated Python test matrix to 3.10–3.14 (removed 3.9), refactored per-platform SVN installation steps, bumped minimum Python requirement and type-checker target version to 3.10, updated pyupgrade invocation from --py39-plus to --py310-plus.
Core Entry Point
dfetch/__main__.py
Updated run() function signature to use union syntax (Console | None instead of Optional[Console]), removed Optional import.
Logging Module
dfetch/log.py
Replaced Optional/Union with PEP 604 syntax across configure_root_logger(), setup_root(), get_logger(), and DLogger.status() signatures and internal variable annotations.
Manifest & Configuration
dfetch/manifest/manifest.py, dfetch/manifest/parse.py, dfetch/manifest/project.py, dfetch/manifest/remote.py
Converted ManifestDict type fields and method signatures (e.g., Manifest.__init__, from_yaml, _load_yaml) to use union syntax; updated ProjectEntryDict and RemoteDict field types accordingly.
Project & Superproject Handling
dfetch/project/__init__.py, dfetch/project/metadata.py, dfetch/project/subproject.py
Updated determine_superproject_vcs(), Options.patch, Metadata.fetched(), and SubProject return/parameter types to union syntax; removed Optional/Union imports.
VCS & Patch Utilities
dfetch/vcs/git.py, dfetch/vcs/patch.py, dfetch/vcs/svn.py
Converted GitLocalRepo, SvnRepo, and parse_patch type annotations (path parameters, optional version/ignore parameters, return types) from Optional/Union to PEP 604 syntax.
General Utilities
dfetch/util/cmdline.py, dfetch/util/license.py, dfetch/util/purl.py, dfetch/util/util.py, dfetch/util/versions.py, dfetch/commands/update_patch.py
Updated utility function and class signatures (e.g., run_on_cmdline(), guess_license_in_file(), safe_rm(), in_directory()) to use union syntax for optional and multi-type parameters.
Changelog
CHANGELOG.rst
Added release note documenting Python 3.9 support removal in 0.12.0 (unreleased).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • #985 — Updates patch parsing and handling APIs in dfetch/vcs/patch.py alongside type annotation changes.
  • #931 — Modifies manifest, project metadata, and subproject type annotations concurrently with similar union syntax conversions.
  • #960 — Introduces Rich-based logging APIs (configure_root_logger, setup_root, get_logger, DLogger.status) that are type-annotated in this PR.

Suggested labels

enhancement

Suggested reviewers

  • ben-edna
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main objective of the pull request, which is to drop Python 3.9 support and upgrade to Python 3.10+.
Docstring Coverage ✅ Passed Docstring coverage is 95.45% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch drop-py39-support

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
.github/workflows/run.yml (1)

83-102: Good improvement: per-platform SVN installation.

Splitting SVN installation into platform-specific conditional steps is cleaner than a single step. Consider giving each step a distinct name (e.g., "Install SVN (Ubuntu)", "Install SVN (macOS)", "Install SVN (Windows)") for easier log navigation, though this is a minor nit.

dfetch/util/license.py (1)

47-59: Docstring still references old-style type annotations.

The function signature now uses str | PathLike[str] and License | None, but the docstring on lines 56 and 59 still uses Union[str, os.PathLike[str]] and Optional[License]. Consider updating for consistency.

Proposed fix
     Args:
-        filename (Union[str, os.PathLike[str]]): Path to the file to analyze
+        filename (str | os.PathLike[str]): Path to the file to analyze
 
     Returns:
-        Optional[License]: The most probable license if found, None if no license could be detected
+        License | None: The most probable license if found, None if no license could be detected
dfetch/project/subproject.py (1)

44-49: Stale docstring still references old typing syntax.

Line 48 docstring still says Tuple[Optional[Version], Optional[Version]] while the actual return type is now tuple[Version | None, Version | None].

📝 Suggested docstring update
-            Tuple[Optional[Version], Optional[Version]]: Wanted, Have
+            tuple[Version | None, Version | None]: Wanted, Have
dfetch/manifest/manifest.py (1)

146-157: Docstring still uses old-style Union[...] notation.

The docstring on lines 149–151 still references Union[ProjectEntryDict, ProjectEntry, Dict[str, Union[str, list[str]]]] while the actual signature now uses PEP 604 syntax. Consider updating for consistency.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@spoorcc spoorcc merged commit a5f8945 into main Feb 9, 2026
35 checks passed
@spoorcc spoorcc deleted the drop-py39-support branch February 9, 2026 21:44
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.

1 participant