NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

dist.py (28867B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\dist.py
      2 __revision__ = '$Id: dist.py 87602 2011-01-01 04:24:26Z richard.tew $'
      3 import sys, os, re
      4 from email import message_from_file
      5 try:
      6     import warnings
      7 except ImportError:
      8     warnings = None
      9 
     10 from distutils.errors import DistutilsOptionError, DistutilsArgError, DistutilsModuleError, DistutilsClassError
     11 from distutils.fancy_getopt import FancyGetopt, translate_longopt
     12 from distutils.util import check_environ, strtobool, rfc822_escape
     13 from distutils import log
     14 from distutils.debug import DEBUG
     15 PKG_INFO_ENCODING = 'utf-8'
     16 command_re = re.compile('^[a-zA-Z]([a-zA-Z0-9_]*)$')
     17 
     18 class Distribution():
     19     global_options = [('verbose', 'v', 'run verbosely (default)', 1),
     20      ('quiet', 'q', 'run quietly (turns verbosity off)'),
     21      ('dry-run', 'n', "don't actually do anything"),
     22      ('help', 'h', 'show detailed help message'),
     23      ('no-user-cfg', None, 'ignore pydistutils.cfg in your home directory')]
     24     common_usage = "Common commands: (see '--help-commands' for more)\n\n  setup.py build      will build the package underneath 'build/'\n  setup.py install    will install the package\n"
     25     display_options = [('help-commands', None, 'list all available commands'),
     26      ('name', None, 'print package name'),
     27      ('version', 'V', 'print package version'),
     28      ('fullname', None, 'print <package name>-<version>'),
     29      ('author', None, "print the author's name"),
     30      ('author-email', None, "print the author's email address"),
     31      ('maintainer', None, "print the maintainer's name"),
     32      ('maintainer-email', None, "print the maintainer's email address"),
     33      ('contact', None, "print the maintainer's name if known, else the author's"),
     34      ('contact-email', None, "print the maintainer's email address if known, else the author's"),
     35      ('url', None, 'print the URL for this package'),
     36      ('license', None, 'print the license of the package'),
     37      ('licence', None, 'alias for --license'),
     38      ('description', None, 'print the package description'),
     39      ('long-description', None, 'print the long package description'),
     40      ('platforms', None, 'print the list of platforms'),
     41      ('classifiers', None, 'print the list of classifiers'),
     42      ('keywords', None, 'print the list of keywords'),
     43      ('provides', None, 'print the list of packages/modules provided'),
     44      ('requires', None, 'print the list of packages/modules required'),
     45      ('obsoletes', None, 'print the list of packages/modules made obsolete')]
     46     display_option_names = map(lambda x: translate_longopt(x[0]), display_options)
     47     negative_opt = {'quiet': 'verbose'}
     48 
     49     def __init__(self, attrs = None):
     50         self.verbose = 1
     51         self.dry_run = 0
     52         self.help = 0
     53         for attr in self.display_option_names:
     54             setattr(self, attr, 0)
     55 
     56         self.metadata = DistributionMetadata()
     57         for basename in self.metadata._METHOD_BASENAMES:
     58             method_name = 'get_' + basename
     59             setattr(self, method_name, getattr(self.metadata, method_name))
     60 
     61         self.cmdclass = {}
     62         self.command_packages = None
     63         self.script_name = None
     64         self.script_args = None
     65         self.command_options = {}
     66         self.dist_files = []
     67         self.packages = None
     68         self.package_data = {}
     69         self.package_dir = None
     70         self.py_modules = None
     71         self.libraries = None
     72         self.headers = None
     73         self.ext_modules = None
     74         self.ext_package = None
     75         self.include_dirs = None
     76         self.extra_path = None
     77         self.scripts = None
     78         self.data_files = None
     79         self.password = ''
     80         self.command_obj = {}
     81         self.have_run = {}
     82         if attrs:
     83             options = attrs.get('options')
     84             if options is not None:
     85                 del attrs['options']
     86                 for command, cmd_options in options.items():
     87                     opt_dict = self.get_option_dict(command)
     88                     for opt, val in cmd_options.items():
     89                         opt_dict[opt] = ('setup script', val)
     90 
     91             if 'licence' in attrs:
     92                 attrs['license'] = attrs['licence']
     93                 del attrs['licence']
     94                 msg = "'licence' distribution option is deprecated; use 'license'"
     95                 if warnings is not None:
     96                     warnings.warn(msg)
     97                 else:
     98                     sys.stderr.write(msg + '\n')
     99             for key, val in attrs.items():
    100                 if hasattr(self.metadata, 'set_' + key):
    101                     getattr(self.metadata, 'set_' + key)(val)
    102                 elif hasattr(self.metadata, key):
    103                     setattr(self.metadata, key, val)
    104                 elif hasattr(self, key):
    105                     setattr(self, key, val)
    106                 else:
    107                     msg = 'Unknown distribution option: %s' % repr(key)
    108                     if warnings is not None:
    109                         warnings.warn(msg)
    110                     else:
    111                         sys.stderr.write(msg + '\n')
    112 
    113         self.want_user_cfg = True
    114         if self.script_args is not None:
    115             for arg in self.script_args:
    116                 if not arg.startswith('-'):
    117                     break
    118                 if arg == '--no-user-cfg':
    119                     self.want_user_cfg = False
    120                     break
    121 
    122         self.finalize_options()
    123 
    124     def get_option_dict(self, command):
    125         dict = self.command_options.get(command)
    126         if dict is None:
    127             dict = self.command_options[command] = {}
    128         return dict
    129 
    130     def dump_option_dicts(self, header = None, commands = None, indent = ''):
    131         from pprint import pformat
    132         if commands is None:
    133             commands = self.command_options.keys()
    134             commands.sort()
    135         if header is not None:
    136             self.announce(indent + header)
    137             indent = indent + '  '
    138         if not commands:
    139             self.announce(indent + 'no commands known yet')
    140             return
    141         for cmd_name in commands:
    142             opt_dict = self.command_options.get(cmd_name)
    143             if opt_dict is None:
    144                 self.announce(indent + "no option dict for '%s' command" % cmd_name)
    145             else:
    146                 self.announce(indent + "option dict for '%s' command:" % cmd_name)
    147                 out = pformat(opt_dict)
    148                 for line in out.split('\n'):
    149                     self.announce(indent + '  ' + line)
    150 
    151     def find_config_files(self):
    152         files = []
    153         check_environ()
    154         sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
    155         sys_file = os.path.join(sys_dir, 'distutils.cfg')
    156         if os.path.isfile(sys_file):
    157             files.append(sys_file)
    158         if os.name == 'posix':
    159             user_filename = '.pydistutils.cfg'
    160         else:
    161             user_filename = 'pydistutils.cfg'
    162         if self.want_user_cfg:
    163             user_file = os.path.join(os.path.expanduser('~'), user_filename)
    164             if os.path.isfile(user_file):
    165                 files.append(user_file)
    166         local_file = 'setup.cfg'
    167         if os.path.isfile(local_file):
    168             files.append(local_file)
    169         if DEBUG:
    170             self.announce('using config files: %s' % ', '.join(files))
    171         return files
    172 
    173     def parse_config_files(self, filenames = None):
    174         from ConfigParser import ConfigParser
    175         if filenames is None:
    176             filenames = self.find_config_files()
    177         if DEBUG:
    178             self.announce('Distribution.parse_config_files():')
    179         parser = ConfigParser()
    180         for filename in filenames:
    181             if DEBUG:
    182                 self.announce('  reading %s' % filename)
    183             parser.read(filename)
    184             for section in parser.sections():
    185                 options = parser.options(section)
    186                 opt_dict = self.get_option_dict(section)
    187                 for opt in options:
    188                     if opt != '__name__':
    189                         val = parser.get(section, opt)
    190                         opt = opt.replace('-', '_')
    191                         opt_dict[opt] = (filename, val)
    192 
    193             parser.__init__()
    194 
    195         if 'global' in self.command_options:
    196             for opt, (src, val) in self.command_options['global'].items():
    197                 alias = self.negative_opt.get(opt)
    198                 try:
    199                     if alias:
    200                         setattr(self, alias, not strtobool(val))
    201                     elif opt in ('verbose', 'dry_run'):
    202                         setattr(self, opt, strtobool(val))
    203                     else:
    204                         setattr(self, opt, val)
    205                 except ValueError as msg:
    206                     raise DistutilsOptionError, msg
    207 
    208     def parse_command_line(self):
    209         toplevel_options = self._get_toplevel_options()
    210         self.commands = []
    211         parser = FancyGetopt(toplevel_options + self.display_options)
    212         parser.set_negative_aliases(self.negative_opt)
    213         parser.set_aliases({'licence': 'license'})
    214         args = parser.getopt(args=self.script_args, object=self)
    215         option_order = parser.get_option_order()
    216         log.set_verbosity(self.verbose)
    217         if self.handle_display_options(option_order):
    218             return
    219         while args:
    220             args = self._parse_command_opts(parser, args)
    221             if args is None:
    222                 return
    223 
    224         if self.help:
    225             self._show_help(parser, display_options=len(self.commands) == 0, commands=self.commands)
    226             return
    227         if not self.commands:
    228             raise DistutilsArgError, 'no commands supplied'
    229         return 1
    230 
    231     def _get_toplevel_options(self):
    232         return self.global_options + [('command-packages=', None, 'list of packages that provide distutils commands')]
    233 
    234     def _parse_command_opts(self, parser, args):
    235         from distutils.cmd import Command
    236         command = args[0]
    237         if not command_re.match(command):
    238             raise SystemExit, "invalid command name '%s'" % command
    239         self.commands.append(command)
    240         try:
    241             cmd_class = self.get_command_class(command)
    242         except DistutilsModuleError as msg:
    243             raise DistutilsArgError, msg
    244 
    245         if not issubclass(cmd_class, Command):
    246             raise DistutilsClassError, 'command class %s must subclass Command' % cmd_class
    247         if not (hasattr(cmd_class, 'user_options') and isinstance(cmd_class.user_options, list)):
    248             raise DistutilsClassError, ('command class %s must provide ' + "'user_options' attribute (a list of tuples)") % cmd_class
    249         negative_opt = self.negative_opt
    250         if hasattr(cmd_class, 'negative_opt'):
    251             negative_opt = negative_opt.copy()
    252             negative_opt.update(cmd_class.negative_opt)
    253         if hasattr(cmd_class, 'help_options') and isinstance(cmd_class.help_options, list):
    254             help_options = fix_help_options(cmd_class.help_options)
    255         else:
    256             help_options = []
    257         parser.set_option_table(self.global_options + cmd_class.user_options + help_options)
    258         parser.set_negative_aliases(negative_opt)
    259         args, opts = parser.getopt(args[1:])
    260         if hasattr(opts, 'help') and opts.help:
    261             self._show_help(parser, display_options=0, commands=[cmd_class])
    262             return
    263         if hasattr(cmd_class, 'help_options') and isinstance(cmd_class.help_options, list):
    264             help_option_found = 0
    265             for help_option, short, desc, func in cmd_class.help_options:
    266                 if hasattr(opts, parser.get_attr_name(help_option)):
    267                     help_option_found = 1
    268                     if hasattr(func, '__call__'):
    269                         func()
    270                     else:
    271                         raise DistutilsClassError("invalid help function %r for help option '%s': must be a callable object (function, etc.)" % (func, help_option))
    272 
    273             if help_option_found:
    274                 return
    275         opt_dict = self.get_option_dict(command)
    276         for name, value in vars(opts).items():
    277             opt_dict[name] = ('command line', value)
    278 
    279         return args
    280 
    281     def finalize_options(self):
    282         for attr in ('keywords', 'platforms'):
    283             value = getattr(self.metadata, attr)
    284             if value is None:
    285                 continue
    286             if isinstance(value, str):
    287                 value = [ elm.strip() for elm in value.split(',') ]
    288                 setattr(self.metadata, attr, value)
    289 
    290     def _show_help(self, parser, global_options = 1, display_options = 1, commands = []):
    291         from distutils.core import gen_usage
    292         from distutils.cmd import Command
    293         if global_options:
    294             if display_options:
    295                 options = self._get_toplevel_options()
    296             else:
    297                 options = self.global_options
    298             parser.set_option_table(options)
    299             parser.print_help(self.common_usage + '\nGlobal options:')
    300             print ''
    301         if display_options:
    302             parser.set_option_table(self.display_options)
    303             parser.print_help('Information display options (just display ' + 'information, ignore any commands)')
    304             print ''
    305         for command in self.commands:
    306             if isinstance(command, type) and issubclass(command, Command):
    307                 klass = command
    308             else:
    309                 klass = self.get_command_class(command)
    310             if hasattr(klass, 'help_options') and isinstance(klass.help_options, list):
    311                 parser.set_option_table(klass.user_options + fix_help_options(klass.help_options))
    312             else:
    313                 parser.set_option_table(klass.user_options)
    314             parser.print_help("Options for '%s' command:" % klass.__name__)
    315             print ''
    316 
    317         print gen_usage(self.script_name)
    318 
    319     def handle_display_options(self, option_order):
    320         from distutils.core import gen_usage
    321         if self.help_commands:
    322             self.print_commands()
    323             print ''
    324             print gen_usage(self.script_name)
    325             return 1
    326         any_display_options = 0
    327         is_display_option = {}
    328         for option in self.display_options:
    329             is_display_option[option[0]] = 1
    330 
    331         for opt, val in option_order:
    332             if val and is_display_option.get(opt):
    333                 opt = translate_longopt(opt)
    334                 value = getattr(self.metadata, 'get_' + opt)()
    335                 if opt in ('keywords', 'platforms'):
    336                     print ','.join(value)
    337                 elif opt in ('classifiers', 'provides', 'requires', 'obsoletes'):
    338                     print '\n'.join(value)
    339                 else:
    340                     print value
    341                 any_display_options = 1
    342 
    343         return any_display_options
    344 
    345     def print_command_list(self, commands, header, max_length):
    346         print header + ':'
    347         for cmd in commands:
    348             klass = self.cmdclass.get(cmd)
    349             if not klass:
    350                 klass = self.get_command_class(cmd)
    351             try:
    352                 description = klass.description
    353             except AttributeError:
    354                 description = '(no description available)'
    355 
    356             print '  %-*s  %s' % (max_length, cmd, description)
    357 
    358     def print_commands(self):
    359         import distutils.command
    360         std_commands = distutils.command.__all__
    361         is_std = {}
    362         for cmd in std_commands:
    363             is_std[cmd] = 1
    364 
    365         extra_commands = []
    366         for cmd in self.cmdclass.keys():
    367             if not is_std.get(cmd):
    368                 extra_commands.append(cmd)
    369 
    370         max_length = 0
    371         for cmd in std_commands + extra_commands:
    372             if len(cmd) > max_length:
    373                 max_length = len(cmd)
    374 
    375         self.print_command_list(std_commands, 'Standard commands', max_length)
    376         if extra_commands:
    377             print
    378             self.print_command_list(extra_commands, 'Extra commands', max_length)
    379 
    380     def get_command_list(self):
    381         import distutils.command
    382         std_commands = distutils.command.__all__
    383         is_std = {}
    384         for cmd in std_commands:
    385             is_std[cmd] = 1
    386 
    387         extra_commands = []
    388         for cmd in self.cmdclass.keys():
    389             if not is_std.get(cmd):
    390                 extra_commands.append(cmd)
    391 
    392         rv = []
    393         for cmd in std_commands + extra_commands:
    394             klass = self.cmdclass.get(cmd)
    395             if not klass:
    396                 klass = self.get_command_class(cmd)
    397             try:
    398                 description = klass.description
    399             except AttributeError:
    400                 description = '(no description available)'
    401 
    402             rv.append((cmd, description))
    403 
    404         return rv
    405 
    406     def get_command_packages(self):
    407         pkgs = self.command_packages
    408         if not isinstance(pkgs, list):
    409             if pkgs is None:
    410                 pkgs = ''
    411             pkgs = [ pkg.strip() for pkg in pkgs.split(',') if pkg != '' ]
    412             if 'distutils.command' not in pkgs:
    413                 pkgs.insert(0, 'distutils.command')
    414             self.command_packages = pkgs
    415         return pkgs
    416 
    417     def get_command_class(self, command):
    418         klass = self.cmdclass.get(command)
    419         if klass:
    420             return klass
    421         for pkgname in self.get_command_packages():
    422             module_name = '%s.%s' % (pkgname, command)
    423             klass_name = command
    424             try:
    425                 __import__(module_name)
    426                 module = sys.modules[module_name]
    427             except ImportError:
    428                 continue
    429 
    430             try:
    431                 klass = getattr(module, klass_name)
    432             except AttributeError:
    433                 raise DistutilsModuleError, "invalid command '%s' (no class '%s' in module '%s')" % (command, klass_name, module_name)
    434 
    435             self.cmdclass[command] = klass
    436             return klass
    437 
    438         raise DistutilsModuleError("invalid command '%s'" % command)
    439 
    440     def get_command_obj(self, command, create = 1):
    441         cmd_obj = self.command_obj.get(command)
    442         if not cmd_obj and create:
    443             if DEBUG:
    444                 self.announce("Distribution.get_command_obj(): creating '%s' command object" % command)
    445             klass = self.get_command_class(command)
    446             cmd_obj = self.command_obj[command] = klass(self)
    447             self.have_run[command] = 0
    448             options = self.command_options.get(command)
    449             if options:
    450                 self._set_command_options(cmd_obj, options)
    451         return cmd_obj
    452 
    453     def _set_command_options(self, command_obj, option_dict = None):
    454         command_name = command_obj.get_command_name()
    455         if option_dict is None:
    456             option_dict = self.get_option_dict(command_name)
    457         if DEBUG:
    458             self.announce("  setting options for '%s' command:" % command_name)
    459         for option, (source, value) in option_dict.items():
    460             if DEBUG:
    461                 self.announce('    %s = %s (from %s)' % (option, value, source))
    462             try:
    463                 bool_opts = map(translate_longopt, command_obj.boolean_options)
    464             except AttributeError:
    465                 bool_opts = []
    466 
    467             try:
    468                 neg_opt = command_obj.negative_opt
    469             except AttributeError:
    470                 neg_opt = {}
    471 
    472             try:
    473                 is_string = isinstance(value, str)
    474                 if option in neg_opt and is_string:
    475                     setattr(command_obj, neg_opt[option], not strtobool(value))
    476                 elif option in bool_opts and is_string:
    477                     setattr(command_obj, option, strtobool(value))
    478                 elif hasattr(command_obj, option):
    479                     setattr(command_obj, option, value)
    480                 else:
    481                     raise DistutilsOptionError, "error in %s: command '%s' has no such option '%s'" % (source, command_name, option)
    482             except ValueError as msg:
    483                 raise DistutilsOptionError, msg
    484 
    485     def reinitialize_command(self, command, reinit_subcommands = 0):
    486         from distutils.cmd import Command
    487         if not isinstance(command, Command):
    488             command_name = command
    489             command = self.get_command_obj(command_name)
    490         else:
    491             command_name = command.get_command_name()
    492         if not command.finalized:
    493             return command
    494         command.initialize_options()
    495         command.finalized = 0
    496         self.have_run[command_name] = 0
    497         self._set_command_options(command)
    498         if reinit_subcommands:
    499             for sub in command.get_sub_commands():
    500                 self.reinitialize_command(sub, reinit_subcommands)
    501 
    502         return command
    503 
    504     def announce(self, msg, level = log.INFO):
    505         log.log(level, msg)
    506 
    507     def run_commands(self):
    508         for cmd in self.commands:
    509             self.run_command(cmd)
    510 
    511     def run_command(self, command):
    512         if self.have_run.get(command):
    513             return
    514         log.info('running %s', command)
    515         cmd_obj = self.get_command_obj(command)
    516         cmd_obj.ensure_finalized()
    517         cmd_obj.run()
    518         self.have_run[command] = 1
    519 
    520     def has_pure_modules(self):
    521         return len(self.packages or self.py_modules or []) > 0
    522 
    523     def has_ext_modules(self):
    524         return self.ext_modules and len(self.ext_modules) > 0
    525 
    526     def has_c_libraries(self):
    527         return self.libraries and len(self.libraries) > 0
    528 
    529     def has_modules(self):
    530         return self.has_pure_modules() or self.has_ext_modules()
    531 
    532     def has_headers(self):
    533         return self.headers and len(self.headers) > 0
    534 
    535     def has_scripts(self):
    536         return self.scripts and len(self.scripts) > 0
    537 
    538     def has_data_files(self):
    539         return self.data_files and len(self.data_files) > 0
    540 
    541     def is_pure(self):
    542         return self.has_pure_modules() and not self.has_ext_modules() and not self.has_c_libraries()
    543 
    544 
    545 class DistributionMetadata():
    546     _METHOD_BASENAMES = ('name', 'version', 'author', 'author_email', 'maintainer', 'maintainer_email', 'url', 'license', 'description', 'long_description', 'keywords', 'platforms', 'fullname', 'contact', 'contact_email', 'license', 'classifiers', 'download_url', 'provides', 'requires', 'obsoletes')
    547 
    548     def __init__(self, path = None):
    549         if path is not None:
    550             self.read_pkg_file(open(path))
    551         else:
    552             self.name = None
    553             self.version = None
    554             self.author = None
    555             self.author_email = None
    556             self.maintainer = None
    557             self.maintainer_email = None
    558             self.url = None
    559             self.license = None
    560             self.description = None
    561             self.long_description = None
    562             self.keywords = None
    563             self.platforms = None
    564             self.classifiers = None
    565             self.download_url = None
    566             self.provides = None
    567             self.requires = None
    568             self.obsoletes = None
    569 
    570     def read_pkg_file(self, file):
    571         msg = message_from_file(file)
    572 
    573         def _read_field(name):
    574             value = msg[name]
    575             if value == 'UNKNOWN':
    576                 return None
    577             return value
    578 
    579         def _read_list(name):
    580             values = msg.get_all(name, None)
    581             if values == []:
    582                 return
    583             return values
    584 
    585         metadata_version = msg['metadata-version']
    586         self.name = _read_field('name')
    587         self.version = _read_field('version')
    588         self.description = _read_field('summary')
    589         self.author = _read_field('author')
    590         self.maintainer = None
    591         self.author_email = _read_field('author-email')
    592         self.maintainer_email = None
    593         self.url = _read_field('home-page')
    594         self.license = _read_field('license')
    595         if 'download-url' in msg:
    596             self.download_url = _read_field('download-url')
    597         else:
    598             self.download_url = None
    599         self.long_description = _read_field('description')
    600         self.description = _read_field('summary')
    601         if 'keywords' in msg:
    602             self.keywords = _read_field('keywords').split(',')
    603         self.platforms = _read_list('platform')
    604         self.classifiers = _read_list('classifier')
    605         if metadata_version == '1.1':
    606             self.requires = _read_list('requires')
    607             self.provides = _read_list('provides')
    608             self.obsoletes = _read_list('obsoletes')
    609         else:
    610             self.requires = None
    611             self.provides = None
    612             self.obsoletes = None
    613 
    614     def write_pkg_info(self, base_dir):
    615         pkg_info = open(os.path.join(base_dir, 'PKG-INFO'), 'w')
    616         try:
    617             self.write_pkg_file(pkg_info)
    618         finally:
    619             pkg_info.close()
    620 
    621     def write_pkg_file(self, file):
    622         version = '1.0'
    623         if self.provides or self.requires or self.obsoletes:
    624             version = '1.1'
    625         self._write_field(file, 'Metadata-Version', version)
    626         self._write_field(file, 'Name', self.get_name())
    627         self._write_field(file, 'Version', self.get_version())
    628         self._write_field(file, 'Summary', self.get_description())
    629         self._write_field(file, 'Home-page', self.get_url())
    630         self._write_field(file, 'Author', self.get_contact())
    631         self._write_field(file, 'Author-email', self.get_contact_email())
    632         self._write_field(file, 'License', self.get_license())
    633         if self.download_url:
    634             self._write_field(file, 'Download-URL', self.download_url)
    635         long_desc = rfc822_escape(self.get_long_description())
    636         self._write_field(file, 'Description', long_desc)
    637         keywords = ','.join(self.get_keywords())
    638         if keywords:
    639             self._write_field(file, 'Keywords', keywords)
    640         self._write_list(file, 'Platform', self.get_platforms())
    641         self._write_list(file, 'Classifier', self.get_classifiers())
    642         self._write_list(file, 'Requires', self.get_requires())
    643         self._write_list(file, 'Provides', self.get_provides())
    644         self._write_list(file, 'Obsoletes', self.get_obsoletes())
    645 
    646     def _write_field(self, file, name, value):
    647         file.write('%s: %s\n' % (name, self._encode_field(value)))
    648 
    649     def _write_list(self, file, name, values):
    650         for value in values:
    651             self._write_field(file, name, value)
    652 
    653     def _encode_field(self, value):
    654         if value is None:
    655             return
    656         if isinstance(value, unicode):
    657             return value.encode(PKG_INFO_ENCODING)
    658         return str(value)
    659 
    660     def get_name(self):
    661         return self.name or 'UNKNOWN'
    662 
    663     def get_version(self):
    664         return self.version or '0.0.0'
    665 
    666     def get_fullname(self):
    667         return '%s-%s' % (self.get_name(), self.get_version())
    668 
    669     def get_author(self):
    670         return self._encode_field(self.author) or 'UNKNOWN'
    671 
    672     def get_author_email(self):
    673         return self.author_email or 'UNKNOWN'
    674 
    675     def get_maintainer(self):
    676         return self._encode_field(self.maintainer) or 'UNKNOWN'
    677 
    678     def get_maintainer_email(self):
    679         return self.maintainer_email or 'UNKNOWN'
    680 
    681     def get_contact(self):
    682         return self._encode_field(self.maintainer) or self._encode_field(self.author) or 'UNKNOWN'
    683 
    684     def get_contact_email(self):
    685         return self.maintainer_email or self.author_email or 'UNKNOWN'
    686 
    687     def get_url(self):
    688         return self.url or 'UNKNOWN'
    689 
    690     def get_license(self):
    691         return self.license or 'UNKNOWN'
    692 
    693     get_licence = get_license
    694 
    695     def get_description(self):
    696         return self._encode_field(self.description) or 'UNKNOWN'
    697 
    698     def get_long_description(self):
    699         return self._encode_field(self.long_description) or 'UNKNOWN'
    700 
    701     def get_keywords(self):
    702         return self.keywords or []
    703 
    704     def get_platforms(self):
    705         return self.platforms or ['UNKNOWN']
    706 
    707     def get_classifiers(self):
    708         return self.classifiers or []
    709 
    710     def get_download_url(self):
    711         return self.download_url or 'UNKNOWN'
    712 
    713     def get_requires(self):
    714         return self.requires or []
    715 
    716     def set_requires(self, value):
    717         import distutils.versionpredicate
    718         for v in value:
    719             distutils.versionpredicate.VersionPredicate(v)
    720 
    721         self.requires = value
    722 
    723     def get_provides(self):
    724         return self.provides or []
    725 
    726     def set_provides(self, value):
    727         value = [ v.strip() for v in value ]
    728         for v in value:
    729             import distutils.versionpredicate
    730             distutils.versionpredicate.split_provision(v)
    731 
    732         self.provides = value
    733 
    734     def get_obsoletes(self):
    735         return self.obsoletes or []
    736 
    737     def set_obsoletes(self, value):
    738         import distutils.versionpredicate
    739         for v in value:
    740             distutils.versionpredicate.VersionPredicate(v)
    741 
    742         self.obsoletes = value
    743 
    744 
    745 def fix_help_options(options):
    746     new_options = []
    747     for help_tuple in options:
    748         new_options.append(help_tuple[0:3])
    749 
    750     return new_options