简体   繁体   中英

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.

The guards around the setup() call are not commonly seen in practice because this file is not usually imported . It is well-known to be an installer script , intended to be executed directly.

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.

Shouldn't be a problem. I would recommend always using the if __name__ == "__main__": condition even if there the module is never imported. What I would not recommend on the other hand tough, is to share code between the setup script and the code of the project itself.

You can go a different route, and add all your functions of interest to a separate module that's normally importable by the rest of your program. I wouldn't recommend putting package functions into setup.py because the setup file is meant to live outside your package. You may need a utility function to import the module by path in setup.py . I generally use something that looks like this:

def import_file(name, location):
    """
    Imports the specified python file as a module, without explicitly
    registering it to `sys.modules`.
    """
    if sys.version_info[0] == 2:
        # Python 2.7-
        from imp import load_source
        mod = load_source(name, location)
    elif sys.version_info < (3, 5, 0):
        # Python 3.4-
        from importlib.machinery import SourceFileLoader
        mod = SourceFileLoader(name, location).load_module()
    else:
        # Python 3.5+
        from importlib.util import spec_from_file_location, module_from_spec
        spec = spec_from_file_location(name, location)
        mod = module_from_spec(spec)
        spec.loader.exec_module(mod)
    return mod

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM