Search code examples
pythondistutilssetup.py

How can I check for which command is run in setup.py?


I would like to know how to make some code in setup.py conditional on which command (e.g. install or upload) was run.

Specifically, I'd like to have:

  1. An easy way to add "hacks" such as ignoring a particular file in install, but no other commands.
  2. A recommended/canonical way to add hooks such as running tests before installing.

I have tried reading the distutils documentation, but it's pretty sparse on details – the distutils.command[.foo] modules are completely undocumented.

For the first point I can check sys.argv like mentioned in this question, but that doesn't work when multiple commands are run, like:

python setup.py sdist bdist upload

so it isn't applicable in general.


Solution

  • You can override the command instead:

    from distutils.command.install import install
    from distutils.core import setup
    
    def run_file(path):
        with open(path, 'r') as f:
            exec(f.read())
    
    class myinstall(install): # subclass distutils's install command
        def finalize_options(self): # called after option parsing
            # call base class function
            install.finalize_options(self)
            # super won't work because distutils under Python 2 uses old-style classes
            # ignore a module
            self.distribution.py_modules.remove('mymodule')
        def run(self): # called to run a command
            # run tests first
            run_file('path/to/test.py')
            # ^ remember to make sure the module is in sys.path
            # run the real commands
            install.run(self)
    
    setup(
        name='abc',
        py_modules=['mymodule'],
        cmdclass={'install': myinstall}
        # ^ override the install command
    )