Ошибка импорта установленного пакета с помощью setup.py
У меня есть проблема с использованием setup.py
для установки пакета python. Во-первых, у меня есть следующая настройка каталогов:
maindir
|- setup.py
|-mymodule
|- __init__.py
|- mainmodule.py
|-subdir
|- __init__.py
|- submodule.py
то есть. каталог проекта содержит setup.py
и каталог mymodule
, который сам по себе содержит два модуля python в двух каталогах.
Файл submodule.py
содержит только
teststring = "hello world"
mainmodule.py
содержит:
from .subdir import submodule
mainstring = "42"
и setup.py
содержит:
import os
from setuptools import setup
setup(
name = "mytestmodule",
version = "0.0.1",
description = ("A simple module."),
packages=['mymodule'],
)
Когда я выполняю from mymodule import mainmodule
с ipython
из sourceTest
, поведение работает так, как ожидалось, и я могу ссылаться, например. mainmodule.submodule.teststring
, который дает мне строку hello world
.
С другой стороны, когда я устанавливаю этот "пакет" с помощью python setup.py install
и пытаюсь сделать то же самое (из какого-то другого каталога), я получаю ошибку импорта:
In [1]: from mymodule import mainmodule
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
/home/alexander/<ipython-input-1-cf4c9bafa487> in <module>()
----> 1 from mymodule import mainmodule
/home/alexander/build/bdist.linux-i686/egg/mymodule/mainmodule.py in <module>()
ImportError: No module named subdir
Я не вижу, что я сделал неправильно, так как я следовал правилам Начало работы и для импорта внутри- пакеты. Я полагаю, что моя ошибка очень крошечная, но я не могу ее заметить, и помощь приветствуется.
Ответы
Ответ 1
Вы должны перечислить все пакеты в setup
, включая подпакеты:
setup(
name = "mytestmodule",
version = "0.0.1",
description = ("A simple module."),
packages=['mymodule', 'mymodule.subdir'],
)
Или вы можете использовать магическую функцию setuptools
find_packages
:
from setuptools import setup, find_packages
setup(
name = "mytestmodule",
version = "0.0.1",
description = ("A simple module."),
packages=find_packages(),
)
Это упоминается здесь:
Если у вас есть подпакеты, они должны быть явно указаны в пакетах, но любые записи в package_dir автоматически распространяются на подпакеты. (Другими словами, Distutils не сканирует ваше исходное дерево, пытаясь выяснить, какие каталоги соответствуют пакетам Python, ищет файлы __init__.py
.)
Ответ 2
Вам нужно явно указать свои модули. Вместо того чтобы поддерживать сложность добавления модуля в setup.py каждый раз, вы можете использовать метод find_packages
от setuptools
.
find_packages
принимает два необязательных аргумента:
-
where
, который по умолчанию равен '.'
в вашем curdir.
-
exclude
список исключений для
Обычно у меня есть тесты в моем репо, поэтому я использую:
from setuptools import find_packages
packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
Ответ 3
У меня было scriptname.py:main
в моих setup.py console_scripts, .py
является избыточным.