packaging icon indicating copy to clipboard operation
packaging copied to clipboard

error "must be a string containing valid version specifiers" when providing a valid version specifier

Open mbdevpl opened this issue 7 years ago • 12 comments

Hello, please excuse me barging in here, it was suggested in the issue I submitted in setuptools https://github.com/pypa/setuptools/issues/1049 that I should go upstream (i.e. here) with this.

First of all, I'm using Python 3.6.0, setuptools 36.0.0.

In my setup.py I have the following:

setuptools.setup(
    name='my-package', ...,
    python_requires='3.5', ...,
    ...)

And when running python3.6 setup.py sdist (or other *dist*) I get the following error:

error in my-package setup command: 'python_requires' must be a string
containing valid version specifiers; Invalid specifier: '3.5'

But 3.5 is valid according to: https://www.python.org/dev/peps/pep-0345/#requires-python

This field specifies the Python version(s) that the distribution is guaranteed to be compatible with.

Version numbers must be in the format specified in Version Specifiers .

Examples:

Requires-Python: 2.5
Requires-Python: >2.1
Requires-Python: >=2.3.4
Requires-Python: >=2.5,<2.7

When I specify >=3.5 or >3.5 or ==3.5 or <3.5 or <=3.5 setuptools don't complain. But they somehow can't tolerate plain version number. I also checked some other version numbers, like 3 or 3.6. Getting same results.

I'm not sure if the problem is limited to python_requires field, but that's the only place I've seen it so far.

mbdevpl avatar Jun 01 '17 16:06 mbdevpl

Bug is still present in Python 3.6.8, setuptools 40.6.2.

ashtneoi avatar Mar 01 '19 21:03 ashtneoi

Bug is still present in Python 3.7.4, setuptools 41.0.1.

kleinesfilmroellchen avatar Jul 30 '19 17:07 kleinesfilmroellchen

Can someone come up with a test case using just 'packaging' so we know for a fact it's here and not in setuptools (Jason thinks it's "probably" here, but we should prove that first)?

And have people tested with version 19.1 that went out yesterday?

brettcannon avatar Jul 30 '19 18:07 brettcannon

PEP 345 is quite old, it has been superseded by PEP 566, which updates the version specifier specification to be what's defined in PEP 440. This PEP has no mention of specifiers without operators, but also doesn't specifically mention deprecating this from PEP 345.

In addition, "fixing" this has the effect of making the following a valid requirement:

some_package 1.2.3

(as opposed to some_package==1.2.3)

It'd be possible to add an additional constraint that "specifiers in requirements must have operators" but given that:

  • it wouldn't be very clean to implement
  • we've never actually supported this
  • we haven't had many requests to fix it

it might make more sense to amend the PEP instead to be more explicit that this is not supported.

@ncoghlan, @dstufft, as the original authors of PEP 440, any thoughts here?

di avatar Jul 30 '19 18:07 di

@brettcannon This is definitely happening in packaging, we are explicitly testing that an operator-less specifier is invalid:

https://github.com/pypa/packaging/blob/36984ad684dae7d14add4d0db99f8bf51586ee64/tests/test_specifiers.py#L47-L54

di avatar Jul 30 '19 18:07 di

We didn't really consider the Requires-Python field when designing PEP 440 - we were focused on package dependencies.

However, Requires-Python is a special case, as it doesn't require a name on the left hand side, so it's more natural to want to leave out the operator, and PEP 345 explicitly declares that to be legal. PEP 566 also gives an example without an operator, and only explicitly defers to PEP 440 for the version numbers, not the overall field format.

The examples in PEP 345 indicate that the implied PEP 440 operator for Requires-Python when one is omitted is ~=: https://www.python.org/dev/peps/pep-0345/#version-specifiers

ncoghlan avatar Jul 31 '19 15:07 ncoghlan

Relevant lines from PEP 345:

Requires-Python: 3: Any Python 3 version, no matter which one, excluding post or pre-releases. Requires-Python: >=2.6,<3: Any version of Python 2.6 or 2.7, including post releases of 2.6, pre and post releases of 2.7. It excludes pre releases of Python 3. Requires-Python: 2.6.2: Equivalent to ">=2.6.2,<2.6.3". So this includes only Python 2.6.2. Of course, if Python was numbered with 4 digits, it would have include all versions of the 2.6.2 series. Requires-Python: 2.5.0: Equivalent to ">=2.5.0,<2.5.1".

pradyunsg avatar Jul 31 '19 17:07 pradyunsg

The examples in PEP 345 indicate that the implied PEP 440 operator for Requires-Python when one is omitted is ~=:

I disagree.

The specifier for major.minor should be >=major.minor,<major.(minor+1) -- the +1 would be done on whatever the last segment in the version is.

That is distinct from ~= major.minor's equivalent >= major.minor, == major.*.

pradyunsg avatar Jul 31 '19 17:07 pradyunsg

(for those following via email -- I've updated my comment above)

pradyunsg avatar Jul 31 '19 17:07 pradyunsg

Ah, you're right - I missed that the examples without the specifier were more restrictive than the compatible version operator.

We could still decide to allow tools to apply the more permissive interpretation, but I agree that would be a spec change, whereas the restrictive interpretation would just be bringing forward the existing PEP 345 definition.

ncoghlan avatar Aug 08 '19 23:08 ncoghlan

hey guys, I am also facing a quit similar issue here and I don't understand what should i do?

Collecting smart-open==3.0.0 (from -r installables/requirements.txt (line 78))
  Downloading smart_open-3.0.0.tar.gz (113 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 113.0/113.0 kB 14.4 MB/s eta 0:00:00
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'error'
  error: subprocess-exited-with-error
  
  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [1 lines of output]
      error in smart_open setup command: 'python_requires' must be a string containing valid version specifiers; Invalid specifier: '>=3.5.*'
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

cipherML avatar Feb 02 '24 11:02 cipherML

error in smart_open setup command: 'python_requires' must be a string containing valid version specifiers; Invalid specifier: '>=3.5.*'

Please see https://github.com/pypa/packaging/issues/530, which is what you're seeing this message because of.

pradyunsg avatar Feb 03 '24 13:02 pradyunsg