symbian-qemu-0.9.1-12/python-2.6.1/Lib/distutils/dist.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """distutils.dist
       
     2 
       
     3 Provides the Distribution class, which represents the module distribution
       
     4 being built/installed/distributed.
       
     5 """
       
     6 
       
     7 # This module should be kept compatible with Python 2.1.
       
     8 
       
     9 __revision__ = "$Id: dist.py 66181 2008-09-03 11:13:56Z marc-andre.lemburg $"
       
    10 
       
    11 import sys, os, string, re
       
    12 from types import *
       
    13 from copy import copy
       
    14 
       
    15 try:
       
    16     import warnings
       
    17 except ImportError:
       
    18     warnings = None
       
    19 
       
    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
       
    25 
       
    26 # Encoding used for the PKG-INFO files
       
    27 PKG_INFO_ENCODING = 'utf-8'
       
    28 
       
    29 # Regex to define acceptable Distutils command names.  This is not *quite*
       
    30 # the same as a Python NAME -- I don't allow leading underscores.  The fact
       
    31 # that they're very similar is no coincidence; the default naming scheme is
       
    32 # to look for a Python module named after the command.
       
    33 command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
       
    34 
       
    35 
       
    36 class Distribution:
       
    37     """The core of the Distutils.  Most of the work hiding behind 'setup'
       
    38     is really done within a Distribution instance, which farms the work out
       
    39     to the Distutils commands specified on the command line.
       
    40 
       
    41     Setup scripts will almost never instantiate Distribution directly,
       
    42     unless the 'setup()' function is totally inadequate to their needs.
       
    43     However, it is conceivable that a setup script might wish to subclass
       
    44     Distribution for some specialized purpose, and then pass the subclass
       
    45     to 'setup()' as the 'distclass' keyword argument.  If so, it is
       
    46     necessary to respect the expectations that 'setup' has of Distribution.
       
    47     See the code for 'setup()', in core.py, for details.
       
    48     """
       
    49 
       
    50 
       
    51     # 'global_options' describes the command-line options that may be
       
    52     # supplied to the setup script prior to any actual commands.
       
    53     # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
       
    54     # these global options.  This list should be kept to a bare minimum,
       
    55     # since every global option is also valid as a command option -- and we
       
    56     # don't want to pollute the commands with too many options that they
       
    57     # have minimal control over.
       
    58     # The fourth entry for verbose means that it can be repeated.
       
    59     global_options = [('verbose', 'v', "run verbosely (default)", 1),
       
    60                       ('quiet', 'q', "run quietly (turns verbosity off)"),
       
    61                       ('dry-run', 'n', "don't actually do anything"),
       
    62                       ('help', 'h', "show detailed help message"),
       
    63                      ]
       
    64 
       
    65     # 'common_usage' is a short (2-3 line) string describing the common
       
    66     # usage of the setup script.
       
    67     common_usage = """\
       
    68 Common commands: (see '--help-commands' for more)
       
    69 
       
    70   setup.py build      will build the package underneath 'build/'
       
    71   setup.py install    will install the package
       
    72 """
       
    73 
       
    74     # options that are not propagated to the commands
       
    75     display_options = [
       
    76         ('help-commands', None,
       
    77          "list all available commands"),
       
    78         ('name', None,
       
    79          "print package name"),
       
    80         ('version', 'V',
       
    81          "print package version"),
       
    82         ('fullname', None,
       
    83          "print <package name>-<version>"),
       
    84         ('author', None,
       
    85          "print the author's name"),
       
    86         ('author-email', None,
       
    87          "print the author's email address"),
       
    88         ('maintainer', None,
       
    89          "print the maintainer's name"),
       
    90         ('maintainer-email', None,
       
    91          "print the maintainer's email address"),
       
    92         ('contact', None,
       
    93          "print the maintainer's name if known, else the author's"),
       
    94         ('contact-email', None,
       
    95          "print the maintainer's email address if known, else the author's"),
       
    96         ('url', None,
       
    97          "print the URL for this package"),
       
    98         ('license', None,
       
    99          "print the license of the package"),
       
   100         ('licence', None,
       
   101          "alias for --license"),
       
   102         ('description', None,
       
   103          "print the package description"),
       
   104         ('long-description', None,
       
   105          "print the long package description"),
       
   106         ('platforms', None,
       
   107          "print the list of platforms"),
       
   108         ('classifiers', None,
       
   109          "print the list of classifiers"),
       
   110         ('keywords', None,
       
   111          "print the list of keywords"),
       
   112         ('provides', None,
       
   113          "print the list of packages/modules provided"),
       
   114         ('requires', None,
       
   115          "print the list of packages/modules required"),
       
   116         ('obsoletes', None,
       
   117          "print the list of packages/modules made obsolete")
       
   118         ]
       
   119     display_option_names = map(lambda x: translate_longopt(x[0]),
       
   120                                display_options)
       
   121 
       
   122     # negative options are options that exclude other options
       
   123     negative_opt = {'quiet': 'verbose'}
       
   124 
       
   125 
       
   126     # -- Creation/initialization methods -------------------------------
       
   127 
       
   128     def __init__ (self, attrs=None):
       
   129         """Construct a new Distribution instance: initialize all the
       
   130         attributes of a Distribution, and then use 'attrs' (a dictionary
       
   131         mapping attribute names to values) to assign some of those
       
   132         attributes their "real" values.  (Any attributes not mentioned in
       
   133         'attrs' will be assigned to some null value: 0, None, an empty list
       
   134         or dictionary, etc.)  Most importantly, initialize the
       
   135         'command_obj' attribute to the empty dictionary; this will be
       
   136         filled in with real command objects by 'parse_command_line()'.
       
   137         """
       
   138 
       
   139         # Default values for our command-line options
       
   140         self.verbose = 1
       
   141         self.dry_run = 0
       
   142         self.help = 0
       
   143         for attr in self.display_option_names:
       
   144             setattr(self, attr, 0)
       
   145 
       
   146         # Store the distribution meta-data (name, version, author, and so
       
   147         # forth) in a separate object -- we're getting to have enough
       
   148         # information here (and enough command-line options) that it's
       
   149         # worth it.  Also delegate 'get_XXX()' methods to the 'metadata'
       
   150         # object in a sneaky and underhanded (but efficient!) way.
       
   151         self.metadata = DistributionMetadata()
       
   152         for basename in self.metadata._METHOD_BASENAMES:
       
   153             method_name = "get_" + basename
       
   154             setattr(self, method_name, getattr(self.metadata, method_name))
       
   155 
       
   156         # 'cmdclass' maps command names to class objects, so we
       
   157         # can 1) quickly figure out which class to instantiate when
       
   158         # we need to create a new command object, and 2) have a way
       
   159         # for the setup script to override command classes
       
   160         self.cmdclass = {}
       
   161 
       
   162         # 'command_packages' is a list of packages in which commands
       
   163         # are searched for.  The factory for command 'foo' is expected
       
   164         # to be named 'foo' in the module 'foo' in one of the packages
       
   165         # named here.  This list is searched from the left; an error
       
   166         # is raised if no named package provides the command being
       
   167         # searched for.  (Always access using get_command_packages().)
       
   168         self.command_packages = None
       
   169 
       
   170         # 'script_name' and 'script_args' are usually set to sys.argv[0]
       
   171         # and sys.argv[1:], but they can be overridden when the caller is
       
   172         # not necessarily a setup script run from the command-line.
       
   173         self.script_name = None
       
   174         self.script_args = None
       
   175 
       
   176         # 'command_options' is where we store command options between
       
   177         # parsing them (from config files, the command-line, etc.) and when
       
   178         # they are actually needed -- ie. when the command in question is
       
   179         # instantiated.  It is a dictionary of dictionaries of 2-tuples:
       
   180         #   command_options = { command_name : { option : (source, value) } }
       
   181         self.command_options = {}
       
   182 
       
   183         # 'dist_files' is the list of (command, pyversion, file) that
       
   184         # have been created by any dist commands run so far. This is
       
   185         # filled regardless of whether the run is dry or not. pyversion
       
   186         # gives sysconfig.get_python_version() if the dist file is
       
   187         # specific to a Python version, 'any' if it is good for all
       
   188         # Python versions on the target platform, and '' for a source
       
   189         # file. pyversion should not be used to specify minimum or
       
   190         # maximum required Python versions; use the metainfo for that
       
   191         # instead.
       
   192         self.dist_files = []
       
   193 
       
   194         # These options are really the business of various commands, rather
       
   195         # than of the Distribution itself.  We provide aliases for them in
       
   196         # Distribution as a convenience to the developer.
       
   197         self.packages = None
       
   198         self.package_data = {}
       
   199         self.package_dir = None
       
   200         self.py_modules = None
       
   201         self.libraries = None
       
   202         self.headers = None
       
   203         self.ext_modules = None
       
   204         self.ext_package = None
       
   205         self.include_dirs = None
       
   206         self.extra_path = None
       
   207         self.scripts = None
       
   208         self.data_files = None
       
   209 
       
   210         # And now initialize bookkeeping stuff that can't be supplied by
       
   211         # the caller at all.  'command_obj' maps command names to
       
   212         # Command instances -- that's how we enforce that every command
       
   213         # class is a singleton.
       
   214         self.command_obj = {}
       
   215 
       
   216         # 'have_run' maps command names to boolean values; it keeps track
       
   217         # of whether we have actually run a particular command, to make it
       
   218         # cheap to "run" a command whenever we think we might need to -- if
       
   219         # it's already been done, no need for expensive filesystem
       
   220         # operations, we just check the 'have_run' dictionary and carry on.
       
   221         # It's only safe to query 'have_run' for a command class that has
       
   222         # been instantiated -- a false value will be inserted when the
       
   223         # command object is created, and replaced with a true value when
       
   224         # the command is successfully run.  Thus it's probably best to use
       
   225         # '.get()' rather than a straight lookup.
       
   226         self.have_run = {}
       
   227 
       
   228         # Now we'll use the attrs dictionary (ultimately, keyword args from
       
   229         # the setup script) to possibly override any or all of these
       
   230         # distribution options.
       
   231 
       
   232         if attrs:
       
   233             # Pull out the set of command options and work on them
       
   234             # specifically.  Note that this order guarantees that aliased
       
   235             # command options will override any supplied redundantly
       
   236             # through the general options dictionary.
       
   237             options = attrs.get('options')
       
   238             if options:
       
   239                 del attrs['options']
       
   240                 for (command, cmd_options) in options.items():
       
   241                     opt_dict = self.get_option_dict(command)
       
   242                     for (opt, val) in cmd_options.items():
       
   243                         opt_dict[opt] = ("setup script", val)
       
   244 
       
   245             if 'licence' in attrs:
       
   246                 attrs['license'] = attrs['licence']
       
   247                 del attrs['licence']
       
   248                 msg = "'licence' distribution option is deprecated; use 'license'"
       
   249                 if warnings is not None:
       
   250                     warnings.warn(msg)
       
   251                 else:
       
   252                     sys.stderr.write(msg + "\n")
       
   253 
       
   254             # Now work on the rest of the attributes.  Any attribute that's
       
   255             # not already defined is invalid!
       
   256             for (key,val) in attrs.items():
       
   257                 if hasattr(self.metadata, "set_" + key):
       
   258                     getattr(self.metadata, "set_" + key)(val)
       
   259                 elif hasattr(self.metadata, key):
       
   260                     setattr(self.metadata, key, val)
       
   261                 elif hasattr(self, key):
       
   262                     setattr(self, key, val)
       
   263                 else:
       
   264                     msg = "Unknown distribution option: %s" % repr(key)
       
   265                     if warnings is not None:
       
   266                         warnings.warn(msg)
       
   267                     else:
       
   268                         sys.stderr.write(msg + "\n")
       
   269 
       
   270         self.finalize_options()
       
   271 
       
   272     # __init__ ()
       
   273 
       
   274 
       
   275     def get_option_dict (self, command):
       
   276         """Get the option dictionary for a given command.  If that
       
   277         command's option dictionary hasn't been created yet, then create it
       
   278         and return the new dictionary; otherwise, return the existing
       
   279         option dictionary.
       
   280         """
       
   281 
       
   282         dict = self.command_options.get(command)
       
   283         if dict is None:
       
   284             dict = self.command_options[command] = {}
       
   285         return dict
       
   286 
       
   287 
       
   288     def dump_option_dicts (self, header=None, commands=None, indent=""):
       
   289         from pprint import pformat
       
   290 
       
   291         if commands is None:             # dump all command option dicts
       
   292             commands = self.command_options.keys()
       
   293             commands.sort()
       
   294 
       
   295         if header is not None:
       
   296             print indent + header
       
   297             indent = indent + "  "
       
   298 
       
   299         if not commands:
       
   300             print indent + "no commands known yet"
       
   301             return
       
   302 
       
   303         for cmd_name in commands:
       
   304             opt_dict = self.command_options.get(cmd_name)
       
   305             if opt_dict is None:
       
   306                 print indent + "no option dict for '%s' command" % cmd_name
       
   307             else:
       
   308                 print indent + "option dict for '%s' command:" % cmd_name
       
   309                 out = pformat(opt_dict)
       
   310                 for line in string.split(out, "\n"):
       
   311                     print indent + "  " + line
       
   312 
       
   313     # dump_option_dicts ()
       
   314 
       
   315 
       
   316 
       
   317     # -- Config file finding/parsing methods ---------------------------
       
   318 
       
   319     def find_config_files (self):
       
   320         """Find as many configuration files as should be processed for this
       
   321         platform, and return a list of filenames in the order in which they
       
   322         should be parsed.  The filenames returned are guaranteed to exist
       
   323         (modulo nasty race conditions).
       
   324 
       
   325         There are three possible config files: distutils.cfg in the
       
   326         Distutils installation directory (ie. where the top-level
       
   327         Distutils __inst__.py file lives), a file in the user's home
       
   328         directory named .pydistutils.cfg on Unix and pydistutils.cfg
       
   329         on Windows/Mac, and setup.cfg in the current directory.
       
   330         """
       
   331         files = []
       
   332         check_environ()
       
   333 
       
   334         # Where to look for the system-wide Distutils config file
       
   335         sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
       
   336 
       
   337         # Look for the system config file
       
   338         sys_file = os.path.join(sys_dir, "distutils.cfg")
       
   339         if os.path.isfile(sys_file):
       
   340             files.append(sys_file)
       
   341 
       
   342         # What to call the per-user config file
       
   343         if os.name == 'posix':
       
   344             user_filename = ".pydistutils.cfg"
       
   345         else:
       
   346             user_filename = "pydistutils.cfg"
       
   347 
       
   348         # And look for the user config file
       
   349         user_file = os.path.join(os.path.expanduser('~'), user_filename)
       
   350         if os.path.isfile(user_file):
       
   351             files.append(user_file)
       
   352 
       
   353         # All platforms support local setup.cfg
       
   354         local_file = "setup.cfg"
       
   355         if os.path.isfile(local_file):
       
   356             files.append(local_file)
       
   357 
       
   358         return files
       
   359 
       
   360     # find_config_files ()
       
   361 
       
   362 
       
   363     def parse_config_files (self, filenames=None):
       
   364         from ConfigParser import ConfigParser
       
   365 
       
   366         if filenames is None:
       
   367             filenames = self.find_config_files()
       
   368 
       
   369         if DEBUG: print "Distribution.parse_config_files():"
       
   370 
       
   371         parser = ConfigParser()
       
   372         for filename in filenames:
       
   373             if DEBUG: print "  reading", filename
       
   374             parser.read(filename)
       
   375             for section in parser.sections():
       
   376                 options = parser.options(section)
       
   377                 opt_dict = self.get_option_dict(section)
       
   378 
       
   379                 for opt in options:
       
   380                     if opt != '__name__':
       
   381                         val = parser.get(section,opt)
       
   382                         opt = string.replace(opt, '-', '_')
       
   383                         opt_dict[opt] = (filename, val)
       
   384 
       
   385             # Make the ConfigParser forget everything (so we retain
       
   386             # the original filenames that options come from)
       
   387             parser.__init__()
       
   388 
       
   389         # If there was a "global" section in the config file, use it
       
   390         # to set Distribution options.
       
   391 
       
   392         if 'global' in self.command_options:
       
   393             for (opt, (src, val)) in self.command_options['global'].items():
       
   394                 alias = self.negative_opt.get(opt)
       
   395                 try:
       
   396                     if alias:
       
   397                         setattr(self, alias, not strtobool(val))
       
   398                     elif opt in ('verbose', 'dry_run'): # ugh!
       
   399                         setattr(self, opt, strtobool(val))
       
   400                     else:
       
   401                         setattr(self, opt, val)
       
   402                 except ValueError, msg:
       
   403                     raise DistutilsOptionError, msg
       
   404 
       
   405     # parse_config_files ()
       
   406 
       
   407 
       
   408     # -- Command-line parsing methods ----------------------------------
       
   409 
       
   410     def parse_command_line (self):
       
   411         """Parse the setup script's command line, taken from the
       
   412         'script_args' instance attribute (which defaults to 'sys.argv[1:]'
       
   413         -- see 'setup()' in core.py).  This list is first processed for
       
   414         "global options" -- options that set attributes of the Distribution
       
   415         instance.  Then, it is alternately scanned for Distutils commands
       
   416         and options for that command.  Each new command terminates the
       
   417         options for the previous command.  The allowed options for a
       
   418         command are determined by the 'user_options' attribute of the
       
   419         command class -- thus, we have to be able to load command classes
       
   420         in order to parse the command line.  Any error in that 'options'
       
   421         attribute raises DistutilsGetoptError; any error on the
       
   422         command-line raises DistutilsArgError.  If no Distutils commands
       
   423         were found on the command line, raises DistutilsArgError.  Return
       
   424         true if command-line was successfully parsed and we should carry
       
   425         on with executing commands; false if no errors but we shouldn't
       
   426         execute commands (currently, this only happens if user asks for
       
   427         help).
       
   428         """
       
   429         #
       
   430         # We now have enough information to show the Macintosh dialog
       
   431         # that allows the user to interactively specify the "command line".
       
   432         #
       
   433         toplevel_options = self._get_toplevel_options()
       
   434         if sys.platform == 'mac':
       
   435             import EasyDialogs
       
   436             cmdlist = self.get_command_list()
       
   437             self.script_args = EasyDialogs.GetArgv(
       
   438                 toplevel_options + self.display_options, cmdlist)
       
   439 
       
   440         # We have to parse the command line a bit at a time -- global
       
   441         # options, then the first command, then its options, and so on --
       
   442         # because each command will be handled by a different class, and
       
   443         # the options that are valid for a particular class aren't known
       
   444         # until we have loaded the command class, which doesn't happen
       
   445         # until we know what the command is.
       
   446 
       
   447         self.commands = []
       
   448         parser = FancyGetopt(toplevel_options + self.display_options)
       
   449         parser.set_negative_aliases(self.negative_opt)
       
   450         parser.set_aliases({'licence': 'license'})
       
   451         args = parser.getopt(args=self.script_args, object=self)
       
   452         option_order = parser.get_option_order()
       
   453         log.set_verbosity(self.verbose)
       
   454 
       
   455         # for display options we return immediately
       
   456         if self.handle_display_options(option_order):
       
   457             return
       
   458 
       
   459         while args:
       
   460             args = self._parse_command_opts(parser, args)
       
   461             if args is None:            # user asked for help (and got it)
       
   462                 return
       
   463 
       
   464         # Handle the cases of --help as a "global" option, ie.
       
   465         # "setup.py --help" and "setup.py --help command ...".  For the
       
   466         # former, we show global options (--verbose, --dry-run, etc.)
       
   467         # and display-only options (--name, --version, etc.); for the
       
   468         # latter, we omit the display-only options and show help for
       
   469         # each command listed on the command line.
       
   470         if self.help:
       
   471             self._show_help(parser,
       
   472                             display_options=len(self.commands) == 0,
       
   473                             commands=self.commands)
       
   474             return
       
   475 
       
   476         # Oops, no commands found -- an end-user error
       
   477         if not self.commands:
       
   478             raise DistutilsArgError, "no commands supplied"
       
   479 
       
   480         # All is well: return true
       
   481         return 1
       
   482 
       
   483     # parse_command_line()
       
   484 
       
   485     def _get_toplevel_options (self):
       
   486         """Return the non-display options recognized at the top level.
       
   487 
       
   488         This includes options that are recognized *only* at the top
       
   489         level as well as options recognized for commands.
       
   490         """
       
   491         return self.global_options + [
       
   492             ("command-packages=", None,
       
   493              "list of packages that provide distutils commands"),
       
   494             ]
       
   495 
       
   496     def _parse_command_opts (self, parser, args):
       
   497         """Parse the command-line options for a single command.
       
   498         'parser' must be a FancyGetopt instance; 'args' must be the list
       
   499         of arguments, starting with the current command (whose options
       
   500         we are about to parse).  Returns a new version of 'args' with
       
   501         the next command at the front of the list; will be the empty
       
   502         list if there are no more commands on the command line.  Returns
       
   503         None if the user asked for help on this command.
       
   504         """
       
   505         # late import because of mutual dependence between these modules
       
   506         from distutils.cmd import Command
       
   507 
       
   508         # Pull the current command from the head of the command line
       
   509         command = args[0]
       
   510         if not command_re.match(command):
       
   511             raise SystemExit, "invalid command name '%s'" % command
       
   512         self.commands.append(command)
       
   513 
       
   514         # Dig up the command class that implements this command, so we
       
   515         # 1) know that it's a valid command, and 2) know which options
       
   516         # it takes.
       
   517         try:
       
   518             cmd_class = self.get_command_class(command)
       
   519         except DistutilsModuleError, msg:
       
   520             raise DistutilsArgError, msg
       
   521 
       
   522         # Require that the command class be derived from Command -- want
       
   523         # to be sure that the basic "command" interface is implemented.
       
   524         if not issubclass(cmd_class, Command):
       
   525             raise DistutilsClassError, \
       
   526                   "command class %s must subclass Command" % cmd_class
       
   527 
       
   528         # Also make sure that the command object provides a list of its
       
   529         # known options.
       
   530         if not (hasattr(cmd_class, 'user_options') and
       
   531                 type(cmd_class.user_options) is ListType):
       
   532             raise DistutilsClassError, \
       
   533                   ("command class %s must provide " +
       
   534                    "'user_options' attribute (a list of tuples)") % \
       
   535                   cmd_class
       
   536 
       
   537         # If the command class has a list of negative alias options,
       
   538         # merge it in with the global negative aliases.
       
   539         negative_opt = self.negative_opt
       
   540         if hasattr(cmd_class, 'negative_opt'):
       
   541             negative_opt = copy(negative_opt)
       
   542             negative_opt.update(cmd_class.negative_opt)
       
   543 
       
   544         # Check for help_options in command class.  They have a different
       
   545         # format (tuple of four) so we need to preprocess them here.
       
   546         if (hasattr(cmd_class, 'help_options') and
       
   547             type(cmd_class.help_options) is ListType):
       
   548             help_options = fix_help_options(cmd_class.help_options)
       
   549         else:
       
   550             help_options = []
       
   551 
       
   552 
       
   553         # All commands support the global options too, just by adding
       
   554         # in 'global_options'.
       
   555         parser.set_option_table(self.global_options +
       
   556                                 cmd_class.user_options +
       
   557                                 help_options)
       
   558         parser.set_negative_aliases(negative_opt)
       
   559         (args, opts) = parser.getopt(args[1:])
       
   560         if hasattr(opts, 'help') and opts.help:
       
   561             self._show_help(parser, display_options=0, commands=[cmd_class])
       
   562             return
       
   563 
       
   564         if (hasattr(cmd_class, 'help_options') and
       
   565             type(cmd_class.help_options) is ListType):
       
   566             help_option_found=0
       
   567             for (help_option, short, desc, func) in cmd_class.help_options:
       
   568                 if hasattr(opts, parser.get_attr_name(help_option)):
       
   569                     help_option_found=1
       
   570                     #print "showing help for option %s of command %s" % \
       
   571                     #      (help_option[0],cmd_class)
       
   572 
       
   573                     if callable(func):
       
   574                         func()
       
   575                     else:
       
   576                         raise DistutilsClassError(
       
   577                             "invalid help function %r for help option '%s': "
       
   578                             "must be a callable object (function, etc.)"
       
   579                             % (func, help_option))
       
   580 
       
   581             if help_option_found:
       
   582                 return
       
   583 
       
   584         # Put the options from the command-line into their official
       
   585         # holding pen, the 'command_options' dictionary.
       
   586         opt_dict = self.get_option_dict(command)
       
   587         for (name, value) in vars(opts).items():
       
   588             opt_dict[name] = ("command line", value)
       
   589 
       
   590         return args
       
   591 
       
   592     # _parse_command_opts ()
       
   593 
       
   594     def finalize_options (self):
       
   595         """Set final values for all the options on the Distribution
       
   596         instance, analogous to the .finalize_options() method of Command
       
   597         objects.
       
   598         """
       
   599 
       
   600         keywords = self.metadata.keywords
       
   601         if keywords is not None:
       
   602             if type(keywords) is StringType:
       
   603                 keywordlist = string.split(keywords, ',')
       
   604                 self.metadata.keywords = map(string.strip, keywordlist)
       
   605 
       
   606         platforms = self.metadata.platforms
       
   607         if platforms is not None:
       
   608             if type(platforms) is StringType:
       
   609                 platformlist = string.split(platforms, ',')
       
   610                 self.metadata.platforms = map(string.strip, platformlist)
       
   611 
       
   612     def _show_help (self,
       
   613                     parser,
       
   614                     global_options=1,
       
   615                     display_options=1,
       
   616                     commands=[]):
       
   617         """Show help for the setup script command-line in the form of
       
   618         several lists of command-line options.  'parser' should be a
       
   619         FancyGetopt instance; do not expect it to be returned in the
       
   620         same state, as its option table will be reset to make it
       
   621         generate the correct help text.
       
   622 
       
   623         If 'global_options' is true, lists the global options:
       
   624         --verbose, --dry-run, etc.  If 'display_options' is true, lists
       
   625         the "display-only" options: --name, --version, etc.  Finally,
       
   626         lists per-command help for every command name or command class
       
   627         in 'commands'.
       
   628         """
       
   629         # late import because of mutual dependence between these modules
       
   630         from distutils.core import gen_usage
       
   631         from distutils.cmd import Command
       
   632 
       
   633         if global_options:
       
   634             if display_options:
       
   635                 options = self._get_toplevel_options()
       
   636             else:
       
   637                 options = self.global_options
       
   638             parser.set_option_table(options)
       
   639             parser.print_help(self.common_usage + "\nGlobal options:")
       
   640             print
       
   641 
       
   642         if display_options:
       
   643             parser.set_option_table(self.display_options)
       
   644             parser.print_help(
       
   645                 "Information display options (just display " +
       
   646                 "information, ignore any commands)")
       
   647             print
       
   648 
       
   649         for command in self.commands:
       
   650             if type(command) is ClassType and issubclass(command, Command):
       
   651                 klass = command
       
   652             else:
       
   653                 klass = self.get_command_class(command)
       
   654             if (hasattr(klass, 'help_options') and
       
   655                 type(klass.help_options) is ListType):
       
   656                 parser.set_option_table(klass.user_options +
       
   657                                         fix_help_options(klass.help_options))
       
   658             else:
       
   659                 parser.set_option_table(klass.user_options)
       
   660             parser.print_help("Options for '%s' command:" % klass.__name__)
       
   661             print
       
   662 
       
   663         print gen_usage(self.script_name)
       
   664         return
       
   665 
       
   666     # _show_help ()
       
   667 
       
   668 
       
   669     def handle_display_options (self, option_order):
       
   670         """If there were any non-global "display-only" options
       
   671         (--help-commands or the metadata display options) on the command
       
   672         line, display the requested info and return true; else return
       
   673         false.
       
   674         """
       
   675         from distutils.core import gen_usage
       
   676 
       
   677         # User just wants a list of commands -- we'll print it out and stop
       
   678         # processing now (ie. if they ran "setup --help-commands foo bar",
       
   679         # we ignore "foo bar").
       
   680         if self.help_commands:
       
   681             self.print_commands()
       
   682             print
       
   683             print gen_usage(self.script_name)
       
   684             return 1
       
   685 
       
   686         # If user supplied any of the "display metadata" options, then
       
   687         # display that metadata in the order in which the user supplied the
       
   688         # metadata options.
       
   689         any_display_options = 0
       
   690         is_display_option = {}
       
   691         for option in self.display_options:
       
   692             is_display_option[option[0]] = 1
       
   693 
       
   694         for (opt, val) in option_order:
       
   695             if val and is_display_option.get(opt):
       
   696                 opt = translate_longopt(opt)
       
   697                 value = getattr(self.metadata, "get_"+opt)()
       
   698                 if opt in ['keywords', 'platforms']:
       
   699                     print string.join(value, ',')
       
   700                 elif opt in ('classifiers', 'provides', 'requires',
       
   701                              'obsoletes'):
       
   702                     print string.join(value, '\n')
       
   703                 else:
       
   704                     print value
       
   705                 any_display_options = 1
       
   706 
       
   707         return any_display_options
       
   708 
       
   709     # handle_display_options()
       
   710 
       
   711     def print_command_list (self, commands, header, max_length):
       
   712         """Print a subset of the list of all commands -- used by
       
   713         'print_commands()'.
       
   714         """
       
   715 
       
   716         print header + ":"
       
   717 
       
   718         for cmd in commands:
       
   719             klass = self.cmdclass.get(cmd)
       
   720             if not klass:
       
   721                 klass = self.get_command_class(cmd)
       
   722             try:
       
   723                 description = klass.description
       
   724             except AttributeError:
       
   725                 description = "(no description available)"
       
   726 
       
   727             print "  %-*s  %s" % (max_length, cmd, description)
       
   728 
       
   729     # print_command_list ()
       
   730 
       
   731 
       
   732     def print_commands (self):
       
   733         """Print out a help message listing all available commands with a
       
   734         description of each.  The list is divided into "standard commands"
       
   735         (listed in distutils.command.__all__) and "extra commands"
       
   736         (mentioned in self.cmdclass, but not a standard command).  The
       
   737         descriptions come from the command class attribute
       
   738         'description'.
       
   739         """
       
   740 
       
   741         import distutils.command
       
   742         std_commands = distutils.command.__all__
       
   743         is_std = {}
       
   744         for cmd in std_commands:
       
   745             is_std[cmd] = 1
       
   746 
       
   747         extra_commands = []
       
   748         for cmd in self.cmdclass.keys():
       
   749             if not is_std.get(cmd):
       
   750                 extra_commands.append(cmd)
       
   751 
       
   752         max_length = 0
       
   753         for cmd in (std_commands + extra_commands):
       
   754             if len(cmd) > max_length:
       
   755                 max_length = len(cmd)
       
   756 
       
   757         self.print_command_list(std_commands,
       
   758                                 "Standard commands",
       
   759                                 max_length)
       
   760         if extra_commands:
       
   761             print
       
   762             self.print_command_list(extra_commands,
       
   763                                     "Extra commands",
       
   764                                     max_length)
       
   765 
       
   766     # print_commands ()
       
   767 
       
   768     def get_command_list (self):
       
   769         """Get a list of (command, description) tuples.
       
   770         The list is divided into "standard commands" (listed in
       
   771         distutils.command.__all__) and "extra commands" (mentioned in
       
   772         self.cmdclass, but not a standard command).  The descriptions come
       
   773         from the command class attribute 'description'.
       
   774         """
       
   775         # Currently this is only used on Mac OS, for the Mac-only GUI
       
   776         # Distutils interface (by Jack Jansen)
       
   777 
       
   778         import distutils.command
       
   779         std_commands = distutils.command.__all__
       
   780         is_std = {}
       
   781         for cmd in std_commands:
       
   782             is_std[cmd] = 1
       
   783 
       
   784         extra_commands = []
       
   785         for cmd in self.cmdclass.keys():
       
   786             if not is_std.get(cmd):
       
   787                 extra_commands.append(cmd)
       
   788 
       
   789         rv = []
       
   790         for cmd in (std_commands + extra_commands):
       
   791             klass = self.cmdclass.get(cmd)
       
   792             if not klass:
       
   793                 klass = self.get_command_class(cmd)
       
   794             try:
       
   795                 description = klass.description
       
   796             except AttributeError:
       
   797                 description = "(no description available)"
       
   798             rv.append((cmd, description))
       
   799         return rv
       
   800 
       
   801     # -- Command class/object methods ----------------------------------
       
   802 
       
   803     def get_command_packages (self):
       
   804         """Return a list of packages from which commands are loaded."""
       
   805         pkgs = self.command_packages
       
   806         if not isinstance(pkgs, type([])):
       
   807             pkgs = string.split(pkgs or "", ",")
       
   808             for i in range(len(pkgs)):
       
   809                 pkgs[i] = string.strip(pkgs[i])
       
   810             pkgs = filter(None, pkgs)
       
   811             if "distutils.command" not in pkgs:
       
   812                 pkgs.insert(0, "distutils.command")
       
   813             self.command_packages = pkgs
       
   814         return pkgs
       
   815 
       
   816     def get_command_class (self, command):
       
   817         """Return the class that implements the Distutils command named by
       
   818         'command'.  First we check the 'cmdclass' dictionary; if the
       
   819         command is mentioned there, we fetch the class object from the
       
   820         dictionary and return it.  Otherwise we load the command module
       
   821         ("distutils.command." + command) and fetch the command class from
       
   822         the module.  The loaded class is also stored in 'cmdclass'
       
   823         to speed future calls to 'get_command_class()'.
       
   824 
       
   825         Raises DistutilsModuleError if the expected module could not be
       
   826         found, or if that module does not define the expected class.
       
   827         """
       
   828         klass = self.cmdclass.get(command)
       
   829         if klass:
       
   830             return klass
       
   831 
       
   832         for pkgname in self.get_command_packages():
       
   833             module_name = "%s.%s" % (pkgname, command)
       
   834             klass_name = command
       
   835 
       
   836             try:
       
   837                 __import__ (module_name)
       
   838                 module = sys.modules[module_name]
       
   839             except ImportError:
       
   840                 continue
       
   841 
       
   842             try:
       
   843                 klass = getattr(module, klass_name)
       
   844             except AttributeError:
       
   845                 raise DistutilsModuleError, \
       
   846                       "invalid command '%s' (no class '%s' in module '%s')" \
       
   847                       % (command, klass_name, module_name)
       
   848 
       
   849             self.cmdclass[command] = klass
       
   850             return klass
       
   851 
       
   852         raise DistutilsModuleError("invalid command '%s'" % command)
       
   853 
       
   854 
       
   855     # get_command_class ()
       
   856 
       
   857     def get_command_obj (self, command, create=1):
       
   858         """Return the command object for 'command'.  Normally this object
       
   859         is cached on a previous call to 'get_command_obj()'; if no command
       
   860         object for 'command' is in the cache, then we either create and
       
   861         return it (if 'create' is true) or return None.
       
   862         """
       
   863         cmd_obj = self.command_obj.get(command)
       
   864         if not cmd_obj and create:
       
   865             if DEBUG:
       
   866                 print "Distribution.get_command_obj(): " \
       
   867                       "creating '%s' command object" % command
       
   868 
       
   869             klass = self.get_command_class(command)
       
   870             cmd_obj = self.command_obj[command] = klass(self)
       
   871             self.have_run[command] = 0
       
   872 
       
   873             # Set any options that were supplied in config files
       
   874             # or on the command line.  (NB. support for error
       
   875             # reporting is lame here: any errors aren't reported
       
   876             # until 'finalize_options()' is called, which means
       
   877             # we won't report the source of the error.)
       
   878             options = self.command_options.get(command)
       
   879             if options:
       
   880                 self._set_command_options(cmd_obj, options)
       
   881 
       
   882         return cmd_obj
       
   883 
       
   884     def _set_command_options (self, command_obj, option_dict=None):
       
   885         """Set the options for 'command_obj' from 'option_dict'.  Basically
       
   886         this means copying elements of a dictionary ('option_dict') to
       
   887         attributes of an instance ('command').
       
   888 
       
   889         'command_obj' must be a Command instance.  If 'option_dict' is not
       
   890         supplied, uses the standard option dictionary for this command
       
   891         (from 'self.command_options').
       
   892         """
       
   893         command_name = command_obj.get_command_name()
       
   894         if option_dict is None:
       
   895             option_dict = self.get_option_dict(command_name)
       
   896 
       
   897         if DEBUG: print "  setting options for '%s' command:" % command_name
       
   898         for (option, (source, value)) in option_dict.items():
       
   899             if DEBUG: print "    %s = %s (from %s)" % (option, value, source)
       
   900             try:
       
   901                 bool_opts = map(translate_longopt, command_obj.boolean_options)
       
   902             except AttributeError:
       
   903                 bool_opts = []
       
   904             try:
       
   905                 neg_opt = command_obj.negative_opt
       
   906             except AttributeError:
       
   907                 neg_opt = {}
       
   908 
       
   909             try:
       
   910                 is_string = type(value) is StringType
       
   911                 if option in neg_opt and is_string:
       
   912                     setattr(command_obj, neg_opt[option], not strtobool(value))
       
   913                 elif option in bool_opts and is_string:
       
   914                     setattr(command_obj, option, strtobool(value))
       
   915                 elif hasattr(command_obj, option):
       
   916                     setattr(command_obj, option, value)
       
   917                 else:
       
   918                     raise DistutilsOptionError, \
       
   919                           ("error in %s: command '%s' has no such option '%s'"
       
   920                            % (source, command_name, option))
       
   921             except ValueError, msg:
       
   922                 raise DistutilsOptionError, msg
       
   923 
       
   924     def reinitialize_command (self, command, reinit_subcommands=0):
       
   925         """Reinitializes a command to the state it was in when first
       
   926         returned by 'get_command_obj()': ie., initialized but not yet
       
   927         finalized.  This provides the opportunity to sneak option
       
   928         values in programmatically, overriding or supplementing
       
   929         user-supplied values from the config files and command line.
       
   930         You'll have to re-finalize the command object (by calling
       
   931         'finalize_options()' or 'ensure_finalized()') before using it for
       
   932         real.
       
   933 
       
   934         'command' should be a command name (string) or command object.  If
       
   935         'reinit_subcommands' is true, also reinitializes the command's
       
   936         sub-commands, as declared by the 'sub_commands' class attribute (if
       
   937         it has one).  See the "install" command for an example.  Only
       
   938         reinitializes the sub-commands that actually matter, ie. those
       
   939         whose test predicates return true.
       
   940 
       
   941         Returns the reinitialized command object.
       
   942         """
       
   943         from distutils.cmd import Command
       
   944         if not isinstance(command, Command):
       
   945             command_name = command
       
   946             command = self.get_command_obj(command_name)
       
   947         else:
       
   948             command_name = command.get_command_name()
       
   949 
       
   950         if not command.finalized:
       
   951             return command
       
   952         command.initialize_options()
       
   953         command.finalized = 0
       
   954         self.have_run[command_name] = 0
       
   955         self._set_command_options(command)
       
   956 
       
   957         if reinit_subcommands:
       
   958             for sub in command.get_sub_commands():
       
   959                 self.reinitialize_command(sub, reinit_subcommands)
       
   960 
       
   961         return command
       
   962 
       
   963 
       
   964     # -- Methods that operate on the Distribution ----------------------
       
   965 
       
   966     def announce (self, msg, level=1):
       
   967         log.debug(msg)
       
   968 
       
   969     def run_commands (self):
       
   970         """Run each command that was seen on the setup script command line.
       
   971         Uses the list of commands found and cache of command objects
       
   972         created by 'get_command_obj()'.
       
   973         """
       
   974         for cmd in self.commands:
       
   975             self.run_command(cmd)
       
   976 
       
   977 
       
   978     # -- Methods that operate on its Commands --------------------------
       
   979 
       
   980     def run_command (self, command):
       
   981         """Do whatever it takes to run a command (including nothing at all,
       
   982         if the command has already been run).  Specifically: if we have
       
   983         already created and run the command named by 'command', return
       
   984         silently without doing anything.  If the command named by 'command'
       
   985         doesn't even have a command object yet, create one.  Then invoke
       
   986         'run()' on that command object (or an existing one).
       
   987         """
       
   988         # Already been here, done that? then return silently.
       
   989         if self.have_run.get(command):
       
   990             return
       
   991 
       
   992         log.info("running %s", command)
       
   993         cmd_obj = self.get_command_obj(command)
       
   994         cmd_obj.ensure_finalized()
       
   995         cmd_obj.run()
       
   996         self.have_run[command] = 1
       
   997 
       
   998 
       
   999     # -- Distribution query methods ------------------------------------
       
  1000 
       
  1001     def has_pure_modules (self):
       
  1002         return len(self.packages or self.py_modules or []) > 0
       
  1003 
       
  1004     def has_ext_modules (self):
       
  1005         return self.ext_modules and len(self.ext_modules) > 0
       
  1006 
       
  1007     def has_c_libraries (self):
       
  1008         return self.libraries and len(self.libraries) > 0
       
  1009 
       
  1010     def has_modules (self):
       
  1011         return self.has_pure_modules() or self.has_ext_modules()
       
  1012 
       
  1013     def has_headers (self):
       
  1014         return self.headers and len(self.headers) > 0
       
  1015 
       
  1016     def has_scripts (self):
       
  1017         return self.scripts and len(self.scripts) > 0
       
  1018 
       
  1019     def has_data_files (self):
       
  1020         return self.data_files and len(self.data_files) > 0
       
  1021 
       
  1022     def is_pure (self):
       
  1023         return (self.has_pure_modules() and
       
  1024                 not self.has_ext_modules() and
       
  1025                 not self.has_c_libraries())
       
  1026 
       
  1027     # -- Metadata query methods ----------------------------------------
       
  1028 
       
  1029     # If you're looking for 'get_name()', 'get_version()', and so forth,
       
  1030     # they are defined in a sneaky way: the constructor binds self.get_XXX
       
  1031     # to self.metadata.get_XXX.  The actual code is in the
       
  1032     # DistributionMetadata class, below.
       
  1033 
       
  1034 # class Distribution
       
  1035 
       
  1036 
       
  1037 class DistributionMetadata:
       
  1038     """Dummy class to hold the distribution meta-data: name, version,
       
  1039     author, and so forth.
       
  1040     """
       
  1041 
       
  1042     _METHOD_BASENAMES = ("name", "version", "author", "author_email",
       
  1043                          "maintainer", "maintainer_email", "url",
       
  1044                          "license", "description", "long_description",
       
  1045                          "keywords", "platforms", "fullname", "contact",
       
  1046                          "contact_email", "license", "classifiers",
       
  1047                          "download_url",
       
  1048                          # PEP 314
       
  1049                          "provides", "requires", "obsoletes",
       
  1050                          )
       
  1051 
       
  1052     def __init__ (self):
       
  1053         self.name = None
       
  1054         self.version = None
       
  1055         self.author = None
       
  1056         self.author_email = None
       
  1057         self.maintainer = None
       
  1058         self.maintainer_email = None
       
  1059         self.url = None
       
  1060         self.license = None
       
  1061         self.description = None
       
  1062         self.long_description = None
       
  1063         self.keywords = None
       
  1064         self.platforms = None
       
  1065         self.classifiers = None
       
  1066         self.download_url = None
       
  1067         # PEP 314
       
  1068         self.provides = None
       
  1069         self.requires = None
       
  1070         self.obsoletes = None
       
  1071 
       
  1072     def write_pkg_info (self, base_dir):
       
  1073         """Write the PKG-INFO file into the release tree.
       
  1074         """
       
  1075         pkg_info = open( os.path.join(base_dir, 'PKG-INFO'), 'w')
       
  1076 
       
  1077         self.write_pkg_file(pkg_info)
       
  1078 
       
  1079         pkg_info.close()
       
  1080 
       
  1081     # write_pkg_info ()
       
  1082 
       
  1083     def write_pkg_file (self, file):
       
  1084         """Write the PKG-INFO format data to a file object.
       
  1085         """
       
  1086         version = '1.0'
       
  1087         if self.provides or self.requires or self.obsoletes:
       
  1088             version = '1.1'
       
  1089 
       
  1090         self._write_field(file, 'Metadata-Version', version)
       
  1091         self._write_field(file, 'Name', self.get_name())
       
  1092         self._write_field(file, 'Version', self.get_version())
       
  1093         self._write_field(file, 'Summary', self.get_description())
       
  1094         self._write_field(file, 'Home-page', self.get_url())
       
  1095         self._write_field(file, 'Author', self.get_contact())
       
  1096         self._write_field(file, 'Author-email', self.get_contact_email())
       
  1097         self._write_field(file, 'License', self.get_license())
       
  1098         if self.download_url:
       
  1099             self._write_field(file, 'Download-URL', self.download_url)
       
  1100 
       
  1101         long_desc = rfc822_escape( self.get_long_description())
       
  1102         self._write_field(file, 'Description', long_desc)
       
  1103 
       
  1104         keywords = string.join( self.get_keywords(), ',')
       
  1105         if keywords:
       
  1106             self._write_field(file, 'Keywords', keywords)
       
  1107 
       
  1108         self._write_list(file, 'Platform', self.get_platforms())
       
  1109         self._write_list(file, 'Classifier', self.get_classifiers())
       
  1110 
       
  1111         # PEP 314
       
  1112         self._write_list(file, 'Requires', self.get_requires())
       
  1113         self._write_list(file, 'Provides', self.get_provides())
       
  1114         self._write_list(file, 'Obsoletes', self.get_obsoletes())
       
  1115 
       
  1116     def _write_field(self, file, name, value):
       
  1117 
       
  1118         if isinstance(value, unicode):
       
  1119             value = value.encode(PKG_INFO_ENCODING)
       
  1120         else:
       
  1121             value = str(value)
       
  1122         file.write('%s: %s\n' % (name, value))
       
  1123 
       
  1124     def _write_list (self, file, name, values):
       
  1125 
       
  1126         for value in values:
       
  1127             self._write_field(file, name, value)
       
  1128 
       
  1129     # -- Metadata query methods ----------------------------------------
       
  1130 
       
  1131     def get_name (self):
       
  1132         return self.name or "UNKNOWN"
       
  1133 
       
  1134     def get_version(self):
       
  1135         return self.version or "0.0.0"
       
  1136 
       
  1137     def get_fullname (self):
       
  1138         return "%s-%s" % (self.get_name(), self.get_version())
       
  1139 
       
  1140     def get_author(self):
       
  1141         return self.author or "UNKNOWN"
       
  1142 
       
  1143     def get_author_email(self):
       
  1144         return self.author_email or "UNKNOWN"
       
  1145 
       
  1146     def get_maintainer(self):
       
  1147         return self.maintainer or "UNKNOWN"
       
  1148 
       
  1149     def get_maintainer_email(self):
       
  1150         return self.maintainer_email or "UNKNOWN"
       
  1151 
       
  1152     def get_contact(self):
       
  1153         return (self.maintainer or
       
  1154                 self.author or
       
  1155                 "UNKNOWN")
       
  1156 
       
  1157     def get_contact_email(self):
       
  1158         return (self.maintainer_email or
       
  1159                 self.author_email or
       
  1160                 "UNKNOWN")
       
  1161 
       
  1162     def get_url(self):
       
  1163         return self.url or "UNKNOWN"
       
  1164 
       
  1165     def get_license(self):
       
  1166         return self.license or "UNKNOWN"
       
  1167     get_licence = get_license
       
  1168 
       
  1169     def get_description(self):
       
  1170         return self.description or "UNKNOWN"
       
  1171 
       
  1172     def get_long_description(self):
       
  1173         return self.long_description or "UNKNOWN"
       
  1174 
       
  1175     def get_keywords(self):
       
  1176         return self.keywords or []
       
  1177 
       
  1178     def get_platforms(self):
       
  1179         return self.platforms or ["UNKNOWN"]
       
  1180 
       
  1181     def get_classifiers(self):
       
  1182         return self.classifiers or []
       
  1183 
       
  1184     def get_download_url(self):
       
  1185         return self.download_url or "UNKNOWN"
       
  1186 
       
  1187     # PEP 314
       
  1188 
       
  1189     def get_requires(self):
       
  1190         return self.requires or []
       
  1191 
       
  1192     def set_requires(self, value):
       
  1193         import distutils.versionpredicate
       
  1194         for v in value:
       
  1195             distutils.versionpredicate.VersionPredicate(v)
       
  1196         self.requires = value
       
  1197 
       
  1198     def get_provides(self):
       
  1199         return self.provides or []
       
  1200 
       
  1201     def set_provides(self, value):
       
  1202         value = [v.strip() for v in value]
       
  1203         for v in value:
       
  1204             import distutils.versionpredicate
       
  1205             distutils.versionpredicate.split_provision(v)
       
  1206         self.provides = value
       
  1207 
       
  1208     def get_obsoletes(self):
       
  1209         return self.obsoletes or []
       
  1210 
       
  1211     def set_obsoletes(self, value):
       
  1212         import distutils.versionpredicate
       
  1213         for v in value:
       
  1214             distutils.versionpredicate.VersionPredicate(v)
       
  1215         self.obsoletes = value
       
  1216 
       
  1217 # class DistributionMetadata
       
  1218 
       
  1219 
       
  1220 def fix_help_options (options):
       
  1221     """Convert a 4-tuple 'help_options' list as found in various command
       
  1222     classes to the 3-tuple form required by FancyGetopt.
       
  1223     """
       
  1224     new_options = []
       
  1225     for help_tuple in options:
       
  1226         new_options.append(help_tuple[0:3])
       
  1227     return new_options
       
  1228 
       
  1229 
       
  1230 if __name__ == "__main__":
       
  1231     dist = Distribution()
       
  1232     print "ok"