Как правильно упаковать приложение Python3 с подпакетами - PullRequest
1 голос
/ 11 июня 2019

У меня есть пакет, s3_backend, который содержит модуль api.py, и подпакет util, который сам содержит 5 модулей. Я хотел бы упаковать его и загрузить в PyPI, чтобы люди могли pip install package и использовать API сценариев api.py в пакете верхнего уровня. Оба пакета (s3_backend и 's3_backend.util') содержат файлы _init__.py.

Весь проект хранится в каталоге имен project со следующей структурой

project
    |- s3_backend (package)
        |- __init__.py
        |- util (package)
            |- __init__.py
            |- module1.py
            |...
            |- module5.py
        |- api.py
    |- setup.py

api.py сам импортирует modules1-4.

Локально, изнутри project, я могу сделать импорт API api.func1 () ... Без ошибок. Когда я загрузил пакет в TestPyPI и установил пакет в virtualenv в новом каталоге, я столкнулся с проблемами, связанными с оператором импорта в api.py, который импортирует modules1-4 из подпакета s3_backend.util.

Эта строка из утилиты import module1, module2, module3, module4 Выдает эту ошибку Нет названий модулей "util" Когда я запускаю эту команду из s3_backend import util

Я могу успешно

import s3_backend

и

help(s3_backend)

показывает

api.py
util (package)

Содержимое моего setup.py показано ниже. Как правильно обрабатывать подпакеты в моем файле setup.py, и я неправильно пишу свои операторы импорта?

Для исправлений я попытался заменить

from util import ...

с

from .util import ... 

и

from s3_backend.util import ... 

но это вызвало проблемы на местном уровне.

Исходный код для setup.py:

# project/setup.py
from distutils.core import setup

setup(
  name='s3_backend',
  version='0.1.7',
  license='MIT',
  description='scripting api for file upload to s3',
  author='SkippyElvis',
  author_email='Skippy@Elvis.com',
  url='https://github.com/jackhwolf/s3_backend',
  keywords=['aws', 's3', 'file upload'],
  packages=['s3_backend', 's3_backend.util'],
  classifiers=[
    'Programming Language :: Python :: 3',
  ],
)

Оператор импорта в api.py:

from util import module1, module2, module3, module4

Пожалуйста, дайте мне знать, если вам что-то понадобится, чтобы помочь мне. Спасибо!

SkippyElvis

1 Ответ

1 голос
/ 17 июня 2019

Не могли бы вы попробовать вместо этого использовать setuptools?Функция find_packages прекрасно работает, если у вас есть файл init .py в каждой папке, которую вы хотите включить.

Вот что вам нужно использовать в файле setup.py

# project/setup.py
from setuptools import setup, find_packages

setup(
  name='s3_backend',
  version='0.1.7',
  license='MIT',
  description='scripting api for file upload to s3',
  author='SkippyElvis',
  author_email='Skippy@Elvis.com',
  url='https://github.com/jackhwolf/s3_backend',
  keywords=['aws', 's3', 'file upload'],
  packages=find_packages(),
  classifiers=[
    'Programming Language :: Python :: 3',
  ],
)

В противном случае вы можете использовать функцию macuyver для имитации find_packages.Я бы не рекомендовал это.

Что касается вашего импорта, я сторонник использования абсолютного импорта на уровне корня.Это обеспечивает две вещи: это гарантирует, что вы используете библиотеки внутри себя так, как их будут использовать ваши пользователи.Кроме того, он также гарантирует, что вы не пытаетесь проверить свой код из какой-то папки, а вместо этого вызываете его с помощью тестов.То, как он «навязывает», то есть ваш абсолютный импорт не будет работать из какой-то папки.Вместо этого он должен вызываться через внешний вызов файла / функции.

...