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

2

5

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.

Deviation answered 1/1, 2018 at 10:7 Comment(0)
F
6

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"']
)
Freeloader answered 1/1, 2018 at 12:5 Comment(2)
The problem with the first approach is that if someone creates a wheel file using Python 3.5 or later, then the created wheel will not include the typing requirement and therefore that wheel won't install correctly on older python versions.Deviation
Usually, it's the project maintainer/developer who creates the wheels and uploads them to PyPI. He is responsible of building wheels that run on every platform/language implementation that are advertised to be supported (smth like mypkg-0.1-cp35.cp36-abi3-any.whl could be imaginable). If someone pulls your source code and builds a wheel that doesn't run, you can't be responsible for that ;-)Freeloader
D
4

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.

Deviation answered 6/1, 2018 at 16:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.