在setup.py构建中包括项目根目录中的python文件 [英] including python file from project root in setup.py build

查看:56
本文介绍了在setup.py构建中包括项目根目录中的python文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在运行时创建的build/lib目录中包含一个python文件

I am trying to include a python file in the build/lib directory created when running

python setup.py install

尤其是,我想包含一个简单的配置文件('definitions.py'),该文件定义了ROOT_DIR变量,然后由子程序包使用."definitions.py"文件包含:

In particular, I would like to include a simple configuration file ('definitions.py') that defines a ROOT_DIR variable, which is then used by subpackages. The 'definitions.py' file contains:

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

我的目标是让每个子包('config.py')内的配置文件都调用ROOT_DIR来构建自己的绝对路径:

My goal is to have configuration files within each subpackage ('config.py') call ROOT_DIR to build their own absolute paths:

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

这个想法是从以下stackoverflow答案中得出的: https://stackoverflow.com/a/25389715 .
但是,在运行"setup.py install"时,此"definitions.py"文件永远不会显示在构建目录中.

The idea is drawn from this stackoverflow answer: https://stackoverflow.com/a/25389715.
However, this 'definitions.py' file never shows up in the build directory when running 'setup.py install'.

这是项目的目录结构:


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

我的多次尝试均失败(尝试,例如 https://stackoverflow.com/a/11848281 中提供的建议).据我所知,这是因为definitions.py位于项目结构的顶层(缺少__init__.py文件).

My multiple attempts have failed (trying, e.g. the suggestions offered in https://stackoverflow.com/a/11848281). As far as I can tell, it's because definitions.py is in the top-level of my project structure (which lacks an __init__.py file).

我尝试过:

1)...在setuptools.setup()中使用'package-data'变量

1) ...using the 'package-data' variable in setuptools.setup()

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

,但是definitions.py不会显示在内部版本
中(我认为是因为definitions.py不在具有__init__.py的包"中).

but definitions.py does not show up in the build
(I think because definitions.py is not in a 'package' that has an __init__.py?).

2)...使用MANIFEST.in文件,但这也不起作用
(我认为是因为MANIFEST不适用于.py文件?)

2) ...using a MANIFEST.in file, but this also does not work
(I think because MANIFEST does not work with .py files?)

我的问题
是否可以在构建目录中包含definitions.py?
或者,是否可以提供一种更好的方法来提供从顶级目录构建的多个子包的绝对路径的访问权限?

My question:
Is there a way to include definitions.py in the build directory?
Or, is there a better way to provide access to absolute paths built from the top-level directory for multiple sub-packages?

推荐答案

如果您正在寻找一种方法来访问已安装模块中的非python数据文件,例如您所链接的问题(顶级软件包(应该可以在子软件包中访问),请使用 pkg_resources 机制,而不要发明自定义路径分辨率.项目结构示例:

If you are looking for a way to access a non-python data file in the installed module like in the question you've linked (a configuration file in the top-level package that should be accessible in subpackages), use pkg_resources machinery instead of inventing a custom path resolution. An example project structure:

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 ,它提供了现代资源利用 pathlib :

Update:

As pointed out by wim in the comments, there's now a backport for importlib.resources (which is only available in Python 3.7 and onwards) - importlib_resources, which offers a modern resource machinery that utilizes 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 从软件包的任何位置,而无需执行任何路径解析:

Original answer

Using pkg_resources, you can access the root/config.txt from any spot of your package without having to perform any path resolution at all:

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')

这篇关于在setup.py构建中包括项目根目录中的python文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆