如何在Python命名空间包中正确打包根级别模块?
问题描述
项目结构如下:
<project root> setup.py <namespace_package> module_a.py module_b.py <package> __init__.py
根据PyPA文档,该布局是合规的,本地通过pip可编辑安装也能正常运行,但创建sdist或wheel包时,module_a.py和module_b.py并未被包含进去。当前使用的setup.py代码如下:
from setuptools import find_namespace_packages, setup setup( name="foo", version="0.1", description="foo", long_description="fooooooooooooooooo", author="me", author_email="me@non-ya.business", packages=find_namespace_packages(include=["namespace_package.*"]), include_package_data=True, )
我不想把这些根级别模块改成同名目录下的__init__.py文件(不符合Python风格),请问有没有更简洁的解决方法?
解决方案
方法一:调整find_namespace_packages的包含范围
find_namespace_packages(include=["namespace_package.*"])只会匹配namespace_package下的子包,不会包含namespace_package这个命名空间包本身的模块。只需把include参数改成同时包含命名空间包本身即可:
from setuptools import find_namespace_packages, setup setup( name="foo", version="0.1", description="foo", long_description="fooooooooooooooooo", author="me", author_email="me@non-ya.business", packages=find_namespace_packages(include=["namespace_package", "namespace_package.*"]), include_package_data=True, )
这样find_namespace_packages会识别namespace_package作为命名空间包,同时自动包含它下面的所有顶层模块和子包,无需手动维护模块列表。
方法二:结合py_modules显式指定模块
如果不想修改find_namespace_packages的参数,可以用py_modules单独列出这些顶层模块,同时保留子包的自动查找:
from setuptools import find_namespace_packages, setup setup( name="foo", version="0.1", description="foo", long_description="fooooooooooooooooo", author="me", author_email="me@non-ya.business", packages=find_namespace_packages(include=["namespace_package.*"]), py_modules=["namespace_package.module_a", "namespace_package.module_b"], include_package_data=True, )
不过这种方法需要手动添加新的顶层模块,不如方法一简洁高效。
补充说明
命名空间包本身不需要__init__.py,但setuptools的find_namespace_packages默认只会扫描包含子包的目录,当目录下只有单独的模块文件时,必须显式指定包含该目录,才能让打包工具识别并打包这些模块。
内容的提问来源于stack exchange,提问作者carej
相关产品推荐
相关产品推荐

