2013-03-12 3 views
19

У меня возникла проблема с использованием setup.py для установки пакета python. Во-первых, у меня есть следующие настройки каталога:Ошибка импорта установленного пакета с помощью setup.py

maindir 
    |- setup.py 
    |-mymodule 
     |- __init__.py 
     |- mainmodule.py 
     |-subdir 
      |- __init__.py 
      |- submodule.py 

т.е. директория проекта содержит setup.py и каталог mymodule, который сам по себе содержит два питона модулей в двух каталогах. Файл 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 

Я не вижу, что Я поступил неправильно, поскольку я следил за Getting started tutorial и rules for importing intra-packages. Я полагаю, что моя ошибка очень крошечная, но я не могу ее заметить, и помощь приветствуется.

ответ

34

Вы должны перечислить все пакеты в setup, в том числе подпакетов:

setup(
    name = "mytestmodule", 
    version = "0.0.1", 
    description = ("A simple module."), 
    packages=['mymodule', 'mymodule.subdir'], 
) 

Или вы можете использовать setuptools «s волшебная функция find_packages:

from setuptools import setup, find_packages 
setup(
    name = "mytestmodule", 
    version = "0.0.1", 
    description = ("A simple module."), 
    packages=find_packages(), 
) 

Это упоминается here:

If you have sub-packages, they must be explicitly listed in packages, but any entries in package_dir automatically extend to sub-packages. (In other words, the Distutils does not scan your source tree, trying to figure out which directories correspond to Python packages by looking for __init__.py files.)

+1

Это описано где-то? Есть ли какая-то документация по содержимому 'setup' на' distutils'?Невозможно найти репрезентативную документацию. – Alex

+0

Добавлена ​​ссылка на пример из документов. –

+0

Для получения дополнительной информации о том, как «package_dir» используется рекурсивно для поиска подпакетов, при условии, что эти подпакеты перечислены в «пакетах», прочитайте [this] (https://docs.python.org/2/ Distutils/setupscript.html # список-все-пакеты). –

5

Вы необходимо явно указать свои модули. Вместо того чтобы поддерживать сложность добавления модуля к setup.py каждый раз, вы можете использовать метод find_packages от setuptools.

find_packages имеет два необязательных аргумента:

  1. where, который по умолчанию для '.' т.е. ваш CURDIR.
  2. exclude список вещей, чтобы исключить

я обычно тесты в моем репо, поэтому я использую:

from setuptools import find_packages 

packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), 
0

Я был scriptname.py:main в моем setup.py console_scripts, то .py является излишним.

Смежные вопросы