在不同目录中使用源代码构建Python包

2024-03-28 10:36:52 发布

您现在位置:Python中文网/ 问答频道 /正文

在构建源代码树如下所示的python包时:

src -\
     +- module -\
           <stuff>
     +- setup.py

很清楚。你知道吗

有没有可能构建一个包,其中模块源与设置.py?对于更具体的用例,模块的代码要么在src之外的位置部分自动生成,要么完全自动生成

例如

src -\
     +- setup.py
generated -\
           module -\
                   <module code>

Tags: 模块代码pysrc源代码setupcode用例
2条回答

您可以使用package_dir参数来控制包所在的目录setup(...)

package_dir是一个以..开始的相对路径时,它看起来确实构建了一个正确的源代码分发,但是pip似乎会拒绝安装它,我建议您将生成的代码嵌套在src目录中,然后使用package_dir来选择它。你知道吗

下面是一个在generated子目录中移动所有模块的示例:

setup(
    name='mypkg',
    package_dir={'': 'generated'},
    packages=find_packages('generated'),
)

使用如下设置:

$ tree .
.
├── generated
│   ├── mod1
│   │   └── __init__.py
│   └── mod2
│       └── __init__.py
└── setup.py

这将使以下操作在安装后成功:import mod1; import mod2

如果要使这些模块以不同的前缀可用,可以执行以下操作:

setup(
    name='mypkg',
    package_dir={'hello': 'generated'},
    packages=[f'hello.{mod}' for mod in find_packages('generated')],
)

这将使import hello.mod1; import hello.mod2在安装之后成功

可以在包查找配置中使用相对路径。示例:

所有分布式源都位于generated

from setuptools import setup, find_packages


setup(
    ...
    package_dir={'': '../generated'},
    packages=find_packages(where='../generated'),
)

选定的包应该包含在generated

在本例中,只包括来自generatedspameggs包:

import pathlib
from setuptools import setup, find_packages


setup(
    name='so',
    package_dir={'spam': '../generated/spam', 'eggs': '../generated/eggs'},
    packages=find_packages(where='../generated'),  # or just ['spam', 'eggs']
)

或者实现动态查找,例如

package_dir={p.name: p.resolve() for p in pathlib.Path('..', 'generated').iterdir()}

通过解析与setup.py文件

相关的所有路径,可以更好地实现

解析与setup.py脚本相关的所有路径允许您从src以外的任何其他目录运行脚本,例如,您可以运行python src/setup.py bdist_wheel等。您可能需要它,也可能不需要它,这取决于您的用例。尽管如此,方法还是和往常一样:解析到__file__的所有路径,例如

import pathlib
from setuptools import setup, find_packages


src_base = pathlib.Path(__file__, '..', '..', 'generated').resolve()

setup(
    ...
    package_dir={'': str(src_base)},
    packages=find_packages(where=src_base),
)

相关问题 更多 >