Запретить установку пакета на старых версиях Python
Что мы можем поместить в файл setup.py
чтобы pip не собирал и не пытался установить пакет при использовании неподдерживаемой версии Python?
Например, magicstack
- это проект, перечисленный с помощью классификатора magicstack
:
Programming Language :: Python :: 3 :: Only
Поэтому я ожидаю следующего поведения, если pip --version
привязан к python 2.7:
$ pip install magicstack
Collecting magicstack
Could not find a version that satisfies the requirement magicstack (from versions: )
No matching distribution found for magicstack
Но на самом деле pip собирает релиз, загружает его, пытается установить и терпит неудачу. Существуют и другие выпуски только для Python3, например, curio
, которые на самом деле отлично устанавливаются - потому что setup.py
не использовал ничего специфичного для Python 3 - только для сбоя во время импорта, когда используется только один синтаксис Python 3. И я уверен, что есть пакеты, которые устанавливают нормально, импортируют нормально, и, возможно, только сбой во время выполнения!
Какой правильный способ указать поддерживаемые версии Python таким образом, чтобы pip уважал? Я нашел обходной путь, включающий загрузку только файла колеса и отказывающийся загружать дистрибутив .tar.gz, но мне было бы интересно узнать правильное исправление.
Редактировать: Как pip узнает, что не нужно загружать дистрибутив колеса, если Python/os/архитектура не совпадает? Использует ли он просто соглашение о именах файлов .whl или есть что-то более сложное, чем то, что происходит за кулисами? Можем ли мы как-то передать метаданные в исходный дистрибутив, чтобы pip правильно делал с загрузками .tar.gz?
Ответы
Ответ 1
Существует правильный способ сделать это, но, к сожалению, pip начал поддерживать его только в версии 9.0.0 (выпущена 2016-11-02), и поэтому пользователи с более старыми версиями pip будут продолжать загружать пакеты по воле, независимо от того, какой Python версия они для.
В вашем файле setup.py
передайте setup()
аргумент python_requires
в python_requires
качестве python_requires
версии PEP 440 указан список поддерживаемых версий Python для вашего пакета. Например, если ваш пакет предназначен только для Python 3+, напишите:
setup(
...
python_requires='>=3',
...
)
Если ваш пакет предназначен для Python 3.3 и выше, но вы еще не готовы перейти на поддержку Python 4, напишите:
setup(
...
python_requires='~=3.3',
...
)
Если ваш пакет предназначен для Python 2.6, 2.7 и всех версий Python 3, начиная с 3.3, напишите:
setup(
...
python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4',
...
)
И так далее.
После того, как вы это сделаете, вам нужно обновить версию setuptools как минимум до 24.2.0 для python_requires
аргумента python_requires
; более ранние версии просто проигнорируют это с предупреждением. После этого все созданные вами проектные диски и диски будут содержать соответствующие метаданные, которые сообщают PyPI сообщить pip, для каких версий Python они предназначены.
Ответ 2
Распределение magicstack
по pypi нарушено. magicstack
потому что исходный дистрибутив не содержит пакета magicstack
, хотя setup.py
для исходного дистрибутива говорит, что должен.
Пока pypi содержит исходный дистрибутив (например, .tar.gz
, .zip
), pip будет загружать его, если не сможет найти соответствующий бинарный дистрибутив (например, .egg
, .whl
) для вашей версии python/os/зодчества,
Один из вариантов - загружать только двоичные дистрибутивы в PyPI (предпочтительно wheels
). Другой вариант - проверить sys.version
в вашем setup.py
наличие совместимых версий и в противном случае вызвать исключение.