web-dev-qa-db-fra.com

Erreur d'importation sur le paquet installé à l'aide de setup.py

J'ai un problème avec l'utilisation de setup.py pour configurer un paquet Python. Premièrement, j'ai la configuration de répertoire suivante:

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

c’est-à-dire que le répertoire du projet contient le setup.py et un répertoire mymodule, qui contient deux modules python dans deux répertoires. Le fichier submodule.py contient seulement

teststring = "hello world"

mainmodule.py contient:

from .subdir import submodule
mainstring = "42"

et setup.py contient:

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

Quand je fais from mymodule import mainmodule avec ipython depuis sourceTest, le comportement fonctionne comme prévu et je peux faire référence par exemple à. mainmodule.submodule.teststring qui me donne la chaîne hello world

D'un autre côté, lorsque j'installe ce 'package' en utilisant python setup.py install et que j'essaie de faire de même (depuis un autre répertoire), j'obtiens une erreur d'importation:

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

Je ne vois pas ce que j'ai fait de mal, car j'ai suivi un Tutoriel de démarrage et pour importer des intra-packages . Je suppose que mon erreur est minime, mais je ne peux pas la repérer et l’aide est appréciée. 

22
Alex

Vous devez répertorier tous les packages dans setup, y compris les sous-packages:

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

Ou vous pouvez utiliser la fonction magique setuptools_ find_packages:

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

Ceci est mentionné ici :

Si vous avez des sous-packages, ils doivent être explicitement répertoriés dans les packages, , Mais toutes les entrées de package_dir s'étendent automatiquement aux sous-packages. (Autrement dit, Distutils n'analyse pas votre arborescence de sources, en essayant de trouver quels répertoires correspondent aux paquets Python de recherchant des fichiers __init__.py.)

39
Pavel Anossov

Vous devez spécifier vos chaque modules explicitement. Au lieu de maintenir la complexité de l'ajout de module à setup.py à chaque fois, vous pouvez utiliser la méthode find_packages de setuptools.

find_packages prend deux arguments optionnels:

  1. where qui correspond par défaut à '.', c'est-à-dire votre curdir. 
  2. exclude liste de choses à exclure

J'ai habituellement des tests dans mon dépôt, alors j'utilise:

from setuptools import find_packages

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

J'ai eu scriptname.py:main dans mon setup_ps console_scripts, le .py est redondant.

0
ThorSummoner