Упаковка на Python в 2020 году

#python #pip #packaging

#python #pip #упаковка

Вопрос:

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

Я прочитал определенное количество сообщений, обсуждений и pep 517/518. Тем не менее, я все еще не до конца понимаю, как правильно организовать мои файлы для упаковки.

Я решил следовать setup.cfg пути, а pyproject.toml не пути. Это ясно. Я определю необходимый пакет для выполнения в setup.cfg .

Я также использую virtualenv , и я понял, что пакет, связанный с разработкой ( black , pytest,... ), должен быть определен в отдельном файле setup.cfg , обычно вызываемом requirements.txt . Одна вещь, которая не ясна: должно setup.cfg быть подмножеством requirements.txt и, следовательно, повторять некоторую информацию? Это кажется плохой практикой и в какой-то момент определенно станет отключенным и сложным в обслуживании.

Я пытался найти ответ на этот вопрос. Я нашел эту статью, но я не понимаю, как добавить это

 --index-url https://pypi.python.org/simple/ 
-e .
  

в requirements.txt помогает избежать проблемы или даже справиться с зависимостями разработки.

Я еще больше теряюсь, когда он представляет следующую возможность:

 --index-url https://pypi.python.org/simple/ 
-e https://github.com/foo/bar.git#egg=bar
-e .
  

Чего это дает?

Наконец, совместим ли этот setup.cfg способ с пакетом building of wheels?

Комментарии:

1. Отличный вопрос — существует множество (часто противоречивых) фольклорных материалов — было бы неплохо получить окончательное представление об этом. В идеале такая, в которой указано определенное количество полей, таких как; Простота развертывания, воспроизводимость, простота и прямолинейность, понятная конечным пользователям и с минимальным элементом неожиданности.

2. Любопытно, почему вы отклоняете pyproject.toml путь. Похоже, что pypoetry упрощает управление пакетами с их помощью.

3. Судя по моим показаниям, setup.cfg поддерживается более широко. И на сегодняшний день между ними нет явного победителя. Поэтому я подумал … лучше пойти по наиболее поддерживаемому маршруту

4. Я думаю, у вас недоразумение: requirements.txt не используется для зависимостей разработчиков. Он используется для закрепления развертывания, аналогично тому, что другие языки называют файлом блокировки. Yes setup.cfg перечислит подмножество зависимостей, уже упомянутых в requirements.txt (потому что в первом перечислены только ваши прямые зависимости, а не транзитивные). Но это не совсем дублирование информации, потому что в настройках у вас есть спецификаторы совместимости, такие как верхняя или нижняя границы, тогда как requirements.txt должны быть все == булавки. Я согласен с Эндрю, что pyproject.toml — гораздо лучший выбор, чем setup.cfg.

5. Кстати, обычно не имеет большого значения, что больше всего «поддерживается» пользователем пакета, потому что после публикации файла wheel setup.py/setup.cfg их там даже нет. Они не попадают в колесо. Это только ваша машина разработки, которая создает дистрибутив, в котором вам нужны достаточно последние версии setuptools и т. Д. Если вы не хотите публиковать sdist (что является еще одной банкой червей), среда сборки остается под вашим собственным контролем.

Ответ №1:

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

Подход №1

В моем setup.py файле конфигурации я использую это extras_require поле для определения зависимостей, связанных с разработкой, например:

setup.py

 from setuptools import find_packages, setup

INSTALL_REQUIRES = ["python-dotenv"]
EXTRAS_REQUIRE = {
    "dev": ["flake8", "black", "mypy"],
}


setup(
    name="mypackage",
    version="0.1.0",
    description="My awesome package",
    packages=find_packages(),
    install_requires=INSTALL_REQUIRES,
    extras_require=EXTRAS_REQUIRE,
    python_requires=">=3.8",
)
  

Как вы можете видеть выше, у меня есть EXTRAS_REQUIRE словарь с dev ключом, в котором я перечисляю свои зависимости от разработчиков.
Затем я могу использовать pip для установки пакета. Если я хочу исключить установку, которую я просто делаю pip install . , таким образом python-dotenv mypackage , в вашей среде будут установлены только требуемые и, очевидно, пакеты.
Однако, если вы хотите включить зависимости, связанные с разработкой, вы можете указать дополнительную установку следующим pip install .['dev'] образом, тогда все ваши dev dev также будут установлены в среде.

Подход №2

В случае, если вы настаиваете на том, чтобы ваши требования к разработчикам содержались в отдельном файле требований, вы также можете это сделать, давайте вызовем его requirements-dev.txt и заполним следующим образом:

requirements-dev.txt

 .  # note the dot here, this will tell pip to include the install_requires deps from your setup.py
flake8
black
mypy
  

и измените предыдущий setup.py , удалив дополнительный словарь:

setup.py

 
from setuptools import find_packages, setup

INSTALL_REQUIRES = ["python-dotenv"]

setup(
    name="mypackage",
    version="0.1.0",
    description="My awesome package",
    packages=find_packages(),
    install_requires=INSTALL_REQUIRES,
    python_requires=">=3.8",
)
  

Затем вы можете установить свой пакет, pip install -r requirements-dev.txt и если вы не хотите устанавливать зависимости разработчика, вы просто делаете обычное pip install . и все.