Directly call distutils’ or setuptools’ setup() function with command name/options, without parsing the command line?

 

I’d like to call Python’s distutils’ or setuptools’ setup() function in a slightly unconventional way, but I’m not sure whether distutils is meant for this kind of usage.

As an example, let’s say I currently have a ‘setup.py’ file, which looks like this (lifted verbatim from the distutils docs–the setuptools usage is almost identical):

from distutils.core import setup

setup(name='Distutils',
      version='1.0',
      description='Python Distribution Utilities',
      author='Greg Ward',
      author_email='[email protected]',
      url='http://www.python.org/sigs/distutils-sig/',
      packages=['distutils', 'distutils.command'],
     )

Normally, to build just the .spec file for an RPM of this module, I could run python setup.py bdist_rpm --spec-only, which parses the command line and calls the ‘bdist_rpm’ code to handle the RPM-specific stuff. The .spec file ends up in ‘./dist’.

How can I change my setup() invocation so that it runs the ‘bdist_rpm’ command with the ‘–spec-only’ option, WITHOUT parsing command-line parameters? Can I pass the command name and options as parameters to setup()? Or can I manually construct a command line, and pass that as a parameter, instead?

NOTE: I already know that I could call the script in a separate process, with an actual command line, using os.system() or the subprocess module or something similar. I’m trying to avoid using any kind of external command invocations. I’m looking specifically for a solution that runs setup() in the current interpreter.

For background, I’m converting some release-management shell scripts into a single Python program. One of the tasks is running ‘setup.py’ to generate a .spec file for further pre-release testing. Running ‘setup.py’ as an external command, with its own command line options, seems like an awkward method, and it complicates the rest of the program. I feel like there may be a more Pythonic way.

Never tried this, but I did happen to look in distutils/core.py, where I notice this near the start of setup():

if 'script_name' not in attrs:
    attrs['script_name'] = os.path.basename(sys.argv[0])
if 'script_args' not in attrs:
    attrs['script_args'] = sys.argv[1:]

So, it looks as if you can “fake-out” setup() by adding:

setup(
    ...
    script_name = 'setup.py',
    script_args = ['bdist_rpm', '--spec-only']
)

Attribution
Source : Link , Question Author : Ryan B. Lynch , Author : ig0774

Leave a Comment