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

Dedup and merge reqs to pass into pip #15

Closed
wants to merge 1 commit into from

Conversation

uranusjr
Copy link
Member

I was trying this on some setuptools-based packages, and find this edge case. If a package specifies both setup-requires in setup.py and build-system.requires in pyproject.toml (for compatibility reasons), setuptools’s get_requires_for_build_* hooks would return both of them.

This would result in something like ['setuptools>=32.2.2', 'setuptools>=36.6', 'setuptools', 'wheel'], and pip does not like it, failing the build.

This PR adds a very naive parser to merge the requirements before passing them to pip. The above example would be converted into ['setuptools>=36.6,32.2.2', 'wheel']. Not the most elegant result, but pip accepts it and does the right thing.

I am not sure how this fits in the tests. Feel free to point me a direction and I’ll add it.

def _load_pyproject(source_dir):
with open(os.path.join(source_dir, 'pyproject.toml')) as f:
pyproject_data = pytoml.load(f)
buildsys = pyproject_data['build-system']
return buildsys['requires'], buildsys['build-backend']


REQUIREMENT_PATTERN = re.compile(r'^(?P<name>[^~><=!]+)(?P<spec>.*)$')

Choose a reason for hiding this comment

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

should we use instead here the pep 440 parser instead of the naive regex? I've used it when I hit this edge case in tox to resolve the conflict. Tbh though I think we should really warn if the two versions don't match exactly. it's likely a bug.

Copy link
Member

Choose a reason for hiding this comment

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

@pfmoore @takluyver Thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

I suspect so, but I don't use this class in pip, so I've no real idea.

Copy link
Member Author

@uranusjr uranusjr Sep 19, 2018

Choose a reason for hiding this comment

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

AFAICT there are no existing PEP 440 implementations that can tell if a version specifier has conflicts by looking at it. So the only viable thing to do IMO is to just feed it into pip and see what happens.

Theoratically the input here can be an arbitrary PEP 508-compliant string, complete with markers and such, so the complete solution should likely use packaging.requirements to do the parsing. I can do that if @takluyver thinks it’s a good idea to add packaging as a dependency.

Copy link

@gaborbernat gaborbernat Sep 19, 2018

Choose a reason for hiding this comment

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

https://packaging.pypa.io/en/latest/requirements/ should allow you to parse, and then you can make the decision if the two versions (if both exists) matches or not. but yeah overall I agree with your assessment. your regex here is a poor mans packaging and if needed we might as well depend on upstream to avoid bugs.

@takluyver
Copy link
Member

I think that what you hit is a bug in the setuptools build backend: I don't think it should be returning the values from build-system.requires at all. The spec says that the get_requires_for_build_* hooks should return:

an additional list of strings containing PEP 508 dependency specifications, above and beyond those specified in the pyproject.toml file

To me, that means that the backend shouldn't include the build-system.requires values, because the frontend should have already found those before calling the hook.

There may still be some need for deduplication, either in the frontend or the backend. But I'd recommend we focus on fixing the specific problem with setuptools first.

@gaborbernat
Copy link

Hmm, going from there indeed setuptools should avoid specifying both wheel and setuptools if they are in the build requires. Can you raise a setuptools issue for this then and link it to this?

@pfmoore
Copy link
Member

pfmoore commented Sep 19, 2018

Ah, if that's what this is about, I agree. I'd noticed this problem with the setuptools backend, but hadn't got around to (needing to) address it in pip yet.

@jaraco
Copy link
Member

jaraco commented Dec 11, 2018

The downstream issue has been solved with Setuptools 40.6.3. I suggest then this PR can be closed.

@jaraco jaraco closed this Dec 11, 2018
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.

6 participants