Search code examples
pythonpython-3.xsetuptoolssetup.py

Run setup function from setuptools only if __name__ == "__main__"?


I would like to run setup() in setup.py only if the module is actually run. So I want to do something like:

from setuptools import setup

def somefunction():
    ...

if __name__ == "__main__":
    setup(...)

(I want to use some of the defined functions in the file, which are used in the setup() call, in another python script that is used during a documentation build process)

Is this possible? Disallowed? Discouraged? Why?

I could not find any documentation about this, but oddly all examples do NOT use the test for "main", so I wonder if there is anything that makes using this problematic.


Solution

  • The guards around the setup() call are not commonly seen in practice because this file is not usually imported. The setup.py is an installer script, intended to be executed directly - or executed indirectly via a build frontend such as pip or build.

    However, you may add the guards for the reason mentioned ("I want to use some of the defined functions in the file") and everything within distutils/setuptools should still work fine. It is somewhat unusual for the setup.py script to have library functions defined within, so you may ask yourself whether there is a better home for such functions, rather than writing them directly in the installer script itself.

    Is this possible?

    Yes.

    Disallowed?

    No.

    Discouraged?

    Somewhat opinion-based. Personally, I would say yes: discourage that.

    Why?

    The job of setup.py is to install your code from a source distribution, period. It is not typically the home for other random tasks such as documentation of build process. This file will not even be included in a wheel distribution, which is probably the more typical way to deploy Python code these days.

    As a final note: if and when you move toward modern Python packaging practices using pyproject.toml, with a declarative build-system, there will be no setup.py script. Then you are going to have to find a new home for such helper functions anyway.