Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

662 duplicates are not supported in requirements.txt when run with disable pip #749

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

mathbou
Copy link
Contributor

@mathbou mathbou commented Mar 17, 2024

Recently, I run in the same problem described in #662. To avoid this, I propose a finer check for duplicates based on both name and specifier.

As stated in the issue, when the --disable-pip flag is used, we could consider that a full requirement resolution has been made. Knowing that, as long as specifiers matches, having duplicates is not a problem. If they don't match, we raise an error like before.

On the side, I also add a small fix for stdout/stderr reading in pip_audit/_subprocess.py. I don't know if it's specific to windows, but the fact that a size was specified, I had the process hanging indefinitely.

@woodruffw
Copy link
Member

Thanks for the patch @mathbou! I'll review this today.

@woodruffw woodruffw self-requested a review March 18, 2024 14:44
@woodruffw woodruffw added the component:dep-sources Dependency sources label Mar 18, 2024
Comment on lines +228 to +241
req_specifiers: dict[str, SpecifierSet] = dict()

for req in reqs:
if (
isinstance(req, InstallRequirement)
and (req.marker is None or req.marker.evaluate())
and req.req is not None
):
if req.name in req_names:
duplicate_req_specifier = req_specifiers.get(req.name)

if not duplicate_req_specifier:
req_specifiers[req.name] = req.specifier

elif duplicate_req_specifier != req.specifier:
Copy link
Member

@woodruffw woodruffw Mar 18, 2024

Choose a reason for hiding this comment

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

Just making sure I understand the behavior here: rather than deduping on just the requirement's name (i.e. package name), we're now deduping on different specifiers for duplicated names, right?

IIUC that means that we'll still have some false positives here (since SpecifierSet != SpecifierSet does not imply that the two are incompatible), right? If so that's fine, just making sure I understand 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

rather than deduping on just the requirement's name (i.e. package name), we're now deduping on different specifiers for duplicated names

Yep, that's the idea. As long as each package sharing the same name, also share the same specifier, it is considered identical.

IIUC that means that we'll still have some false positives here (since SpecifierSet != SpecifierSet does not imply that the two are incompatible), right? If so that's fine, just making sure I understand 🙂

I'm not sure how we could still get false positives here 🤔 Have you a specific case in mind ?
Unless you modify the resolved requirements, it is very unlikely to get different SpecifierSet for the package and its extras.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure how we could still get false positives here 🤔 Have you a specific case in mind ?
Unless you modify the resolved requirements, it is very unlikely to get different SpecifierSet for the package and its extras.

What I'm thinking of is something like this:

example >= 1.0
example >= 1.0, < 3.0

In this case, SpecifierSet(">= 1.0") != SpecifierSet(">= 1.0, < 3.0"), but the two are not incompatible (all versions in 1.x and 2.x satisfy both sets). Unless I'm misunderstanding, I believe this change will still incorrectly reject this as a "duplicate" dependency, when one is a superset of the other.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are correct, it this case it will be rejected.
Maybe it would be more appropriate to reject them as incompatible instead of duplicate, what do you think ?

pip_audit/_subprocess.py Outdated Show resolved Hide resolved
@woodruffw woodruffw added the needs-response Needs response from the reporter. label Mar 20, 2024
@mathbou mathbou requested a review from woodruffw May 10, 2024 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component:dep-sources Dependency sources needs-response Needs response from the reporter.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants