Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setup.py: require a recent version of setuptools before trying to install

I'm creating a package that has 'typing;python_version<"3.5"' in it's install_requires. Apparently, this kind of dependency specification has only been implemented in recent versions of setuptools. If the setuptools on the user's machine is old they'll get:

'install_requires' must be a string or list of strings containing valid project/version requirement specifiers; Expected version spec in typing;python_version<"3.5" at ;python_version<"3.5"

The easy solution is to tell the users to pip install 'setuptools>=36.2.1' before pip install my-package. (Note that 36.2.1 is just a version that I know works, not necessarily the the absolute minimum requirement)

But is there any way to specify this requirement in setup.py so that it gets done automatically? Adding setuptools>=36.2.1 to install_requires and setup_requires did not work. It says Installed /tmp/pip-si2fqg-build/.eggs/setuptools-38.2.5-py3.3.egg and then gives the same error above.

like image 231
AXO Avatar asked Jan 01 '18 10:01

AXO


2 Answers

You can't update setuptools and use its code in the setup script in one pass. I see two possible solutions: If you want to support old versions of setuptools, you can't use env markers. Implement the check yourself by using sys.version_info:

import sys
from setuptools import setup


setup(
    name='spam',
    version='0.1',
    packages=[],
    install_requires=['typing'] if sys.version_info < (3, 5) else []
)

If you don't want to support old versions of setuptools, check its version and abort early, informing the user:

import sys
from distutils.version import StrictVersion
from setuptools import setup, __version__


if StrictVersion(__version__) < StrictVersion('20.2'):
    print('your setuptools version does not support PEP 508. Upgrade setuptools and repeat the installation.')
    sys.exit(1)


setup(
    name='spam',
    version='0.1',
    packages=[],
    install_requires=['typing;python_version<"3.5"']
)
like image 103
hoefling Avatar answered Nov 07 '22 08:11

hoefling


I just learned about PEP 518 -- Specifying Minimum Build System Requirements for Python Projects that addresses this exact problem.

In short, this accepted PEP proposes to store dependencies in TOML format, in a file named pyproject.toml. For most Python projects the contents of this file will be:

[build-system]
# Minimum requirements for the build system to execute.
requires = ["setuptools", "wheel"]  # PEP 508 specifications.

In the case of this specific question, we just need to replace "setuptools" with "setuptools>=36.2.1".

The bad news is that pip does not support this yet. The good news is that it is implemented and will probably be shipped with pip 9.1.

like image 35
AXO Avatar answered Nov 07 '22 08:11

AXO