Как написать код Python, который может потребовать минимальную версию python?

Я хотел бы узнать, есть ли способ потребовать минимальную версию python.

У меня есть несколько модулей python, которым требуется Python 2.6 из-за новой обработки исключений (ключевое слово as).

Похоже, что даже если я проверю версию python в начале моего script, код не будет запущен, потому что интерпретатор не будет работать внутри модуля, выбросив уродливую системную ошибку вместо того, чтобы сообщать пользователю использовать новую питон.

Ответ 1

import sys
if sys.hexversion < 0x02060000:
    sys.exit("Python 2.6 or newer is required to run this program.")

import module_requiring_26

Также крутая часть об этом заключается в том, что она может быть включена внутри файла __init__ или модуля.

Ответ 2

Вам не следует использовать какие-либо функции Python 2.6 внутри самого script. Кроме того, вы должны выполнить проверку своей версии перед импортом любого из модулей, требующих новой версии Python.

например. запустите свой script так:

#!/usr/bin/env python
import sys

if sys.version_info[0] != 2 or sys.version_info[1] < 6:
    print("This script requires Python version 2.6")
    sys.exit(1)

# rest of script, including real initial imports, here

Ответ 3

Вы можете воспользоваться тем, что Python будет делать правильные вещи при сравнении кортежей:

#!/usr/bin/python
import sys
MIN_PYTHON = (2, 6)
if sys.version_info < MIN_PYTHON:
    sys.exit("Python %s.%s or later is required.\n" % MIN_PYTHON)

Ответ 4

Самый простой способ, который я нашел для этого (см. этот question), - это просто добавить строку, например:

b'You need Python 2.6 or later.'

в начале файла. Это приводит к тому, что байтовые литералы были введены в версии 2.6, поэтому любые более ранние версии будут поднимать SyntaxError с любым сообщением, которое вы пишете как трассировка стека.

Если вам нужен Python 2.7, как насчет:

{'You need Python 2.7 or later.'}

который является синтаксической ошибкой в ​​2.6.

Для Python 2.5 это должно работать:

'You need Python 2.5' if 'you want this to run or' else 'this line fails!'

который является синтаксической ошибкой в ​​2.4.

Ответ 5

Начиная с версии 9.0.0, pip поддерживает поле Require -Python в метаданных дистрибутива, которое может быть записано в setuptools начиная с версии 24-2-0. Эта функция доступна через python_requires ключевого слова python_requires для setup функции.

Пример (в setup.py):

setup(
...
   python_requires='>=2.5,<2.7',
...

)

Чтобы воспользоваться этой возможностью, нужно сначала упаковать проект/скрипт, если это еще не сделано. Это очень просто в типичном случае и, тем не менее, должно быть сделано, поскольку позволяет пользователям легко устанавливать, использовать и удалять данный проект/скрипт. Пожалуйста, смотрите подробности в Руководстве пользователя по упаковке Python.

Ответ 6

Я предполагаю, что у вас есть что-то вроде:

import module_foo
...
import sys
# check sys.version

но module_foo также требует определенной версии? В этом случае вполне правильно изменить код таким образом:

import sys
# check sys.version
import module_foo

Python не требует, чтобы импорт, кроме from __future__ import [something], находился в верхней части вашего кода.

Ответ 7

Вместо индексации вы всегда можете это сделать,

import platform
if platform.python_version() not in ('2.6.6'):
    raise RuntimeError('Not right version')

Ответ 8

В дополнение к существующим, полезным ответам:

Вы можете написать сценарии , которые работают как с Python 2.x, так и с 3.x, а требуют минимальную версию для каждого.

Например, если ваш код использует модуль argparse, вам нужно как минимум 2.7 (с 2.x Python) или не менее 3.2 (с 3.x Python).

Следующий фрагмент реализует такую ​​проверку; единственное, что нуждается в адаптации к другому, но аналогичному сценарию - это назначения MIN_VERSION_PY2=... и MIN_VERSION_PY3=....

Как было отмечено: это должно быть помещено вверху script, перед любыми другими операторами import.

import sys

MIN_VERSION_PY2 = (2, 7)    # min. 2.x version as major, minor[, micro] tuple
MIN_VERSION_PY3 = (3, 2)    # min. 3.x version

# This is generic code that uses the tuples defined above.
if (sys.version_info[0] == 2 and sys.version_info < MIN_VERSION_PY2
      or
    sys.version_info[0] == 3 and sys.version_info < MIN_VERSION_PY3):
      sys.exit(
        "ERROR: This script requires Python 2.x >= %s or Python 3.x >= %s;"
        " you're running %s." % (
          '.'.join(map(str, MIN_VERSION_PY2)), 
          '.'.join(map(str, MIN_VERSION_PY3)), 
          '.'.join(map(str, sys.version_info))
        )
      )

Если требования к версии не выполняются, в stderr будет напечатано что-то вроде следующего сообщения, а script выйдет с кодом выхода 1.

This script requires Python 2.x >= 2.7 or Python 3.x >= 3.2; you're running 2.6.2.final.0.

Примечание. Это, по существу, переписанная версия более раннего, ненужного сложного ответа, после осознания - благодаря Аркадию полезный ответ - что операторы сравнения, такие как > может быть непосредственно применен к кортежам.

Ответ 9

Мне нужно убедиться, что я использую Python 3.5 (или, в конечном счете, выше). Я обезглавил сам по себе, а затем я подумал спросить, что СО - но меня не впечатлили ответы (извините, y'all:: smile::). Вместо того, чтобы сдаться, я придумал подход ниже. Я тестировал различные комбинации спецификационных кортежей min_python и max_python и, похоже, хорошо работает:

  • Ввод этого кода в __init__.py привлекателен:

    • Предотвращает загрязнение многих модулей с проверкой избыточной версии
    • Размещение этого в верхней части иерархии пакетов еще больше поддерживает принципал DRY, предполагая, что вся иерархия соответствует тем же самым ограничениям на версию Python
    • Использует место (файл), где я могу использовать наиболее переносимый код Python (например, Python 1???) для логики проверки и все еще писать мои реальные модули в версии кода я хотите
    • Если у меня есть другой пакет-init, который не совместим со всеми версиями Python Versions Ever, я могу перекопать его в другой модуль, например. __init_p3__.py, как показано в окончательной строке прокомментированного образца. Не забудьте заменить держатель pkgname на соответствующее имя упаковки.
  • Если вы не хотите использовать min (или max), просто установите его на = ()

  • Если вы только заботитесь о основной версии, просто используйте "одно-плечо", например. = (3, ) Не забывайте запятую, в противном случае (3) является просто выражением в скобках (тривиальным), оценивающим один int
  • Вы можете указать более тонкий min/max, чем один или два уровня версии, например. = (3, 4, 1)
  • Будет только одно предложение "Предположите работать как", когда max на самом деле не больше min, либо потому, что max является пустым кортежем ( "none-ple"?), либо имеет меньшее количество элементов.

ПРИМЕЧАНИЕ. Я не очень люблю программиста Windoze, поэтому значения text_cmd_min и text_cmd_max ориентированы на * Nix-системы. Если вы исправите код для работы в других средах (например, Windoze или какой-то конкретный вариант Nix), отправьте сообщение. (В идеале для всех сред достаточно одного супер-умного кода, но я доволен своим решением только для Nix.)

PS: Я немного новичок в Python, и у меня нет интерпретатора с версией, меньшей 2,7.9.final.0, поэтому он туфа для проверки моего кода для более ранних вариантов, С другой стороны, кто-то действительно заботится? (Это актуальный вопрос, который у меня есть: В каком (реальном) контексте мне нужно было бы решить проблему "Изящный неправильный-Python-версия" для интерпретаторов до 2.7.9?)

__ __ INIT. Ру

'''Verify the Python Interpreter version is in range required by this package'''

min_python = (3, 5)
max_python = (3, )

import sys

if (sys.version_info[:len(min_python)] < min_python) or (sys.version_info[:len(max_python)] > max_python):

    text_have = '.'.join("%s" % n for n in sys.version_info)
    text_min  = '.'.join("%d" % n for n in min_python) if min_python else None
    text_max  = '.'.join("%d" % n for n in max_python) if max_python else None

    text_cmd_min = 'python' + text_min + '  ' + "  ".join("'%s'" % a for a in sys.argv) if min_python              else None
    text_cmd_max = 'python' + text_max + '  ' + "  ".join("'%s'" % a for a in sys.argv) if max_python > min_python else None

    sys.stderr.write("Using Python version: " + text_have + "\n")

    if min_python:  sys.stderr.write(" - Min required: " + text_min + "\n")
    if max_python:  sys.stderr.write(" - Max allowed : " + text_max + "\n")
    sys.stderr.write("\n")

    sys.stderr.write("Consider running as:\n\n")
    if text_cmd_min:  sys.stderr.write(text_cmd_min + "\n")
    if text_cmd_max:  sys.stderr.write(text_cmd_max + "\n")
    sys.stderr.write("\n")

    sys.exit(9)

# import pkgname.__init_p3__