Skip to content

fix: handle @latest version specifier with environment markers - #11098

Open
dajiaohuang wants to merge 1 commit into
python-poetry:mainfrom
dajiaohuang:fix/poetry-add-latest-with-markers
Open

dajiaohuang wants to merge 1 commit into
python-poetry:mainfrom
dajiaohuang:fix/poetry-add-latest-with-markers

Conversation

@dajiaohuang

Copy link
Copy Markdown

Resolves #10227

Problem

When using poetry add with @latest version specifier combined with environment markers (e.g., poetry add --lock "poetry@latest ; platform_machine!=\"aarch64\""), the command would fail with the error:

```
Path /path/to/project/latest for poetry does not exist
```

This happened because:

  1. The regex stripping @latest in init._parse_requirements() only matched at end-of-string (`@\s*latest$`), failing when markers followed
  2. The _parse_pep508 detection regex did not account for the @latest pattern, causing invalid PEP 508 parsing to be attempted, which then fell through to path parsing (treating "latest" as a directory)

Fix

  • Updated the @latest stripping regex in both init.py and RequirementsParser.parse() to handle cases where @latest is followed by a semicolon (environment markers), while preserving the marker portion: `@\slatest(\s;|$)`
  • Added the @latest detection pattern to _parse_pep508() for robustness
  • Added test cases covering @latest with and without extras and markers

Test cases added

  • `demo@latest`
  • `demo[a,b]@latest`
  • `demo@latest ; python_version >= "3.8"`
  • `demo[a,b]@latest ; python_version >= "3.8"`

All existing tests continue to pass.

Fixes issue where  would fail with
'Path .../latest for <package> does not exist' error because:

1. The regex stripping @latest in init._parse_requirements only matched
   end-of-string, not @latest followed by markers.
2. The _parse_pep508 detection regex didn't account for @latest pattern,
   causing invalid PEP 508 parsing to be attempted.

The fix updates the @latest stripping regex to also handle cases where
@latest is followed by a semicolon (environment markers), while
preserving the marker portion. Also adds the @latest detection pattern
to _parse_pep508 for robustness in case RequirementsParser is called
from other places.

Fixes python-poetry#10227

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Approved.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@dimbleby

Copy link
Copy Markdown
Contributor

Are you making @latest just do the same as not typing that in the first place? I don't really see the point, we should instead ask people not to type that in the first place.

Added the @latest detection pattern to _parse_pep508() for robustness

this is definitely wrong, a PEP508 parser should fail to parse non-compliant strings

@kokokoXUY kokokoXUY left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I found a reproducible VCS revision regression in the new @latest normalization; details inline.

def parse(self, requirement: str) -> DependencySpec:
requirement = requirement.strip()
requirement = re.sub(
r"@\s*latest(\s*;|$)", r"\1", requirement, flags=re.IGNORECASE

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This unconditional rewrite also matches a legitimate VCS revision named latest. I reproduced RequirementsParser.parse("git+https://github.com/demo/demo.git@latest") at this PR head (bce8925): it returns {'git': 'https://github.com/demo/demo.git'} with no rev, whereas the unchanged base returns rev: 'latest'. That silently installs the default branch instead of the requested revision. The same rewrite in init.py affects poetry add too. Could the @latest normalization be limited to a package-name version specifier, leaving VCS URLs and direct references untouched? A regression test for a Git URL with @latest would guard this.

This branch has not been deployed

No deployments
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.

poetry add @latest with markers fails with error

3 participants