Как организовать модули Python для PyPI для поддержки 2.x и 3.x

У меня есть модуль Python, который я хотел бы загрузить на PyPI. До сих пор это работает на Python 2.x. Не должно быть слишком трудно записать версию для 3.x теперь.

Но, после следующих инструкций для того, чтобы сделать модули в этих местах:

мне не ясно, как поддерживать несколько исходных дистрибутивов для различных версий Python, и не ясно, мог ли PyPI поддерживать его. Я предусматриваю, у меня был бы отдельный код для:

  • 2.x
  • 2.6 (возможно, как особый случай для использования нового буферного API)
  • 3.x

Как это возможный настроить модуль Python в PyPI так, чтобы кто-то мог сделать:

easy_install modulename

и это установит правильную вещь, использует ли пользователь 2.x или 3.x?

17
задан Craig McQueen 8 March 2010 в 01:12
поделиться

2 ответа

Я обнаружил, что setup.py для httplib2 кажется, имеет элегантный способ поддержки Python 2.x и 3.x. Поэтому я решил скопировать этот метод.

Задача состоит в том, чтобы создать единый setup.py для дистрибутива пакета, который работает со всеми поддерживаемыми дистрибутивами Python. Затем с помощью того же setup.py можно сделать:

python2 setup.py install

а также

python3 setup.py install

Должно быть возможно сохранить setup.py достаточно простым, чтобы его можно было разобрать со всеми поддерживаемыми дистрибутивами Python. Я успешно сделал это с помощью пакета cobs , который поддерживает 2.4 - 2.6, а также 3.1. Этот пакет включает чистый код Python (отдельный код для Python 2.x и 3.x) и расширения C, написанные отдельно для 2.x и 3.x.

Чтобы сделать это:

1) Я поместил код Python 2.x в подкаталог python2, а код Python 3.x в подкаталог python3.

2) Я поместил код расширения C для 2.x и 3.x в каталог src под python2 и python3.

Итак, структура каталогов такова:

root
  |
  +--python2
  |     |
  |     +--src
  |
  +--python3
  |     |
  |     +--src
  |
  +--setup.py
  +--MANIFEST.in

3) В setup. py, у меня были эти строки в самом верху:

if sys.version_info[0] == 2:
    base_dir = 'python2'
elif sys.version_info[0] == 3:
    base_dir = 'python3'

4) В вызове setup, я указал пакеты как обычно:

setup(
    ...
    packages=[ 'cobs', 'cobs.cobs', 'cobs.cobsr', ],

5) Я указал базовый каталог для кода Python, используя опцию package_dir (см. шаг 3 для base_dir):

    package_dir={
        'cobs' : base_dir + '/cobs',
    },

6) Для расширений C я указал путь:

    ext_modules=[
        Extension('cobs.cobs._cobs_ext', [ base_dir + '/src/_cobs_ext.c', ]),
        Extension('cobs.cobsr._cobsr_ext', [ base_dir + '/src/_cobsr_ext.c', ]),
    ],

Это было все для setup. py. Файл setup.py разбирается как Python 2.x, так и 3.x.

7) Наконец, если вы собираете исходный дистрибутив, используя:

python2 setup.py sdist

то по умолчанию он будет подтягивать только те файлы, которые необходимы для сборки под данный Python. Например, в приведенном выше случае вы получите только файлы под python2 в исходном дистрибутиве, но не файлы под python3. Но для полного дистрибутива исходников вы хотите включить файлы и для 2.x, и для 3.x. Для этого создайте файл MANIFEST.in, который будет содержать что-то вроде этого:

include *.txt
recursive-include python2 *
recursive-include python3 *

Чтобы увидеть, что я сделал, посмотрите исходный код cobs на PyPI или BitBucket.

18
ответ дан 30 November 2019 в 13:53
поделиться

Самое простое решение - использовать дистрибутив с одним исходным кодом.

1
ответ дан 30 November 2019 в 13:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: