从 python bdist_egg 或 bdist_wheel 中排除单个源文件
Exclude single source file from python bdist_egg or bdist_wheel
背景:我有一个负责安全的源文件。里面有魔法键和特定算法。
是否可以从 python egg 或 wheel 包中删除单个源文件?
我已经完成了使用 egg 命令只发送二进制文件的任务。
python setup.py bdist_egg --exclude-source-files
编辑项目结构:
├── setup.py
├── src
| ├── __init__.py
| ├── file1.py
| ├── file2.py
| ├── file_to_exclude.py
感谢您的帮助!
不幸的是,distutils
和 setuptools
都没有提供排除单个模块的可能性,因此您必须解决它。
更新:
我已经描述了一个更好的解决方案 here,它模拟了包排除 setuptools
在 find_packages()
中所做的。您必须覆盖安装脚本中的 build_py
命令,它可以接受排除模式列表,与 find_packages
中的 exclude
列表相同。在您的情况下,它将是:
import fnmatch
from setuptools import find_packages, setup
from setuptools.command.build_py import build_py as build_py_orig
exclude = ['src.file_to_exclude']
class build_py(build_py_orig):
def find_package_modules(self, package, package_dir):
modules = super().find_package_modules(package, package_dir)
return [(pkg, mod, file, ) for (pkg, mod, file, ) in modules
if not any(fnmatch.fnmatchcase(pkg + '.' + mod, pat=pattern)
for pattern in exclude)]
setup(
...,
packages=find_packages(),
cmdclass={'build_py': build_py},
)
我发现这是一个比下面的解决方案更强大且符合 distutils
的解决方案。它还允许通过通配符匹配排除多个模块,例如
exclude = ['src.file*']
将排除 src
包中以 file
开头的所有模块,或
exclude = ['*.file1']
将在所有包中排除 file1.py
。
原回答
将要排除的模块放在单独的包中
您可以使用 setuptools
可以排除包(包含 __init__.py
文件的目录)这一事实,但它需要一些重构。创建一个 package_to_exclude
,将 file_to_exclude.py
放在那里并修复所有最终的导入错误:
project
├── setup.py
└── src
├── __init__.py
├── file1.py
├── file2.py
└── package_to_exclude
├── __init__.py
└── file_to_exclude.py
现在您可以在设置脚本中排除 package_to_exclude
:
from setuptools import find_packages, setup
setup(
...,
packages=find_packages(exclude=['src.package_to_exclude'])
)
排除包,通过py_modules
添加要包含的模块
如果您不能或不想将模块移动到单独的包中,您可以排除 src
包并添加 src
中除 [=35= 之外的所有模块] 在 py_modules
。示例:
import os
from setuptools import find_packages, setup
excluded_files = ['file_to_exclude.py']
included_modules = ['src.' + os.path.splitext(f)[0]
for f in os.listdir('src')
if f not in excluded_files]
setup(
...,
packages=find_packages(exclude=['src']),
py_modules=included_modules,
)
背景:我有一个负责安全的源文件。里面有魔法键和特定算法。
是否可以从 python egg 或 wheel 包中删除单个源文件?
我已经完成了使用 egg 命令只发送二进制文件的任务。
python setup.py bdist_egg --exclude-source-files
编辑项目结构:
├── setup.py
├── src
| ├── __init__.py
| ├── file1.py
| ├── file2.py
| ├── file_to_exclude.py
感谢您的帮助!
不幸的是,distutils
和 setuptools
都没有提供排除单个模块的可能性,因此您必须解决它。
更新:
我已经描述了一个更好的解决方案 here,它模拟了包排除 setuptools
在 find_packages()
中所做的。您必须覆盖安装脚本中的 build_py
命令,它可以接受排除模式列表,与 find_packages
中的 exclude
列表相同。在您的情况下,它将是:
import fnmatch
from setuptools import find_packages, setup
from setuptools.command.build_py import build_py as build_py_orig
exclude = ['src.file_to_exclude']
class build_py(build_py_orig):
def find_package_modules(self, package, package_dir):
modules = super().find_package_modules(package, package_dir)
return [(pkg, mod, file, ) for (pkg, mod, file, ) in modules
if not any(fnmatch.fnmatchcase(pkg + '.' + mod, pat=pattern)
for pattern in exclude)]
setup(
...,
packages=find_packages(),
cmdclass={'build_py': build_py},
)
我发现这是一个比下面的解决方案更强大且符合 distutils
的解决方案。它还允许通过通配符匹配排除多个模块,例如
exclude = ['src.file*']
将排除 src
包中以 file
开头的所有模块,或
exclude = ['*.file1']
将在所有包中排除 file1.py
。
原回答
将要排除的模块放在单独的包中
您可以使用 setuptools
可以排除包(包含 __init__.py
文件的目录)这一事实,但它需要一些重构。创建一个 package_to_exclude
,将 file_to_exclude.py
放在那里并修复所有最终的导入错误:
project
├── setup.py
└── src
├── __init__.py
├── file1.py
├── file2.py
└── package_to_exclude
├── __init__.py
└── file_to_exclude.py
现在您可以在设置脚本中排除 package_to_exclude
:
from setuptools import find_packages, setup
setup(
...,
packages=find_packages(exclude=['src.package_to_exclude'])
)
排除包,通过py_modules
添加要包含的模块
如果您不能或不想将模块移动到单独的包中,您可以排除 src
包并添加 src
中除 [=35= 之外的所有模块] 在 py_modules
。示例:
import os
from setuptools import find_packages, setup
excluded_files = ['file_to_exclude.py']
included_modules = ['src.' + os.path.splitext(f)[0]
for f in os.listdir('src')
if f not in excluded_files]
setup(
...,
packages=find_packages(exclude=['src']),
py_modules=included_modules,
)