web-dev-qa-db-ja.com

setup.pyを使用したインストール済みパッケージのインポートエラー

setup.pyを使用してpythonパッケージをセットアップする場合に問題があります。最初に、次のディレクトリをセットアップしています。

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

つまり、プロジェクトディレクトリにはsetup.pyとディレクトリmymoduleが含まれ、2つのディレクトリに2つの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'],
)

ipython内からsourceTestを使用してfrom mymodule import mainmoduleを実行すると、動作は期待どおりに機能し、たとえば次のように参照できます。 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 および intra-packagesをインポートするためのルール を実行したため、何が間違っているのかわかりません。私の間違いは本当に小さな間違いだと思いますが、それを見つけることはできず、助けていただければ幸いです。

28
Alex

サブパッケージを含む、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 packagesを検索して__init__.pyファイル。)

43
Pavel Anossov

各モジュールを明示的に指定する必要があります。毎回setup.pyにモジュールを追加する複雑さを維持する代わりに、find_packagesメソッド(setuptoolsから)。

find_packagesは2つのオプションの引数を取ります。

  1. whereこれはデフォルトで'.'つまり、curdir。
  2. exclude除外するもののリスト

私は通常、リポジトリにテストを持っているので、以下を使用します。

from setuptools import find_packages

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

scriptname.py:main私のsetup.py console_scriptsで、.pyは冗長です。

0
ThorSummoner