Call the setuptools distutils or setuptools () function directly with the command name / parameters, without parsing the command line?

I would like to call the setup () function of the Python distutils or setuptools functions in a slightly unconventional way, but I'm not sure if distutils are intended for such use.

As an example, suppose I currently have a setup.py file that looks like this (taken verbatim from distutils docs docs - using setuptools is almost identical):

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

Usually, to create only the .spec file for the RPM of this module, I can run python setup.py bdist_rpm --spec-only , which parses the command line and calls the code "bdist_rpm" to process RPM-specific files. The .spec file falls into './dist'.

How can I change the setup () call so that it runs the “bdist_rpm” command with the “only-specialization” option, WITHOUT parsing command-line options? Can I pass the name and parameters of the command as parameters to setup ()? Or can I manually build the command line and pass this as a parameter instead?

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

For the background, I convert some release shell scripts into a single Python program. One of the tasks is "setup.py" to create a .spec file for further testing before release. Running "setup.py" as an external command with its own command line parameters looks like an inconvenient method, and this complicates the rest of the program. I feel that there may be a more Pythonic way.

+7
python setuptools distutils
source share
2 answers

I have never tried this, but I had to look in distutils / core.py, where I noticed this at the beginning 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 like you can tweak the "fake" () by adding:

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

Just "fake" the command line options - for example, run the script with

 import sys sys.argv[1:] = ['bdist_rpm', '--spec-only'] from distutils.core import setup setup(name='Distutils', 

etc. etc. In the end, how distutils gets command line options: it looks in sys.argv ! Therefore, just set sys.argv exactly the way you want it, and any command line entered by an incorrectly entered user will be completely ignored.

In fact, you can check to see if the user really entered any argument that you are going to ignore - len(sys.argv) > 1 before changing sys.argv - and giving a warning or avoiding changing sys.argv, or "merge" what the user typed, etc., but this is not at all what you actually requested, so I'm going to leave it to that; -).

+1
source share

All Articles