Подтвердить что ты не робот

Запретить установку пакета на старых версиях 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?

4b9b3361

Ответ 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 наличие совместимых версий и в противном случае вызвать исключение.