Setup.py внутри установленного модуля

Для структуры каталогов, подобной следующей, мне не удалось сделать xy импортируемым пакетом.

xy
├── __init__.py
├── z
│   ├── __init__.py
│   └── stuff.py
└── setup.py

Если бы setup.py был каталогом вверх, я мог бы использовать

from setuptools import setup
setup(name='xy',
      packages=['xy'])

но кроме того, ни одна комбинация package_dir и packages не дала мне import xy, только import z. К сожалению, перемещение каталога setup.py вверх на самом деле не вариант из-за чрезмерного количества жестко закодированных путей.


person Alex Riina    schedule 17.01.2014    source источник
comment
Я не уверен, что понял ваш вопрос, но хотите ли вы импортировать xy, чтобы иметь доступ к xy.setup?   -  person Reti43    schedule 18.01.2014
comment
Я стремлюсь получить доступ к xy.z, не обязательно к xy.setup, но я бы предположил, что xy.setup будет доступен, если где-то явно не удалено.   -  person Alex Riina    schedule 18.01.2014
comment
Если вы напишете import z в xy/__init__.py, импортировав xy, вы должны иметь доступ к xy.z без дополнительной суеты.   -  person Reti43    schedule 18.01.2014
comment
К сожалению, я пытаюсь добавить setup.py в намного большую кодовую базу, чем указано здесь, и импорт всей кодовой базы в файл __init__ не будет приятным даже с некоторым циклом __import__ find_packages().   -  person Alex Riina    schedule 18.01.2014
comment
Это выходит за рамки моего знания, но у меня сложилось впечатление, что вы не можете избежать того факта, что в конечном итоге вы явно объявили желаемый импорт. Будет ли __all__ вообще приятным ?   -  person Reti43    schedule 18.01.2014


Ответы (2)


Я столкнулся с той же проблемой и не нашел подходящего решения (читай «использование предопределенных параметров настройки»).

В итоге я сделал уродливый патч: я перемещаю все в новый подкаталог с именем пакета, а затем перемещаю все обратно.

import os, errno

# create directory
directory = 'xy/'
try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

# move important files
move = [ ... ]

for fname in move:
    os.rename(fname, directory + fname)

setup(
    ...
    package_dir = {'': '.'},
    ...
)


# move back
for fname in move:
    os.rename(directory + fname, fname)
person Silmathoron    schedule 16.08.2017

См. следующий ответ, чтобы узнать, как использовать package_dir и packages для помощи в таких проектах: https://stackoverflow.com/a/58429242/11138259

Вкратце для этого случая здесь:

#!/usr/bin/env python3
import setuptools
setuptools.setup(
    # ...
    packages=['xy', 'xy.z'],
    #packages=setuptools.find_packages('..')   # only if parent directory is otherwise empty
    package_dir={
        'xy': '.',
    },
)
person sinoroc    schedule 17.10.2019