]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distutils/dist.py
   3 Provides the Distribution class, which represents the module distribution 
   4 being built/installed/distributed. 
   7 # This module should be kept compatible with Python 1.5.2. 
  11 import sys
, os
, string
, re
 
  20 from distutils
.errors 
import * 
  21 from distutils
.fancy_getopt 
import FancyGetopt
, translate_longopt
 
  22 from distutils
.util 
import check_environ
, strtobool
, rfc822_escape
 
  23 from distutils 
import log
 
  24 from distutils
.debug 
import DEBUG
 
  26 # Regex to define acceptable Distutils command names.  This is not *quite* 
  27 # the same as a Python NAME -- I don't allow leading underscores.  The fact 
  28 # that they're very similar is no coincidence; the default naming scheme is 
  29 # to look for a Python module named after the command. 
  30 command_re 
= re
.compile (r
'^[a-zA-Z]([a-zA-Z0-9_]*)$') 
  34     """The core of the Distutils.  Most of the work hiding behind 'setup' 
  35     is really done within a Distribution instance, which farms the work out 
  36     to the Distutils commands specified on the command line. 
  38     Setup scripts will almost never instantiate Distribution directly, 
  39     unless the 'setup()' function is totally inadequate to their needs. 
  40     However, it is conceivable that a setup script might wish to subclass 
  41     Distribution for some specialized purpose, and then pass the subclass 
  42     to 'setup()' as the 'distclass' keyword argument.  If so, it is 
  43     necessary to respect the expectations that 'setup' has of Distribution. 
  44     See the code for 'setup()', in core.py, for details. 
  48     # 'global_options' describes the command-line options that may be 
  49     # supplied to the setup script prior to any actual commands. 
  50     # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of 
  51     # these global options.  This list should be kept to a bare minimum, 
  52     # since every global option is also valid as a command option -- and we 
  53     # don't want to pollute the commands with too many options that they 
  54     # have minimal control over. 
  55     # The fourth entry for verbose means that it can be repeated. 
  56     global_options 
= [('verbose', 'v', "run verbosely (default)", 1), 
  57                       ('quiet', 'q', "run quietly (turns verbosity off)"), 
  58                       ('dry-run', 'n', "don't actually do anything"), 
  59                       ('help', 'h', "show detailed help message"), 
  62     # options that are not propagated to the commands 
  64         ('help-commands', None, 
  65          "list all available commands"), 
  67          "print package name"), 
  69          "print package version"), 
  71          "print <package name>-<version>"), 
  73          "print the author's name"), 
  74         ('author-email', None, 
  75          "print the author's email address"), 
  77          "print the maintainer's name"), 
  78         ('maintainer-email', None, 
  79          "print the maintainer's email address"), 
  81          "print the maintainer's name if known, else the author's"), 
  82         ('contact-email', None, 
  83          "print the maintainer's email address if known, else the author's"), 
  85          "print the URL for this package"), 
  87          "print the license of the package"), 
  89          "alias for --license"), 
  91          "print the package description"), 
  92         ('long-description', None, 
  93          "print the long package description"), 
  95          "print the list of platforms"), 
  97          "print the list of classifiers"), 
  99          "print the list of keywords"), 
 101     display_option_names 
= map(lambda x
: translate_longopt(x
[0]), 
 104     # negative options are options that exclude other options 
 105     negative_opt 
= {'quiet': 'verbose'}
 
 108     # -- Creation/initialization methods ------------------------------- 
 110     def __init__ (self
, attrs
=None): 
 111         """Construct a new Distribution instance: initialize all the 
 112         attributes of a Distribution, and then use 'attrs' (a dictionary 
 113         mapping attribute names to values) to assign some of those 
 114         attributes their "real" values.  (Any attributes not mentioned in 
 115         'attrs' will be assigned to some null value: 0, None, an empty list 
 116         or dictionary, etc.)  Most importantly, initialize the 
 117         'command_obj' attribute to the empty dictionary; this will be 
 118         filled in with real command objects by 'parse_command_line()'. 
 121         # Default values for our command-line options 
 125         for attr 
in self
.display_option_names
: 
 126             setattr(self
, attr
, 0) 
 128         # Store the distribution meta-data (name, version, author, and so 
 129         # forth) in a separate object -- we're getting to have enough 
 130         # information here (and enough command-line options) that it's 
 131         # worth it.  Also delegate 'get_XXX()' methods to the 'metadata' 
 132         # object in a sneaky and underhanded (but efficient!) way. 
 133         self
.metadata 
= DistributionMetadata() 
 134         for basename 
in self
.metadata
._METHOD
_BASENAMES
: 
 135             method_name 
= "get_" + basename
 
 136             setattr(self
, method_name
, getattr(self
.metadata
, method_name
)) 
 138         # 'cmdclass' maps command names to class objects, so we 
 139         # can 1) quickly figure out which class to instantiate when 
 140         # we need to create a new command object, and 2) have a way 
 141         # for the setup script to override command classes 
 144         # 'script_name' and 'script_args' are usually set to sys.argv[0] 
 145         # and sys.argv[1:], but they can be overridden when the caller is 
 146         # not necessarily a setup script run from the command-line. 
 147         self
.script_name 
= None 
 148         self
.script_args 
= None 
 150         # 'command_options' is where we store command options between 
 151         # parsing them (from config files, the command-line, etc.) and when 
 152         # they are actually needed -- ie. when the command in question is 
 153         # instantiated.  It is a dictionary of dictionaries of 2-tuples: 
 154         #   command_options = { command_name : { option : (source, value) } } 
 155         self
.command_options 
= {} 
 157         # These options are really the business of various commands, rather 
 158         # than of the Distribution itself.  We provide aliases for them in 
 159         # Distribution as a convenience to the developer. 
 161         self
.package_dir 
= None 
 162         self
.py_modules 
= None 
 163         self
.libraries 
= None 
 165         self
.ext_modules 
= None 
 166         self
.ext_package 
= None 
 167         self
.include_dirs 
= None 
 168         self
.extra_path 
= None 
 170         self
.data_files 
= None 
 172         # And now initialize bookkeeping stuff that can't be supplied by 
 173         # the caller at all.  'command_obj' maps command names to 
 174         # Command instances -- that's how we enforce that every command 
 175         # class is a singleton. 
 176         self
.command_obj 
= {} 
 178         # 'have_run' maps command names to boolean values; it keeps track 
 179         # of whether we have actually run a particular command, to make it 
 180         # cheap to "run" a command whenever we think we might need to -- if 
 181         # it's already been done, no need for expensive filesystem 
 182         # operations, we just check the 'have_run' dictionary and carry on. 
 183         # It's only safe to query 'have_run' for a command class that has 
 184         # been instantiated -- a false value will be inserted when the 
 185         # command object is created, and replaced with a true value when 
 186         # the command is successfully run.  Thus it's probably best to use 
 187         # '.get()' rather than a straight lookup. 
 190         # Now we'll use the attrs dictionary (ultimately, keyword args from 
 191         # the setup script) to possibly override any or all of these 
 192         # distribution options. 
 196             # Pull out the set of command options and work on them 
 197             # specifically.  Note that this order guarantees that aliased 
 198             # command options will override any supplied redundantly 
 199             # through the general options dictionary. 
 200             options 
= attrs
.get('options') 
 203                 for (command
, cmd_options
) in options
.items(): 
 204                     opt_dict 
= self
.get_option_dict(command
) 
 205                     for (opt
, val
) in cmd_options
.items(): 
 206                         opt_dict
[opt
] = ("setup script", val
) 
 208             if attrs
.has_key('licence'): 
 209                 attrs
['license'] = attrs
['licence'] 
 211                 msg 
= "'licence' distribution option is deprecated; use 'license'" 
 212                 if warnings 
is not None: 
 215                     sys
.stderr
.write(msg 
+ "\n") 
 217             # Now work on the rest of the attributes.  Any attribute that's 
 218             # not already defined is invalid! 
 219             for (key
,val
) in attrs
.items(): 
 220                 if hasattr(self
.metadata
, key
): 
 221                     setattr(self
.metadata
, key
, val
) 
 222                 elif hasattr(self
, key
): 
 223                     setattr(self
, key
, val
) 
 225                     msg 
= "Unknown distribution option: %s" % repr(key
) 
 226                     if warnings 
is not None: 
 229                         sys
.stderr
.write(msg 
+ "\n") 
 231         self
.finalize_options() 
 236     def get_option_dict (self
, command
): 
 237         """Get the option dictionary for a given command.  If that 
 238         command's option dictionary hasn't been created yet, then create it 
 239         and return the new dictionary; otherwise, return the existing 
 243         dict = self
.command_options
.get(command
) 
 245             dict = self
.command_options
[command
] = {} 
 249     def dump_option_dicts (self
, header
=None, commands
=None, indent
=""): 
 250         from pprint 
import pformat
 
 252         if commands 
is None:             # dump all command option dicts 
 253             commands 
= self
.command_options
.keys() 
 256         if header 
is not None: 
 257             print indent 
+ header
 
 258             indent 
= indent 
+ "  " 
 261             print indent 
+ "no commands known yet" 
 264         for cmd_name 
in commands
: 
 265             opt_dict 
= self
.command_options
.get(cmd_name
) 
 267                 print indent 
+ "no option dict for '%s' command" % cmd_name
 
 269                 print indent 
+ "option dict for '%s' command:" % cmd_name
 
 270                 out 
= pformat(opt_dict
) 
 271                 for line 
in string
.split(out
, "\n"): 
 272                     print indent 
+ "  " + line
 
 274     # dump_option_dicts () 
 278     # -- Config file finding/parsing methods --------------------------- 
 280     def find_config_files (self
): 
 281         """Find as many configuration files as should be processed for this 
 282         platform, and return a list of filenames in the order in which they 
 283         should be parsed.  The filenames returned are guaranteed to exist 
 284         (modulo nasty race conditions). 
 286         There are three possible config files: distutils.cfg in the 
 287         Distutils installation directory (ie. where the top-level 
 288         Distutils __inst__.py file lives), a file in the user's home 
 289         directory named .pydistutils.cfg on Unix and pydistutils.cfg 
 290         on Windows/Mac, and setup.cfg in the current directory. 
 295         # Where to look for the system-wide Distutils config file 
 296         sys_dir 
= os
.path
.dirname(sys
.modules
['distutils'].__file
__) 
 298         # Look for the system config file 
 299         sys_file 
= os
.path
.join(sys_dir
, "distutils.cfg") 
 300         if os
.path
.isfile(sys_file
): 
 301             files
.append(sys_file
) 
 303         # What to call the per-user config file 
 304         if os
.name 
== 'posix': 
 305             user_filename 
= ".pydistutils.cfg" 
 307             user_filename 
= "pydistutils.cfg" 
 309         # And look for the user config file 
 310         if os
.environ
.has_key('HOME'): 
 311             user_file 
= os
.path
.join(os
.environ
.get('HOME'), user_filename
) 
 312             if os
.path
.isfile(user_file
): 
 313                 files
.append(user_file
) 
 315         # All platforms support local setup.cfg 
 316         local_file 
= "setup.cfg" 
 317         if os
.path
.isfile(local_file
): 
 318             files
.append(local_file
) 
 322     # find_config_files () 
 325     def parse_config_files (self
, filenames
=None): 
 327         from ConfigParser 
import ConfigParser
 
 329         if filenames 
is None: 
 330             filenames 
= self
.find_config_files() 
 332         if DEBUG
: print "Distribution.parse_config_files():" 
 334         parser 
= ConfigParser() 
 335         for filename 
in filenames
: 
 336             if DEBUG
: print "  reading", filename
 
 337             parser
.read(filename
) 
 338             for section 
in parser
.sections(): 
 339                 options 
= parser
.options(section
) 
 340                 opt_dict 
= self
.get_option_dict(section
) 
 343                     if opt 
!= '__name__': 
 344                         val 
= parser
.get(section
,opt
) 
 345                         opt 
= string
.replace(opt
, '-', '_') 
 346                         opt_dict
[opt
] = (filename
, val
) 
 348             # Make the ConfigParser forget everything (so we retain 
 349             # the original filenames that options come from) -- gag, 
 350             # retch, puke -- another good reason for a distutils- 
 351             # specific config parser (sigh...) 
 354         # If there was a "global" section in the config file, use it 
 355         # to set Distribution options. 
 357         if self
.command_options
.has_key('global'): 
 358             for (opt
, (src
, val
)) in self
.command_options
['global'].items(): 
 359                 alias 
= self
.negative_opt
.get(opt
) 
 362                         setattr(self
, alias
, not strtobool(val
)) 
 363                     elif opt 
in ('verbose', 'dry_run'): # ugh! 
 364                         setattr(self
, opt
, strtobool(val
)) 
 365                 except ValueError, msg
: 
 366                     raise DistutilsOptionError
, msg
 
 368     # parse_config_files () 
 371     # -- Command-line parsing methods ---------------------------------- 
 373     def parse_command_line (self
): 
 374         """Parse the setup script's command line, taken from the 
 375         'script_args' instance attribute (which defaults to 'sys.argv[1:]' 
 376         -- see 'setup()' in core.py).  This list is first processed for 
 377         "global options" -- options that set attributes of the Distribution 
 378         instance.  Then, it is alternately scanned for Distutils commands 
 379         and options for that command.  Each new command terminates the 
 380         options for the previous command.  The allowed options for a 
 381         command are determined by the 'user_options' attribute of the 
 382         command class -- thus, we have to be able to load command classes 
 383         in order to parse the command line.  Any error in that 'options' 
 384         attribute raises DistutilsGetoptError; any error on the 
 385         command-line raises DistutilsArgError.  If no Distutils commands 
 386         were found on the command line, raises DistutilsArgError.  Return 
 387         true if command-line was successfully parsed and we should carry 
 388         on with executing commands; false if no errors but we shouldn't 
 389         execute commands (currently, this only happens if user asks for 
 393         # We now have enough information to show the Macintosh dialog 
 394         # that allows the user to interactively specify the "command line". 
 396         if sys
.platform 
== 'mac': 
 398             cmdlist 
= self
.get_command_list() 
 399             self
.script_args 
= EasyDialogs
.GetArgv( 
 400                 self
.global_options 
+ self
.display_options
, cmdlist
) 
 402         # We have to parse the command line a bit at a time -- global 
 403         # options, then the first command, then its options, and so on -- 
 404         # because each command will be handled by a different class, and 
 405         # the options that are valid for a particular class aren't known 
 406         # until we have loaded the command class, which doesn't happen 
 407         # until we know what the command is. 
 410         parser 
= FancyGetopt(self
.global_options 
+ self
.display_options
) 
 411         parser
.set_negative_aliases(self
.negative_opt
) 
 412         parser
.set_aliases({'licence': 'license'}
) 
 413         args 
= parser
.getopt(args
=self
.script_args
, object=self
) 
 414         option_order 
= parser
.get_option_order() 
 415         log
.set_verbosity(self
.verbose
) 
 417         # for display options we return immediately 
 418         if self
.handle_display_options(option_order
): 
 422             args 
= self
._parse
_command
_opts
(parser
, args
) 
 423             if args 
is None:            # user asked for help (and got it) 
 426         # Handle the cases of --help as a "global" option, ie. 
 427         # "setup.py --help" and "setup.py --help command ...".  For the 
 428         # former, we show global options (--verbose, --dry-run, etc.) 
 429         # and display-only options (--name, --version, etc.); for the 
 430         # latter, we omit the display-only options and show help for 
 431         # each command listed on the command line. 
 433             self
._show
_help
(parser
, 
 434                             display_options
=len(self
.commands
) == 0, 
 435                             commands
=self
.commands
) 
 438         # Oops, no commands found -- an end-user error 
 439         if not self
.commands
: 
 440             raise DistutilsArgError
, "no commands supplied" 
 442         # All is well: return true 
 445     # parse_command_line() 
 447     def _parse_command_opts (self
, parser
, args
): 
 448         """Parse the command-line options for a single command. 
 449         'parser' must be a FancyGetopt instance; 'args' must be the list 
 450         of arguments, starting with the current command (whose options 
 451         we are about to parse).  Returns a new version of 'args' with 
 452         the next command at the front of the list; will be the empty 
 453         list if there are no more commands on the command line.  Returns 
 454         None if the user asked for help on this command. 
 456         # late import because of mutual dependence between these modules 
 457         from distutils
.cmd 
import Command
 
 459         # Pull the current command from the head of the command line 
 461         if not command_re
.match(command
): 
 462             raise SystemExit, "invalid command name '%s'" % command
 
 463         self
.commands
.append(command
) 
 465         # Dig up the command class that implements this command, so we 
 466         # 1) know that it's a valid command, and 2) know which options 
 469             cmd_class 
= self
.get_command_class(command
) 
 470         except DistutilsModuleError
, msg
: 
 471             raise DistutilsArgError
, msg
 
 473         # Require that the command class be derived from Command -- want 
 474         # to be sure that the basic "command" interface is implemented. 
 475         if not issubclass(cmd_class
, Command
): 
 476             raise DistutilsClassError
, \
 
 477                   "command class %s must subclass Command" % cmd_class
 
 479         # Also make sure that the command object provides a list of its 
 481         if not (hasattr(cmd_class
, 'user_options') and 
 482                 type(cmd_class
.user_options
) is ListType
): 
 483             raise DistutilsClassError
, \
 
 484                   ("command class %s must provide " + 
 485                    "'user_options' attribute (a list of tuples)") % \
 
 488         # If the command class has a list of negative alias options, 
 489         # merge it in with the global negative aliases. 
 490         negative_opt 
= self
.negative_opt
 
 491         if hasattr(cmd_class
, 'negative_opt'): 
 492             negative_opt 
= copy(negative_opt
) 
 493             negative_opt
.update(cmd_class
.negative_opt
) 
 495         # Check for help_options in command class.  They have a different 
 496         # format (tuple of four) so we need to preprocess them here. 
 497         if (hasattr(cmd_class
, 'help_options') and 
 498             type(cmd_class
.help_options
) is ListType
): 
 499             help_options 
= fix_help_options(cmd_class
.help_options
) 
 504         # All commands support the global options too, just by adding 
 505         # in 'global_options'. 
 506         parser
.set_option_table(self
.global_options 
+ 
 507                                 cmd_class
.user_options 
+ 
 509         parser
.set_negative_aliases(negative_opt
) 
 510         (args
, opts
) = parser
.getopt(args
[1:]) 
 511         if hasattr(opts
, 'help') and opts
.help: 
 512             self
._show
_help
(parser
, display_options
=0, commands
=[cmd_class
]) 
 515         if (hasattr(cmd_class
, 'help_options') and 
 516             type(cmd_class
.help_options
) is ListType
): 
 518             for (help_option
, short
, desc
, func
) in cmd_class
.help_options
: 
 519                 if hasattr(opts
, parser
.get_attr_name(help_option
)): 
 521                     #print "showing help for option %s of command %s" % \ 
 522                     #      (help_option[0],cmd_class) 
 527                         raise DistutilsClassError( 
 528                             "invalid help function %s for help option '%s': " 
 529                             "must be a callable object (function, etc.)" 
 530                             % (`func`
, help_option
)) 
 532             if help_option_found
: 
 535         # Put the options from the command-line into their official 
 536         # holding pen, the 'command_options' dictionary. 
 537         opt_dict 
= self
.get_option_dict(command
) 
 538         for (name
, value
) in vars(opts
).items(): 
 539             opt_dict
[name
] = ("command line", value
) 
 543     # _parse_command_opts () 
 546     def finalize_options (self
): 
 547         """Set final values for all the options on the Distribution 
 548         instance, analogous to the .finalize_options() method of Command 
 552         keywords 
= self
.metadata
.keywords
 
 553         if keywords 
is not None: 
 554             if type(keywords
) is StringType
: 
 555                 keywordlist 
= string
.split(keywords
, ',') 
 556                 self
.metadata
.keywords 
= map(string
.strip
, keywordlist
) 
 558         platforms 
= self
.metadata
.platforms
 
 559         if platforms 
is not None: 
 560             if type(platforms
) is StringType
: 
 561                 platformlist 
= string
.split(platforms
, ',') 
 562                 self
.metadata
.platforms 
= map(string
.strip
, platformlist
) 
 564     def _show_help (self
, 
 569         """Show help for the setup script command-line in the form of 
 570         several lists of command-line options.  'parser' should be a 
 571         FancyGetopt instance; do not expect it to be returned in the 
 572         same state, as its option table will be reset to make it 
 573         generate the correct help text. 
 575         If 'global_options' is true, lists the global options: 
 576         --verbose, --dry-run, etc.  If 'display_options' is true, lists 
 577         the "display-only" options: --name, --version, etc.  Finally, 
 578         lists per-command help for every command name or command class 
 581         # late import because of mutual dependence between these modules 
 582         from distutils
.core 
import gen_usage
 
 583         from distutils
.cmd 
import Command
 
 586             parser
.set_option_table(self
.global_options
) 
 587             parser
.print_help("Global options:") 
 591             parser
.set_option_table(self
.display_options
) 
 593                 "Information display options (just display " + 
 594                 "information, ignore any commands)") 
 597         for command 
in self
.commands
: 
 598             if type(command
) is ClassType 
and issubclass(command
, Command
): 
 601                 klass 
= self
.get_command_class(command
) 
 602             if (hasattr(klass
, 'help_options') and 
 603                 type(klass
.help_options
) is ListType
): 
 604                 parser
.set_option_table(klass
.user_options 
+ 
 605                                         fix_help_options(klass
.help_options
)) 
 607                 parser
.set_option_table(klass
.user_options
) 
 608             parser
.print_help("Options for '%s' command:" % klass
.__name
__) 
 611         print gen_usage(self
.script_name
) 
 617     def handle_display_options (self
, option_order
): 
 618         """If there were any non-global "display-only" options 
 619         (--help-commands or the metadata display options) on the command 
 620         line, display the requested info and return true; else return 
 623         from distutils
.core 
import gen_usage
 
 625         # User just wants a list of commands -- we'll print it out and stop 
 626         # processing now (ie. if they ran "setup --help-commands foo bar", 
 627         # we ignore "foo bar"). 
 628         if self
.help_commands
: 
 629             self
.print_commands() 
 631             print gen_usage(self
.script_name
) 
 634         # If user supplied any of the "display metadata" options, then 
 635         # display that metadata in the order in which the user supplied the 
 637         any_display_options 
= 0 
 638         is_display_option 
= {} 
 639         for option 
in self
.display_options
: 
 640             is_display_option
[option
[0]] = 1 
 642         for (opt
, val
) in option_order
: 
 643             if val 
and is_display_option
.get(opt
): 
 644                 opt 
= translate_longopt(opt
) 
 645                 value 
= getattr(self
.metadata
, "get_"+opt
)() 
 646                 if opt 
in ['keywords', 'platforms']: 
 647                     print string
.join(value
, ',') 
 648                 elif opt 
== 'classifiers': 
 649                     print string
.join(value
, '\n') 
 652                 any_display_options 
= 1 
 654         return any_display_options
 
 656     # handle_display_options() 
 658     def print_command_list (self
, commands
, header
, max_length
): 
 659         """Print a subset of the list of all commands -- used by 
 666             klass 
= self
.cmdclass
.get(cmd
) 
 668                 klass 
= self
.get_command_class(cmd
) 
 670                 description 
= klass
.description
 
 671             except AttributeError: 
 672                 description 
= "(no description available)" 
 674             print "  %-*s  %s" % (max_length
, cmd
, description
) 
 676     # print_command_list () 
 679     def print_commands (self
): 
 680         """Print out a help message listing all available commands with a 
 681         description of each.  The list is divided into "standard commands" 
 682         (listed in distutils.command.__all__) and "extra commands" 
 683         (mentioned in self.cmdclass, but not a standard command).  The 
 684         descriptions come from the command class attribute 
 688         import distutils
.command
 
 689         std_commands 
= distutils
.command
.__all
__ 
 691         for cmd 
in std_commands
: 
 695         for cmd 
in self
.cmdclass
.keys(): 
 696             if not is_std
.get(cmd
): 
 697                 extra_commands
.append(cmd
) 
 700         for cmd 
in (std_commands 
+ extra_commands
): 
 701             if len(cmd
) > max_length
: 
 702                 max_length 
= len(cmd
) 
 704         self
.print_command_list(std_commands
, 
 709             self
.print_command_list(extra_commands
, 
 715     def get_command_list (self
): 
 716         """Get a list of (command, description) tuples. 
 717         The list is divided into "standard commands" (listed in 
 718         distutils.command.__all__) and "extra commands" (mentioned in 
 719         self.cmdclass, but not a standard command).  The descriptions come 
 720         from the command class attribute 'description'. 
 722         # Currently this is only used on Mac OS, for the Mac-only GUI 
 723         # Distutils interface (by Jack Jansen) 
 725         import distutils
.command
 
 726         std_commands 
= distutils
.command
.__all
__ 
 728         for cmd 
in std_commands
: 
 732         for cmd 
in self
.cmdclass
.keys(): 
 733             if not is_std
.get(cmd
): 
 734                 extra_commands
.append(cmd
) 
 737         for cmd 
in (std_commands 
+ extra_commands
): 
 738             klass 
= self
.cmdclass
.get(cmd
) 
 740                 klass 
= self
.get_command_class(cmd
) 
 742                 description 
= klass
.description
 
 743             except AttributeError: 
 744                 description 
= "(no description available)" 
 745             rv
.append((cmd
, description
)) 
 748     # -- Command class/object methods ---------------------------------- 
 750     def get_command_class (self
, command
): 
 751         """Return the class that implements the Distutils command named by 
 752         'command'.  First we check the 'cmdclass' dictionary; if the 
 753         command is mentioned there, we fetch the class object from the 
 754         dictionary and return it.  Otherwise we load the command module 
 755         ("distutils.command." + command) and fetch the command class from 
 756         the module.  The loaded class is also stored in 'cmdclass' 
 757         to speed future calls to 'get_command_class()'. 
 759         Raises DistutilsModuleError if the expected module could not be 
 760         found, or if that module does not define the expected class. 
 762         klass 
= self
.cmdclass
.get(command
) 
 766         module_name 
= 'distutils.command.' + command
 
 770             __import__ (module_name
) 
 771             module 
= sys
.modules
[module_name
] 
 773             raise DistutilsModuleError
, \
 
 774                   "invalid command '%s' (no module named '%s')" % \
 
 775                   (command
, module_name
) 
 778             klass 
= getattr(module
, klass_name
) 
 779         except AttributeError: 
 780             raise DistutilsModuleError
, \
 
 781                   "invalid command '%s' (no class '%s' in module '%s')" \
 
 782                   % (command
, klass_name
, module_name
) 
 784         self
.cmdclass
[command
] = klass
 
 787     # get_command_class () 
 789     def get_command_obj (self
, command
, create
=1): 
 790         """Return the command object for 'command'.  Normally this object 
 791         is cached on a previous call to 'get_command_obj()'; if no command 
 792         object for 'command' is in the cache, then we either create and 
 793         return it (if 'create' is true) or return None. 
 795         cmd_obj 
= self
.command_obj
.get(command
) 
 796         if not cmd_obj 
and create
: 
 798                 print "Distribution.get_command_obj(): " \
 
 799                       "creating '%s' command object" % command
 
 801             klass 
= self
.get_command_class(command
) 
 802             cmd_obj 
= self
.command_obj
[command
] = klass(self
) 
 803             self
.have_run
[command
] = 0 
 805             # Set any options that were supplied in config files 
 806             # or on the command line.  (NB. support for error 
 807             # reporting is lame here: any errors aren't reported 
 808             # until 'finalize_options()' is called, which means 
 809             # we won't report the source of the error.) 
 810             options 
= self
.command_options
.get(command
) 
 812                 self
._set
_command
_options
(cmd_obj
, options
) 
 816     def _set_command_options (self
, command_obj
, option_dict
=None): 
 817         """Set the options for 'command_obj' from 'option_dict'.  Basically 
 818         this means copying elements of a dictionary ('option_dict') to 
 819         attributes of an instance ('command'). 
 821         'command_obj' must be a Command instance.  If 'option_dict' is not 
 822         supplied, uses the standard option dictionary for this command 
 823         (from 'self.command_options'). 
 825         command_name 
= command_obj
.get_command_name() 
 826         if option_dict 
is None: 
 827             option_dict 
= self
.get_option_dict(command_name
) 
 829         if DEBUG
: print "  setting options for '%s' command:" % command_name
 
 830         for (option
, (source
, value
)) in option_dict
.items(): 
 831             if DEBUG
: print "    %s = %s (from %s)" % (option
, value
, source
) 
 833                 bool_opts 
= map(translate_longopt
, command_obj
.boolean_options
) 
 834             except AttributeError: 
 837                 neg_opt 
= command_obj
.negative_opt
 
 838             except AttributeError: 
 842                 is_string 
= type(value
) is StringType
 
 843                 if neg_opt
.has_key(option
) and is_string
: 
 844                     setattr(command_obj
, neg_opt
[option
], not strtobool(value
)) 
 845                 elif option 
in bool_opts 
and is_string
: 
 846                     setattr(command_obj
, option
, strtobool(value
)) 
 847                 elif hasattr(command_obj
, option
): 
 848                     setattr(command_obj
, option
, value
) 
 850                     raise DistutilsOptionError
, \
 
 851                           ("error in %s: command '%s' has no such option '%s'" 
 852                            % (source
, command_name
, option
)) 
 853             except ValueError, msg
: 
 854                 raise DistutilsOptionError
, msg
 
 856     def reinitialize_command (self
, command
, reinit_subcommands
=0): 
 857         """Reinitializes a command to the state it was in when first 
 858         returned by 'get_command_obj()': ie., initialized but not yet 
 859         finalized.  This provides the opportunity to sneak option 
 860         values in programmatically, overriding or supplementing 
 861         user-supplied values from the config files and command line. 
 862         You'll have to re-finalize the command object (by calling 
 863         'finalize_options()' or 'ensure_finalized()') before using it for 
 866         'command' should be a command name (string) or command object.  If 
 867         'reinit_subcommands' is true, also reinitializes the command's 
 868         sub-commands, as declared by the 'sub_commands' class attribute (if 
 869         it has one).  See the "install" command for an example.  Only 
 870         reinitializes the sub-commands that actually matter, ie. those 
 871         whose test predicates return true. 
 873         Returns the reinitialized command object. 
 875         from distutils
.cmd 
import Command
 
 876         if not isinstance(command
, Command
): 
 877             command_name 
= command
 
 878             command 
= self
.get_command_obj(command_name
) 
 880             command_name 
= command
.get_command_name() 
 882         if not command
.finalized
: 
 884         command
.initialize_options() 
 885         command
.finalized 
= 0 
 886         self
.have_run
[command_name
] = 0 
 887         self
._set
_command
_options
(command
) 
 889         if reinit_subcommands
: 
 890             for sub 
in command
.get_sub_commands(): 
 891                 self
.reinitialize_command(sub
, reinit_subcommands
) 
 896     # -- Methods that operate on the Distribution ---------------------- 
 898     def announce (self
, msg
, level
=1): 
 901     def run_commands (self
): 
 902         """Run each command that was seen on the setup script command line. 
 903         Uses the list of commands found and cache of command objects 
 904         created by 'get_command_obj()'. 
 906         for cmd 
in self
.commands
: 
 907             self
.run_command(cmd
) 
 910     # -- Methods that operate on its Commands -------------------------- 
 912     def run_command (self
, command
): 
 913         """Do whatever it takes to run a command (including nothing at all, 
 914         if the command has already been run).  Specifically: if we have 
 915         already created and run the command named by 'command', return 
 916         silently without doing anything.  If the command named by 'command' 
 917         doesn't even have a command object yet, create one.  Then invoke 
 918         'run()' on that command object (or an existing one). 
 920         # Already been here, done that? then return silently. 
 921         if self
.have_run
.get(command
): 
 924         log
.info("running %s", command
) 
 925         cmd_obj 
= self
.get_command_obj(command
) 
 926         cmd_obj
.ensure_finalized() 
 928         self
.have_run
[command
] = 1 
 931     # -- Distribution query methods ------------------------------------ 
 933     def has_pure_modules (self
): 
 934         return len(self
.packages 
or self
.py_modules 
or []) > 0 
 936     def has_ext_modules (self
): 
 937         return self
.ext_modules 
and len(self
.ext_modules
) > 0 
 939     def has_c_libraries (self
): 
 940         return self
.libraries 
and len(self
.libraries
) > 0 
 942     def has_modules (self
): 
 943         return self
.has_pure_modules() or self
.has_ext_modules() 
 945     def has_headers (self
): 
 946         return self
.headers 
and len(self
.headers
) > 0 
 948     def has_scripts (self
): 
 949         return self
.scripts 
and len(self
.scripts
) > 0 
 951     def has_data_files (self
): 
 952         return self
.data_files 
and len(self
.data_files
) > 0 
 955         return (self
.has_pure_modules() and 
 956                 not self
.has_ext_modules() and 
 957                 not self
.has_c_libraries()) 
 959     # -- Metadata query methods ---------------------------------------- 
 961     # If you're looking for 'get_name()', 'get_version()', and so forth, 
 962     # they are defined in a sneaky way: the constructor binds self.get_XXX 
 963     # to self.metadata.get_XXX.  The actual code is in the 
 964     # DistributionMetadata class, below. 
 969 class DistributionMetadata
: 
 970     """Dummy class to hold the distribution meta-data: name, version, 
 971     author, and so forth. 
 974     _METHOD_BASENAMES 
= ("name", "version", "author", "author_email", 
 975                          "maintainer", "maintainer_email", "url", 
 976                          "license", "description", "long_description", 
 977                          "keywords", "platforms", "fullname", "contact", 
 978                          "contact_email", "license", "classifiers", 
 985         self
.author_email 
= None 
 986         self
.maintainer 
= None 
 987         self
.maintainer_email 
= None 
 990         self
.description 
= None 
 991         self
.long_description 
= None 
 993         self
.platforms 
= None 
 994         self
.classifiers 
= None 
 995         self
.download_url 
= None 
 997     def write_pkg_info (self
, base_dir
): 
 998         """Write the PKG-INFO file into the release tree. 
1001         pkg_info 
= open( os
.path
.join(base_dir
, 'PKG-INFO'), 'w') 
1003         pkg_info
.write('Metadata-Version: 1.0\n') 
1004         pkg_info
.write('Name: %s\n' % self
.get_name() ) 
1005         pkg_info
.write('Version: %s\n' % self
.get_version() ) 
1006         pkg_info
.write('Summary: %s\n' % self
.get_description() ) 
1007         pkg_info
.write('Home-page: %s\n' % self
.get_url() ) 
1008         pkg_info
.write('Author: %s\n' % self
.get_contact() ) 
1009         pkg_info
.write('Author-email: %s\n' % self
.get_contact_email() ) 
1010         pkg_info
.write('License: %s\n' % self
.get_license() ) 
1011         if self
.download_url
: 
1012             pkg_info
.write('Download-URL: %s\n' % self
.download_url
) 
1014         long_desc 
= rfc822_escape( self
.get_long_description() ) 
1015         pkg_info
.write('Description: %s\n' % long_desc
) 
1017         keywords 
= string
.join( self
.get_keywords(), ',') 
1019             pkg_info
.write('Keywords: %s\n' % keywords 
) 
1021         for platform 
in self
.get_platforms(): 
1022             pkg_info
.write('Platform: %s\n' % platform 
) 
1024         for classifier 
in self
.get_classifiers(): 
1025             pkg_info
.write('Classifier: %s\n' % classifier 
) 
1031     # -- Metadata query methods ---------------------------------------- 
1033     def get_name (self
): 
1034         return self
.name 
or "UNKNOWN" 
1036     def get_version(self
): 
1037         return self
.version 
or "0.0.0" 
1039     def get_fullname (self
): 
1040         return "%s-%s" % (self
.get_name(), self
.get_version()) 
1042     def get_author(self
): 
1043         return self
.author 
or "UNKNOWN" 
1045     def get_author_email(self
): 
1046         return self
.author_email 
or "UNKNOWN" 
1048     def get_maintainer(self
): 
1049         return self
.maintainer 
or "UNKNOWN" 
1051     def get_maintainer_email(self
): 
1052         return self
.maintainer_email 
or "UNKNOWN" 
1054     def get_contact(self
): 
1055         return (self
.maintainer 
or 
1059     def get_contact_email(self
): 
1060         return (self
.maintainer_email 
or 
1061                 self
.author_email 
or 
1065         return self
.url 
or "UNKNOWN" 
1067     def get_license(self
): 
1068         return self
.license 
or "UNKNOWN" 
1069     get_licence 
= get_license
 
1071     def get_description(self
): 
1072         return self
.description 
or "UNKNOWN" 
1074     def get_long_description(self
): 
1075         return self
.long_description 
or "UNKNOWN" 
1077     def get_keywords(self
): 
1078         return self
.keywords 
or [] 
1080     def get_platforms(self
): 
1081         return self
.platforms 
or ["UNKNOWN"] 
1083     def get_classifiers(self
): 
1084         return self
.classifiers 
or [] 
1086     def get_download_url(self
): 
1087         return self
.download_url 
or "UNKNOWN" 
1089 # class DistributionMetadata 
1092 def fix_help_options (options
): 
1093     """Convert a 4-tuple 'help_options' list as found in various command 
1094     classes to the 3-tuple form required by FancyGetopt. 
1097     for help_tuple 
in options
: 
1098         new_options
.append(help_tuple
[0:3]) 
1102 if __name__ 
== "__main__": 
1103     dist 
= Distribution()