Python setup.py:如何让 find_packages() 识别子目录中的包

Posted

技术标签:

【中文标题】Python setup.py:如何让 find_packages() 识别子目录中的包【英文标题】:Python setup.py: How to get find_packages() to identify packages in subdirectories 【发布时间】:2019-06-23 03:35:47 【问题描述】:

我正在尝试创建一个 setup.py 文件,其中 find_packages() 递归地查找包。在此示例中,foobarbaz 都是我想要安装并在 python 路径上可用的模块。例如,我希望能够做到import foo, bar, bazbar-packfoo-pack 只是常规的非 python 目录,它们将包含各种支持文件/目录(例如特定于相应模块的测试、自述文件等)。

├── bar-pack
│   └── bar
│       └── __init__.py
├── baz
│   └── __init__.py
├── foo-pack
│   └── foo
│       └── __init__.py
├── setup.py

那么说setup.py如下:

from setuptools import setup, find_packages
setup(
    name="mypackage",
    version="0.1",
    packages=find_packages(),
)

但是,当我运行python setup.py installpython setup.py sdist 时,只有baz 目录被识别和打包。

我可以进一步简化它,并运行以下命令,但同样,只有baz 被识别。

python -c "from setuptools import setup, find_packages; print(find_packages())"
['baz']

你知道我可以如何扩展 find_packages() 的搜索路径(或手动硬编码搜索路径)吗?

感谢任何帮助。

【问题讨论】:

【参考方案1】:

这就像对“foo”和“bar”包使用src-layout,但对“baz”布局使用平面布局。这是可能的,但需要在setup.py 中进行一些自定义配置。

Setuptools 的find_packages 支持“where”关键字 (docs),您可以使用它。

setup(
    ...
    packages=(
        find_packages() +
        find_packages(where="./bar-pack") +
        find_packages(where="./foo-pack")
    ),
    ...
)

由于find_packages 返回一个普通的旧列表,您也可以手动列出您的包,这可以说更容易/不那么神奇。

setup(
    ...
    packages=["baz", "bar", "foo"],
    ...
)

非标准目录结构意味着您还需要为 distutils 指定 package_dir 结构,它描述了放置已安装包的位置。

拼凑起来:

setup(
    name="mypackage",
    version="0.1",
    packages=["baz", "bar", "foo"],
    package_dir=
        "": ".",
        "bar": "./bar-pack/bar",
        "foo": "./foo-pack/foo",
    ,
)

上面的安装程序会在 site-packages 中创建这个目录结构:

.venv/lib/python3.9/site-packages
├── bar
│   ├── __init__.py
│   └── __pycache__
│       └── __init__.cpython-39.pyc
├── baz
│   ├── __init__.py
│   └── __pycache__
│       └── __init__.cpython-39.pyc
├── foo
│   ├── __init__.py
│   └── __pycache__
│       └── __init__.cpython-39.pyc
└── mypackage-0.1.dist-info
    ├── INSTALLER
    ├── METADATA
    ├── RECORD
    ├── REQUESTED
    ├── WHEEL
    ├── direct_url.json
    └── top_level.txt

【讨论】:

以上是关于Python setup.py:如何让 find_packages() 识别子目录中的包的主要内容,如果未能解决你的问题,请参考以下文章

如何让`setup.py test`在Windows上与`multiprocessing`一起工作?

如何从“python setup.py test”运行 unittest discover?

如何在 Python 的 setup.py 中包含和安装本地依赖项?

[工具] 利用setuptools打包python程序

将数据文件添加到 python 项目 setup.py

让 sphinx 使用 setup.py 中的版本