включая файл python из корня проекта в сборку setup.py - PullRequest
0 голосов
/ 23 октября 2018

Я пытаюсь включить файл python в каталог build / lib, созданный при запуске

python setup.py install

В частности, я хотел бы включить простой файл конфигурации ('definitions.py'), который определяетпеременная ROOT_DIR, которая затем используется подпакетами.Файл 'definitions.py' содержит:

import os
ROOT_DIR  = os.path.dirname(os.path.abspath(__file__))

Моя цель состоит в том, чтобы файлы конфигурации в каждом подпакете ('config.py') вызывали ROOT_DIR для создания своих собственных абсолютных путей:

from definitions import ROOT_DIR
PACKAGE_DIR = os.path.join(ROOT_DIR, 'package1/')

Идея взята из этого ответа на стек: https://stackoverflow.com/a/25389715.Тем не менее, этот файл «Definition.py» никогда не отображается в каталоге сборки при запуске «setup.py install».

Вот структура каталогов проекта:

project
|
├── setup.py
|
├── definitions.py
|
├── package1
|   ├── __init__.py
|   ├── config.py
|   └── ...
|
├── package2
|   ├── __init__.py
|   └── ...
└── ...

Мои многочисленные попытки не увенчались успехом (пытались, например, предложения, предложенные в https://stackoverflow.com/a/11848281). Насколько яМожно сказать, это потому, что Definition.py находится на верхнем уровне структуры моего проекта (в котором отсутствует файл __init__.py).

Я пытался:

1) ... с помощью переменной 'package-data' в setuptools.setup ()

package_data={'package': ['./definitions.py']}

но определение .py не отображается в сборке (я думаю, потому что defines.py отсутствует в «пакете» с __init__.py?).

2) ... с использованием файла MANIFEST.in, но это также не работает (я думаю, потому что MANIFEST не работает с .py файлами?)

Мой вопрос: Есть ли способ включить определения .py в каталог сборки?Или есть ли лучший способ обеспечить доступ к абсолютным путям, созданным из каталога верхнего уровня для нескольких подпакетов?

1 Ответ

0 голосов
/ 23 октября 2018

Если вы ищете способ доступа к файлу данных, отличному от python, в установленном модуле, как в вопросе, который вы связали (файл конфигурации в пакете верхнего уровня, который должен быть доступен в подпакетах), используйте pkg_resources машинное оборудование вместо того, чтобы придумывать собственное разрешение пути.Пример структуры проекта:

project
├── setup.py
└── root
    ├── __init__.py
    ├── config.txt
    ├── sub1
    │   └── __init__.py
    └── sub2
        └── __init__.py

setup.py:

from setuptools import setup

setup(
    name='myproj',
    ...,
    packages=['root', 'root.sub1', 'root.sub2'],  # or setuptools.find_packages()
    package_data={'root': ['config.txt']}
)

Обновление:

Как указано wim в комментариях,теперь есть бэкпорт для importlib.resources (который доступен только в Python 3.7 и более поздних версиях) - importlib_resources, который предлагает современный механизм ресурсов, использующий pathlib:

# access the filepath
importlib_resources.path('root', 'config.txt')

# access the contents as string
importlib_resources.read_text('root', 'config.txt')

# access the contents as file-like object
importlib_resources.open_binary('root', 'config.txt')

Оригинальный ответ

Используя pkg_resources, вы можете получить доступ к root/config.txt из любой точки вашего пакета без необходимости выполнять какое-либо разрешение пути вообще:

import pkg_resources

# access the filepath:
filepath = pkg_resources.resource_filename('root', 'config.txt')

# access the contents as string:
contents = pkg_resources.resource_string('root', 'config.txt')

# access the contents as file-like object:
contents = pkg_resources.resource_stream('root', 'config.txt')

и т. Д.

...