我也在Distutils-SIG中问过这个问题。那里提到setup_requires
了
https://stackoverflow.com/a/12061891/6364,这给了我需要的提示:Distribution
在调用之前创建一个单独的对象setup
来定义setup_requires
条目。
果酱setup.py
现在看起来像:
from setuptools import setup, dist
dist.Distribution(dict(setup_requires='Bread'))
from bread.setup_topping import *
setup(
name='Jam',
version='0.2',
long_description=open('README.md').read(),
**topping_setup_options
)
# Remove *.egg left by bootstrapping Bread
cleanup_bread_bootstrap()
编辑:需要更好地解释 Jam 中发生的事情setup.py
:
- 最初用于在当前目录
Distribution(setup_requires='Bread')
中easy_install
安装 Bread 及其依赖项。
- 调用
setup()
触发bdist_egg
以下,它使用 Bread 来构建 Jam's output
。面包在当前目录中找到。
setup()
稍后将 Jam、Bread 和所有依赖项安装在正确的位置。
- 调用
cleanup_bread_bootstrap()
删除由初始Distribution
.
bread/setup_topping.py
看起来像:
from setuptools.command.bdist_egg import bdist_egg as _bdist_egg
import os, fnmatch, glob, shutil
def recursive_data_files(treeroot, pattern):
results = []
for base, dirs, files in os.walk(treeroot):
goodfiles = fnmatch.filter(files, pattern)
if goodfiles:
results.append((base, [os.path.join(base, f) for f in goodfiles]))
return results
def make_data_files(output='output'):
return (
[('', ['bread.yaml'])]
+ recursive_data_files(output, '*')
)
class bdist_egg(_bdist_egg):
def initialize_options(self):
bake_bread() # build files to './output'
self.distribution.data_files = make_data_files()
_bdist_egg.initialize_options(self)
topping_setup_options = dict(
cmdclass={
'bdist_egg': bdist_egg,
},
install_requires=[
'Bread',
],
zip_safe=False,
)
def cleanup_bread_bootstrap(root='.'):
for f in glob.glob(os.path.join(os.path.abspath(root), '*.egg')):
if os.path.isdir(f):
shutil.rmtree(f) # Egg directory
else:
os.remove(f) # Zipped Egg