使用setup.py创建不同的发行版类型

13 投票
2 回答
2664 浏览
提问于 2025-04-17 05:56

给定以下(演示用的)项目结构:

MyProject/
    README
    LICENSE
    setup.py
    myproject/
        ... # packages
    extrastuff/
        ... # some extra data

我该如何(以及在哪里)声明不同的发布类型?特别是我需要这两个选项:

  1. 一个只包含源代码的发布

  2. 一个包含源代码和所有数据文件(在extrastuff文件夹下)的发布

理想情况下,我该如何声明这两个配置,其中第二个配置依赖于第一个配置?

2 个回答

3

你可以扩展一下setup.py,让它能处理一些自定义的命令行参数。这样你就可以捕捉到这些自定义参数,并把它们去掉,这样就不会影响到setuptools了。

你可以通过sys.argv来获取命令行参数。至于怎么修改调用setuptools.setup(),我建议你先创建一个参数的字典,然后根据命令行参数来修改这个字典,最后用**dict的方式来调用setup(),像这样:

from setuptools import setup
import sys

basic = {'name': 'my program'}
extra = {'bonus': 'content'}

if '--extras' in sys.argv:
    basic.update(extra)
    sys.argv.remove('--extras')

setup(**basic)

如果你想要更全面地解析命令行参数,你还可以使用getopt模块,或者如果你只针对Python 2.7及以上版本,可以使用更新的argparse模块

编辑:我还发现distutils文档中有一部分,标题是创建一个新的Distutils命令。这可能也是一个有用的资源。

11

我之前做过类似的事情……sdist这个命令可以扩展,让它处理额外的命令行参数,并根据这些参数来操作数据文件。如果你运行 python setup.py sdist --help,它会在帮助信息中包含你自定义的命令行参数,这样就很方便了。可以使用下面的做法:

from distutils import log
from distutils.core import setup
from distutils.command.sdist import sdist

class CustomSdist(sdist):

    user_options = [
        ('packaging=', None, "Some option to indicate what should be packaged")
    ] + sdist.user_options

    def __init__(self, *args, **kwargs):
        sdist.__init__(self, *args, **kwargs)

        self.packaging = "default value for this option"

    def get_file_list(self):

        log.info("Chosen packaging option: {self.packaging}".format(self=self))

        # Change the data_files list here based on the packaging option
        self.distribution.data_files = list(
          ('folder', ['file1', 'file2'])
        )
        sdist.get_file_list(self)

if __name__ == "__main__":

    setup(
        name = "name",
        version = "version",
        author = "author",
        author_email = "author_email",
        url = "url",
        py_modules = [
            # ...
        ],
        packages = [
            # ...
        ],
#        data_files = default data files for commands other than sdist if you wish
        cmdclass={
            'sdist': CustomSdist
        }
    )

撰写回答