Python распространение пакета с entry_point console_script - PullRequest
4 голосов
/ 27 мая 2020

Я готовлюсь к развертыванию пакета Python со следующим макетом:

MyPackage/
  setup.py
  MyPackage/
    __init__.py
    __main__.py
    lib/
      __init__.py
      utils.py
    db/
      __init__.py
      db1.py
      db2.py 
    tasks/
      __init__.py
      something.py

setup.py содержит:

setup(name = MyPackage,
      ...
      packages = find_packages(),
      include_package_data = True,
      entry_points = {"console_scripts" : [
          "do_something = MyPackage.__main__:main"
      ]})

__main__.py содержит:

import tasks.something as something

something.my_function()

something модуль содержит:

import db.db1 as db1
import db.db2 as db2

def my_function():
  db1.this_func(...)
  db2.that_func(...)

db1 содержит:

import sqlalchemy
import lib.utils as utils

def this_func(...):
  sqlalchemy.create_engine(...)

и db2 содержит:

import sqlalchemy
import lib.utils as utils

def that_func(...):
  sqlalchemy.create_engine(...)

При запуске из установленного каталога site-packages, __main__.py завершается без проблем. Если я выполняю import MyPackage.tasks.something as something в интерактивном сеансе, модуль также импортирует с ошибкой. Однако, когда я запускаю сценарий console_scripts script do_something, я получаю ModuleNotFound ошибок для tasks.

Что заставляет мой скрипт консоли не находить подпакеты?

Заранее спасибо!

Ответы [ 2 ]

4 голосов
/ 06 июня 2020

Измените ваш импорт, следуя этому примеру:

__ main __. Py :

import tasks.something as something

# to:

import MyPackage.tasks.something as something

# or

from .tasks import something as something
2 голосов
/ 06 июня 2020

Тут две проблемы.

  1. Операторы импорта в __main__.py были неявными относительными. Измените их на абсолютный импорт.
  2. Целевая точка входа console_scripts должна преобразоваться в вызываемый , который не принимает аргументов . В вашем случае это означает, что модуль MyPackage/__main__.py должен определять вызываемый main.

Изменить __main__.py следующим образом:

from MyPackage.tasks import something

def main():
    # command line arguments parsing and logging configuration goes here ..
    something.my_function()

if __name__ == "__main__":
    main()

Точно так же вы должны изменить операторы импорта в db1, db2 и something в правильный относительный импорт:

from ..db import db1
from ..db import db2
from ..lib import utils

В качестве альтернативы используйте абсолютный импорт:

from MyPackage.db import db1
from MyPackage.db import db2
from MyPackage.lib import utils
...