pypa / packaging

Core utilities for Python packages
https://packaging.pypa.io/
Other
608 stars 243 forks source link

Support combining markers? #540

Open pfmoore opened 2 years ago

pfmoore commented 2 years ago

I'm trying to write a PEP 621 consumer, and I'm having trouble with the optional-dependencies item. The issue is that I could potentially need to combine markers, and I don't see a particularly reliable way of doing so. Consider:

[project.optional-dependencies]
test = [
  "pytest < 5.0.0",
  "pytest-cov[all]",
  "pywin32; os_name == 'nt'"
]

To construct Requires-Dist from this, I need to add a dependency pywin32; os_name == 'nt' and extra == 'test'.

The best way I can see of doing this is

req = Requirement(req_str)
if req.marker is None:
    req.marker = Marker(f"extra == '{extra_name}'")
else:
    req.marker = Marker(f"({req.marker}) and extra == '{extra_name}'")

requires_dist.append(str(req))

Is that the best way of doing this? It would be extremely useful in this situation if markers supported & and | operations, to avoid the error-prone conversion to and from strings.

brettcannon commented 2 years ago

Is that the best way of doing this?

It's at least what first came to mind for me. 😁

I think this also ties into https://github.com/pypa/packaging/issues/496 which wanted to expose the AST of markers.

But otherwise overriding & and | to combine markers seems reasonable to me as a way to build them up.