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

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

Open
mbdevpl opened this issue Jun 1, 2017 · 12 comments

Comments

@mbdevpl
Copy link

mbdevpl commented Jun 1, 2017

Hello, please excuse me barging in here, it was suggested in the issue I submitted in setuptools pypa/setuptools#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.

@ashtneoi
Copy link

ashtneoi commented Mar 1, 2019

Bug is still present in Python 3.6.8, setuptools 40.6.2.

@kleinesfilmroellchen
Copy link

Bug is still present in Python 3.7.4, setuptools 41.0.1.

@brettcannon
Copy link
Member

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?

@di
Copy link
Member

di commented Jul 30, 2019

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
Copy link
Member

di commented Jul 30, 2019

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

def test_specifiers_valid(self, specifier):
Specifier(specifier)
@pytest.mark.parametrize(
"specifier",
[
# Operator-less specifier
"2.0",

@ncoghlan
Copy link
Member

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

@pradyunsg
Copy link
Member

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
Copy link
Member

pradyunsg commented Jul 31, 2019

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
Copy link
Member

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

@ncoghlan
Copy link
Member

ncoghlan commented Aug 8, 2019

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.

grking8 added a commit to grking8/python-pypi-example that referenced this issue Dec 29, 2019
@cipherML
Copy link

cipherML commented Feb 2, 2024

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.

@pradyunsg
Copy link
Member

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

Please see #530, which is what you're seeing this message because of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants