Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom distutils commands

I have a library called "example" that I'm installing into my global site-packages directory. However, I'd like to be able to install two versions, one for production and one for testing (I have a web application and other things that are versioned this way).

Is there a way to specify, say "python setup.py stage" that will not only install a different egg into site-packages, but also rename the module from "example" to "example_stage" or something similar?

If distutils cannot do this, is there any other tool that can?

like image 353
dave paola Avatar asked Nov 10 '09 20:11

dave paola


People also ask

What does Distutils mean in Python?

The distutils package provides support for building and installing additional modules into a Python installation. The new modules may be either 100%-pure Python, or may be extension modules written in C, or may be collections of Python packages which include modules coded in both Python and C.

What is Cmdclass?

cmdclass: A mapping of command names to Command subclasses (a dictionary)

What is setup py in Python?

The setup.py file is a Python file which indicates that the installation module/package is most likely packed and distributed using Distutils, the Python Module distribution standard.


1 Answers

This can easily be done with distutils by subclassing distutils.core.Command inside of setup.py.

For example:

from distutils.core import setup, Command import os, sys  class CleanCommand(Command):     description = "custom clean command that forcefully removes dist/build directories"     user_options = []     def initialize_options(self):         self.cwd = None     def finalize_options(self):         self.cwd = os.getcwd()     def run(self):         assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd         os.system('rm -rf ./build ./dist')   

To enable the command you must reference it in setup():

setup(      # stuff omitted for conciseness.      cmdclass={         'clean': CleanCommand } 

Note that you can override built-in commands this way too, such as what I did with 'clean'. (I didn't like how the built-in version left behind the 'dist' and 'build' directories.)

% python setup.py --help-commands | grep clean   clean            custom clean command that forcefully removes dist/build dirs. 

There are a number of conventions that are used:

  • You specify any command-line arguments with user_options.
  • You declare any variables you would use with the initialize_options() method, which is called after initialization to setup your custom namespace for the subclass.
  • The finalize_options() method is called right before run().
  • The guts of the command itself will occur in run() so be sure to do any other prep work before that.

The best example to use is just to look at the source code for one of the default commands found at PYTHON_DIR/distutils/command such as install.py or build.py.

like image 149
jathanism Avatar answered Oct 03 '22 22:10

jathanism