Search code examples
pythonsetuptoolssetup.py

Create different distribution types with setup.py


Given the following (demonstration) project layout:

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

How (and where) do I declare different distribution types? Especially I need these two options:

  1. A distribution containing only the source

  2. A distribution containing the source and all data files under (extrastuff)

Ideally, how do I declare the upper two configuration whereas the second one depends on the first one?


Solution

  • I've implemented something like this before ... the sdist command can be extended to handle additional command line arguments and to manipulate the data files based on these. If you run python setup.py sdist --help, it'll include your custom command line arguments in the help, which is nice. Use the following recipe:

    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
            }
        )