2012-10-19 13 views
35

Podczas opisywania pakietu Pythona w setup.py w distutils w Pythonie, czy istnieje sposób, aby go tak automatycznie uzyskać każdy katalog, który ma w nim __init__.py i uwzględnić go jako podpakiet?make distutils w Pythonie automatycznie odnajduje pakiety

czyli jeśli struktura jest:

mypackage/__init__.py 
mypackage/a/__init__.py 
mypackage/b/__init__.py 

chcę uniknąć robi:

packages = ['mypackage', 'mypackage.a', 'mypackage.b'] 

i zamiast po prostu zrobić:

packages = ['mypackage'] 

i to automatycznie znaleźć rzeczy jak a i b, ponieważ mają plik init. dzięki.

+0

Wystarczy upewnić się, że nie dopuszczać do śmieci gromadzą się w swojej strukturze pakietu przed budową, jeśli to zrobisz. – asmeurer

Odpowiedz

13

Najłatwiej (które znam) jest użycie pkgutil.walk_packages otrzymując pakiety:

from distutils.core import setup 
from pkgutil import walk_packages 

import mypackage 

def find_packages(path=__path__, prefix=""): 
    yield prefix 
    prefix = prefix + "." 
    for _, name, ispkg in walk_packages(path, prefix): 
     if ispkg: 
      yield name 

setup(
    # ... snip ... 
    packages = list(find_packages(mypackage.__path__, mypackage.__name__)), 
    # ... snip ... 
) 
+1

Nie może (rzeczywiście, istnieje najbardziej prawdopodobne * są *) lepsze sposoby na zrobienie tego ... Po prostu nie znam ich (jeszcze) :-) –

+7

find_packages() z setuptools robi dokładnie to samo w zasadzie, zobacz moją odpowiedź – dm76

+1

@ dm76 tak, ale OP wymaga distutils, a nie setuptools. Czy czegoś brakuje? – Paolo

98

Polecam przy użyciu find_packages() funkcji dostępnej z setuptools takich jak:

from setuptools import setup, find_packages 

a następnie zrobić

packages=find_packages() 
+1

Zauważ, że 'find_packages()' nie znajduje> pakietów 3.3-style no-__init__.py. Bilet na ten temat jest dostępny na stronie https://bitbucket.org/pypa/setuptools/issue/97. Na razie konieczne jest dodanie plików '__init __. Py' w pakietach do automatycznego kolekcjonowania' find_packages() 'lub należy je jawnie nazwać w' pakietach'. – Iodnas

+1

Aktualizacja: Nawet lista jawna powoduje problemy, jeśli pliki '__init __. Py' nie są używane w Pythonie 3.3 (nie znaleziono pliku" package init "mymod/mysubmod/__ init__.py" (lub nie jest to zwykły plik) '). – Iodnas

2
import re, os 
def find_packages(path='.'): 
    ret = [] 
    for root, dirs, files in os.walk(path): 
     if '__init__.py' in files: 
      ret.append(re.sub('^[^A-z0-9_]+', '', root.replace('/', '.'))) 
    return ret 

setup(
... 
packages = find_packages() 
... 
) 
15

samo jak dm76 odpowiedź, tylko że ja również testy w moim repo, więc używam:

from setuptools import find_packages 

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