Skip to content

Conversation

@radoering
Copy link
Member

@radoering radoering commented Nov 29, 2025

Summary by Sourcery

Drop support for Python 3.9 and clean up code, tests, and CI configuration to target Python 3.10+.

Enhancements:

  • Simplify temporary_directory helper to always use tempfile.TemporaryDirectory with ignore_cleanup_errors enabled for Python 3.10+.
  • Modernize type annotations to use PEP 604 union syntax and updated collection ABC imports, and leverage pairwise iteration where available.
  • Standardize subprocess helper to always run with locale-based text encoding.

Build:

  • Raise the core package requires-python setting to ">=3.10,<4.0" and update the vendored project metadata accordingly.
  • Remove the Python 3.9 target from linting configuration and related tooling.

CI:

  • Update the test workflow matrix to drop Python 3.9 from CI runs.

Tests:

  • Remove Python 3.9-specific temporary_directory tests and conditions, keeping a single test path for Python 3.10+ behavior.

@sourcery-ai
Copy link

sourcery-ai bot commented Nov 29, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Drops Python 3.9 support across code, tests, configuration, and CI, enabling use of Python 3.10+ features and simplifying version-dependent logic (notably around temporary directories, subprocess encoding, typing, and version constraint utilities).

Class diagram for updated typing constraints and aliases

classDiagram
    class BaseConstraint
    class VersionConstraint

    class SingleMarkerLike~T~
    class SingleMarkerConstraint {
        <<typevar>>
        bound BaseConstraint | VersionConstraint
    }

    SingleMarkerLike <|-- SingleMarker

    class SingleMarker {
        <<generic>> SingleMarkerLike~BaseConstraint | VersionConstraint~
    }

    class DependencyConstraint {
        <<typealias>>
        str | Mapping~str, Any~
    }

    class DependencyConfig {
        <<typealias>>
        Mapping~str, list~DependencyConstraint~ | DependencyConstraint~
    }

    class LocalSegmentType {
        <<typealias>>
        str | int | tuple~str | int, ...~ | None
    }
Loading

Flow diagram for updated temporary_directory helper

flowchart TD
    A[temporary_directory called] --> B[Set kwargs ignore_cleanup_errors true]
    B --> C[Create TemporaryDirectory with kwargs]
    C --> D[Yield Path of temporary directory name]
    D --> E[TemporaryDirectory context exits and cleans up directory]
Loading

File-Level Changes

Change Details Files
Simplify temporary_directory helper to Python 3.10+ behavior only and update tests accordingly.
  • Remove sys.version_info branching in temporary_directory, always using tempfile.TemporaryDirectory with ignore_cleanup_errors=True
  • Delete legacy code path using tempfile.mkdtemp and robust_rmtree for Python 3.9
  • Unskip and rename tests that previously targeted Python 3.10-only behavior
  • Remove tests that covered the Python 3.9-or-older temporary_directory code path
  • Update temporary_directory tests to assume TemporaryDirectory is always used and cleanup is handled via ignore_cleanup_errors
src/poetry/core/utils/helpers.py
tests/utils/test_helpers.py
Leverage Python 3.10+ typing features and simplify type annotations.
  • Replace Union[...] and Optional[...] annotations with PEP 604
unions in several modules
  • Adjust generic TypeVar bound and class parameterization in markers to use
  • Clean up version-specific runtime logic now that minimum Python is 3.10.
    • Simplify subprocess_run helper to always use encoding='locale' with text=True, removing sys.version_info-based conditional
    • Use itertools.pairwise in constraint_regions instead of manual zip over edges, relying on its availability in Python 3.10+
    • Add missing Callable import for TYPE_CHECKING usage in tests conftest
    tests/testutils.py
    src/poetry/core/constraints/version/util.py
    tests/conftest.py
    Update declared Python version support in packaging metadata, vendored configuration, and CI.
    • Bump requires-python from ">=3.9, <4.0" to ">=3.10, <4.0" in main pyproject.toml
    • Remove Ruff target-version setting for py39, allowing tools to assume 3.10+
    • Update vendors/pyproject.toml requires-python from ">=3.9" to ">=3.10"
    • Drop Python 3.9 from GitHub Actions test matrix so CI runs only on 3.10+
    • Regenerate or adjust lock files and vendor metadata consistent with the new minimum Python version
    pyproject.toml
    .github/workflows/tests.yaml
    vendors/pyproject.toml
    poetry.lock
    vendors/poetry.lock
    src/poetry/core/_vendor/lark/LICENSE
    src/poetry/core/_vendor/lark/grammars/common.lark
    src/poetry/core/_vendor/lark/grammars/lark.lark
    src/poetry/core/_vendor/lark/grammars/python.lark
    src/poetry/core/_vendor/lark/grammars/unicode.lark
    src/poetry/core/_vendor/vendor.txt
    src/poetry/core/constraints/generic/constraint.py

    Tips and commands

    Interacting with Sourcery

    • Trigger a new review: Comment @sourcery-ai review on the pull request.
    • Continue discussions: Reply directly to Sourcery's review comments.
    • Generate a GitHub issue from a review comment: Ask Sourcery to create an
      issue from a review comment by replying to it. You can also reply to a
      review comment with @sourcery-ai issue to create an issue from it.
    • Generate a pull request title: Write @sourcery-ai anywhere in the pull
      request title to generate a title at any time. You can also comment
      @sourcery-ai title on the pull request to (re-)generate the title at any time.
    • Generate a pull request summary: Write @sourcery-ai summary anywhere in
      the pull request body to generate a PR summary at any time exactly where you
      want it. You can also comment @sourcery-ai summary on the pull request to
      (re-)generate the summary at any time.
    • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
      request to (re-)generate the reviewer's guide at any time.
    • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
      pull request to resolve all Sourcery comments. Useful if you've already
      addressed all the comments and don't want to see them anymore.
    • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
      request to dismiss all existing Sourcery reviews. Especially useful if you
      want to start fresh with a new review - don't forget to comment
      @sourcery-ai review to trigger a new review!

    Customizing Your Experience

    Access your dashboard to:

    • Enable or disable review features such as the Sourcery-generated pull request
      summary, the reviewer's guide, and others.
    • Change the review language.
    • Add, remove or edit custom review instructions.
    • Adjust other review settings.

    Getting Help

    Copy link

    @sourcery-ai sourcery-ai bot left a comment

    Choose a reason for hiding this comment

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

    Hey there - I've reviewed your changes - here's some feedback:

    • In constraint_regions you switched from zip(edges, edges[1:]) to pairwise(edges) but there’s no corresponding import change in the diff—either add from itertools import pairwise or qualify it as itertools.pairwise to avoid a NameError.
    Prompt for AI Agents
    Please address the comments from this code review:
    
    ## Overall Comments
    - In `constraint_regions` you switched from `zip(edges, edges[1:])` to `pairwise(edges)` but there’s no corresponding import change in the diff—either add `from itertools import pairwise` or qualify it as `itertools.pairwise` to avoid a `NameError`.
    
    ## Individual Comments
    
    ### Comment 1
    <location> `pyproject.toml:64-68` </location>
    <code_context>
     fix = true
     line-length = 88
     src = ["src"]
    -target-version = "py39"
    
     [tool.ruff.lint]
    </code_context>
    
    <issue_to_address>
    **suggestion:** Ruff target-version could be updated to `py310` rather than removed for consistent linting across environments.
    
    Because `requires-python = ">=3.10, <4.0"` is set, dropping `target-version` makes Ruff depend on the local runtime/tooling to infer the version, which can differ between environments. Keeping `target-version = "py310"` makes the applied lint rules (syntax support, built-ins, etc.) deterministic everywhere Ruff runs.
    
    ```suggestion
    fix = true
    line-length = 88
    src = ["src"]
    target-version = "py310"
    
    [tool.ruff.lint]
    ```
    </issue_to_address>

    Sourcery is free for open source - if you like our reviews please consider sharing them ✨
    Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

    @radoering radoering merged commit 69af3f0 into python-poetry:main Dec 7, 2025
    19 of 20 checks passed
    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