Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@sirosen
Copy link
Member

@sirosen sirosen commented Aug 4, 2025

When statically parsing a pyproject.toml, we can encounter self-referential package usage. For example, an extra which names another extra on the same package.

The source for these requirements is the current package, but as a concrete requirement, not an abstract one. To make it concrete, we use a URI dependency link pointed at the package directory as a file-URI.

When the input path to pyproject.toml is relative, it needs to be made absolute for use as a URI. Failing to do so results in errors.

Because the pip-compile output of an such an extra depends concretely on the specific version of the package found in-tree, and not abstractly on the package name (without the URI), tests confirm that we see the rendered package directory as a file URI in pip-compile output.

Contributor checklist
  • Included tests for the changes.
  • A change note is created in changelog.d/ (see changelog.d/README.md for instructions) or the PR text says "no changelog needed".
Maintainer checklist
  • If no changelog is needed, apply the skip-changelog label.
  • Assign the PR to an existing or new milestone for the target version (following Semantic Versioning).

@sirosen sirosen added this to the 7.5.1 milestone Aug 4, 2025
assert out.exit_code == 0
assert out.stdout == dedent(
f"""\
foo[ext1] @ {src_file.parent.absolute().as_uri()}
Copy link
Member

Choose a reason for hiding this comment

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

Is this really what we want? I don't think people would expect absolute paths from someone else's computer to end up in their lock files..

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree, and it's why I was pretty hesitant at first. But also, that's the behavior from 7.4.1 -- it's just not tested.

In theory, someone could be using this in some controlled context like an image build and wanting the concrete dependency path that this provides. So although I'm uncertain that it's right for the long term, I don't want to treat it as blocking the fix.

Copy link
Member

Choose a reason for hiding this comment

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

Wait, did it always use absolute paths in 7.4.1? Not relative? I thought it'd conform to the shape of input that the 7.5.0 changelog promises.. Can we use file://./rel/path/?

Copy link
Member Author

Choose a reason for hiding this comment

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

The path in this case is part of the InstallRequirement itself -- the "link" attribute is populated with this file URI.
The normalization in 7.5.0 only applies to the comes_from data ("via").

We could reach down into this as well and convert to file://./rel/path/ as you say, but I'm not sure if we should. It would be a separate bit of data transformation -- we could share code but it's a different attribute of the parsed requirements data that we'd be manipulating.

Copy link
Member

Choose a reason for hiding this comment

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

I suppose, we could postpone that for now. There might be a use case coverage missing for stripping the @ http://..source in some contexts.

@webknjaz
Copy link
Member

webknjaz commented Aug 4, 2025

Oh, looks like Windows is unhappy about the delimiters again.

@sirosen sirosen force-pushed the fix-relpath-static-pyproject-parse branch 2 times, most recently from fc92905 to b05d736 Compare August 4, 2025 23:55
@sirosen
Copy link
Member Author

sirosen commented Aug 5, 2025

The thing I broke in the tests is treatment of comes_from data in this scenario. We're stringifying the path to the package dir here:

comes_from = f"{package_name} ({src_file})"

It's easy to "fix" by just adding an as_posix() call there, but I can imagine this becoming inconsistent with the behavior when that information is rendered via some other path. I'm going to run some experiments later this week to try to figure out what the variations are on this.

@webknjaz webknjaz moved this to 🧐 @webknjaz's review queue 📋 in 📅 Procrastinating in public Aug 7, 2025
@maurerle

This comment was marked as resolved.

@sirosen

This comment was marked as resolved.

@maurerle

This comment was marked as off-topic.

kim-mskw pushed a commit to assume-framework/assume that referenced this pull request Aug 13, 2025
# Pull Request

There is an issue with self-referential packages in a pyproject.toml
with the latest pip-tools release.
The self-referential [all] package, which is not written to the
requirements.txt as it is not selected still throws a pip-compile error.

More information for this can be found in the ticket:
jazzband/pip-tools#2215

The pin should be removed when
jazzband/pip-tools#2221 gets merged.
@sirosen

This comment was marked as off-topic.

@sirosen
Copy link
Member Author

sirosen commented Aug 13, 2025

I've just gotten back to this, taken a look at the open threads and marked the ones which were applied as suggestions as resolved.

I looked at what happens in the case of dynamic metadata, and we have a similar bit of path formatting in there.

I'd like to resolve this by adding calls to as_posix() to both locations in piptools/build.py.
One is the place mentioned above, where a static build is happening and we're writing the comes_from data.
The other is this line in this function which does the same work on requirements from dynamic metadata.

@webknjaz, are you okay with that increase in scope? I'll need to add some new tests to cover it and another changelog note.
As an overall project direction, I think it's best to try to make all of our outputs posix paths, to make the outputs consistent.

@webknjaz
Copy link
Member

@sirosen agreed. Increasing the scope sounds justified.

@sirosen sirosen force-pushed the fix-relpath-static-pyproject-parse branch from 10d5cf9 to d42c30b Compare September 16, 2025 03:28
@sirosen sirosen force-pushed the fix-relpath-static-pyproject-parse branch from d42c30b to bac58b8 Compare September 24, 2025 19:49
@sirosen
Copy link
Member Author

sirosen commented Sep 24, 2025

I've rebased to keep this fresh with the latest fixes in main and added a new changelog note changelog.d/2221.bugfix.md to cover the new path normalization which happens.

With the click-related issue starting to impact users -- and now that I'm clear that it's not a click bug but an intentional change in behavior -- I'm wanting to push this forward and try to narrow what we put into 7.5.1 .

@sirosen
Copy link
Member Author

sirosen commented Sep 25, 2025

I think something is wrong with the codecov integration.
The report on uncovered lines doesn't make much sense:
https://app.codecov.io/gh/jazzband/pip-tools/pull/2221?dropdown=coverage

One thing I notice is that it seems to mark everything related to piplowest testing as uncovered, which suggests that somehow we're not producing distinct coverage data for those builds in a way that codecov understands.

I don't think it's at all related to this PR.

@sirosen sirosen force-pushed the fix-relpath-static-pyproject-parse branch from bac58b8 to 54ced7c Compare September 25, 2025 21:23
@webknjaz
Copy link
Member

@sirosen will this address #2215 / #2233 ?

Copy link
Member

Choose a reason for hiding this comment

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

Should we symlink 2233 (upon confirmation), also 2221 (or 2221.bugfix.1.md rather)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, #2233 is getting fixed here as well, so I added the symlink. And I did the 2221.bugfix.1.md one as well, since "why not?" 😄

I'm going to put this in the merge queue, along with any other changes I can round up right now.

Copy link
Member

Choose a reason for hiding this comment

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

@sirosen the issues didn't end up auto-closed. Next time, plz try to remember to mark the PR as closing them (via web UI or closes/resolves/fixes keywords).

Copy link
Member

@webknjaz webknjaz left a comment

Choose a reason for hiding this comment

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

Looks good, but maybe add those change note refs before merging..

sirosen and others added 4 commits September 26, 2025 09:51
When statically parsing a pyproject.toml , we can encounter
self-referential package usage. For example, an extra which names
another extra on the same package.

The source for these requirements is the current package, but as a
concrete requirement, not an abstract one. To make it concrete, we use
a URI dependency link pointed at the package directory as a file-URI.

When the input path to `pyproject.toml` is relative, it needs to be
made absolute for use as a URI. Failing to do so results in errors.

Because the `pip-compile` output of an such an extra depends
concretely on the specific version of the package found in-tree, and
not abstractly on the package name (without the URI), tests confirm
that we see the rendered package directory as a file URI in
`pip-compile` output.
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <[email protected]>
When recording requirements derived from pyproject.toml data, the
`comes_from` field includes the path to the pyprojct.toml file.

Because this path is part of the output, which should therefore be
stable across `pip-tools` invocations on different platforms, normalize
these paths to posix-style.
@sirosen sirosen force-pushed the fix-relpath-static-pyproject-parse branch from 23b4447 to a5cf40c Compare September 26, 2025 14:51
@sirosen sirosen enabled auto-merge September 26, 2025 14:51
@sirosen sirosen added this pull request to the merge queue Sep 26, 2025
Merged via the queue into jazzband:main with commit 16c793b Sep 26, 2025
45 checks passed
@github-project-automation github-project-automation bot moved this from 🧐 @webknjaz's review queue 📋 to 🌈 Done 🦄 in 📅 Procrastinating in public Sep 26, 2025
@sirosen sirosen deleted the fix-relpath-static-pyproject-parse branch September 26, 2025 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

3 participants