Changeset 391 for python/trunk/Lib/distutils/dist.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/distutils/dist.py
r2 r391 5 5 """ 6 6 7 # This module should be kept compatible with Python 2.1. 8 9 __revision__ = "$Id: dist.py 77719 2010-01-24 00:57:20Z tarek.ziade $" 10 11 import sys, os, string, re 12 from types import * 13 from copy import copy 7 __revision__ = "$Id$" 8 9 import sys, os, re 10 from email import message_from_file 14 11 15 12 try: … … 18 15 warnings = None 19 16 20 from distutils.errors import * 17 from distutils.errors import (DistutilsOptionError, DistutilsArgError, 18 DistutilsModuleError, DistutilsClassError) 21 19 from distutils.fancy_getopt import FancyGetopt, translate_longopt 22 20 from distutils.util import check_environ, strtobool, rfc822_escape … … 61 59 ('dry-run', 'n', "don't actually do anything"), 62 60 ('help', 'h', "show detailed help message"), 63 ] 61 ('no-user-cfg', None, 62 'ignore pydistutils.cfg in your home directory'), 63 ] 64 64 65 65 # 'common_usage' is a short (2-3 line) string describing the common … … 207 207 self.scripts = None 208 208 self.data_files = None 209 self.password = '' 209 210 210 211 # And now initialize bookkeeping stuff that can't be supplied by … … 254 255 # Now work on the rest of the attributes. Any attribute that's 255 256 # not already defined is invalid! 256 for (key, val) in attrs.items():257 for (key, val) in attrs.items(): 257 258 if hasattr(self.metadata, "set_" + key): 258 259 getattr(self.metadata, "set_" + key)(val) … … 268 269 sys.stderr.write(msg + "\n") 269 270 271 # no-user-cfg is handled before other command line args 272 # because other args override the config files, and this 273 # one is needed before we can load the config files. 274 # If attrs['script_args'] wasn't passed, assume false. 275 # 276 # This also make sure we just look at the global options 277 self.want_user_cfg = True 278 279 if self.script_args is not None: 280 for arg in self.script_args: 281 if not arg.startswith('-'): 282 break 283 if arg == '--no-user-cfg': 284 self.want_user_cfg = False 285 break 286 270 287 self.finalize_options() 271 288 272 # __init__ () 273 274 275 def get_option_dict (self, command): 289 def get_option_dict(self, command): 276 290 """Get the option dictionary for a given command. If that 277 291 command's option dictionary hasn't been created yet, then create it … … 279 293 option dictionary. 280 294 """ 281 282 295 dict = self.command_options.get(command) 283 296 if dict is None: … … 285 298 return dict 286 299 287 288 def dump_option_dicts (self, header=None, commands=None, indent=""): 300 def dump_option_dicts(self, header=None, commands=None, indent=""): 289 301 from pprint import pformat 290 302 … … 294 306 295 307 if header is not None: 296 print indent + header308 self.announce(indent + header) 297 309 indent = indent + " " 298 310 299 311 if not commands: 300 print indent + "no commands known yet"312 self.announce(indent + "no commands known yet") 301 313 return 302 314 … … 304 316 opt_dict = self.command_options.get(cmd_name) 305 317 if opt_dict is None: 306 print indent + "no option dict for '%s' command" % cmd_name 318 self.announce(indent + 319 "no option dict for '%s' command" % cmd_name) 307 320 else: 308 print indent + "option dict for '%s' command:" % cmd_name 321 self.announce(indent + 322 "option dict for '%s' command:" % cmd_name) 309 323 out = pformat(opt_dict) 310 for line in string.split(out, "\n"): 311 print indent + " " + line 312 313 # dump_option_dicts () 314 315 324 for line in out.split('\n'): 325 self.announce(indent + " " + line) 316 326 317 327 # -- Config file finding/parsing methods --------------------------- 318 328 319 def find_config_files 329 def find_config_files(self): 320 330 """Find as many configuration files as should be processed for this 321 331 platform, and return a list of filenames in the order in which they … … 327 337 Distutils __inst__.py file lives), a file in the user's home 328 338 directory named .pydistutils.cfg on Unix and pydistutils.cfg 329 on Windows/Mac, and setup.cfg in the current directory. 339 on Windows/Mac; and setup.cfg in the current directory. 340 341 The file in the user's home directory can be disabled with the 342 --no-user-cfg option. 330 343 """ 331 344 files = [] … … 347 360 348 361 # 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) 362 if self.want_user_cfg: 363 user_file = os.path.join(os.path.expanduser('~'), user_filename) 364 if os.path.isfile(user_file): 365 files.append(user_file) 352 366 353 367 # All platforms support local setup.cfg … … 356 370 files.append(local_file) 357 371 372 if DEBUG: 373 self.announce("using config files: %s" % ', '.join(files)) 374 358 375 return files 359 376 360 # find_config_files () 361 362 363 def parse_config_files (self, filenames=None): 377 def parse_config_files(self, filenames=None): 364 378 from ConfigParser import ConfigParser 365 379 … … 367 381 filenames = self.find_config_files() 368 382 369 if DEBUG: print "Distribution.parse_config_files():" 383 if DEBUG: 384 self.announce("Distribution.parse_config_files():") 370 385 371 386 parser = ConfigParser() 372 387 for filename in filenames: 373 if DEBUG: print " reading", filename 388 if DEBUG: 389 self.announce(" reading %s" % filename) 374 390 parser.read(filename) 375 391 for section in parser.sections(): … … 380 396 if opt != '__name__': 381 397 val = parser.get(section,opt) 382 opt = string.replace(opt,'-', '_')398 opt = opt.replace('-', '_') 383 399 opt_dict[opt] = (filename, val) 384 400 … … 403 419 raise DistutilsOptionError, msg 404 420 405 # parse_config_files ()406 407 408 421 # -- Command-line parsing methods ---------------------------------- 409 422 410 def parse_command_line 423 def parse_command_line(self): 411 424 """Parse the setup script's command line, taken from the 412 425 'script_args' instance attribute (which defaults to 'sys.argv[1:]' … … 432 445 # 433 446 toplevel_options = self._get_toplevel_options() 434 if sys.platform == 'mac':435 import EasyDialogs436 cmdlist = self.get_command_list()437 self.script_args = EasyDialogs.GetArgv(438 toplevel_options + self.display_options, cmdlist)439 447 440 448 # We have to parse the command line a bit at a time -- global … … 456 464 if self.handle_display_options(option_order): 457 465 return 458 459 466 while args: 460 467 args = self._parse_command_opts(parser, args) … … 481 488 return 1 482 489 483 # parse_command_line() 484 485 def _get_toplevel_options (self): 490 def _get_toplevel_options(self): 486 491 """Return the non-display options recognized at the top level. 487 492 … … 494 499 ] 495 500 496 def _parse_command_opts 501 def _parse_command_opts(self, parser, args): 497 502 """Parse the command-line options for a single command. 498 503 'parser' must be a FancyGetopt instance; 'args' must be the list … … 529 534 # known options. 530 535 if not (hasattr(cmd_class, 'user_options') and 531 type(cmd_class.user_options) is ListType):536 isinstance(cmd_class.user_options, list)): 532 537 raise DistutilsClassError, \ 533 538 ("command class %s must provide " + … … 539 544 negative_opt = self.negative_opt 540 545 if hasattr(cmd_class, 'negative_opt'): 541 negative_opt = copy(negative_opt)546 negative_opt = negative_opt.copy() 542 547 negative_opt.update(cmd_class.negative_opt) 543 548 … … 545 550 # format (tuple of four) so we need to preprocess them here. 546 551 if (hasattr(cmd_class, 'help_options') and 547 type(cmd_class.help_options) is ListType):552 isinstance(cmd_class.help_options, list)): 548 553 help_options = fix_help_options(cmd_class.help_options) 549 554 else: … … 563 568 564 569 if (hasattr(cmd_class, 'help_options') and 565 type(cmd_class.help_options) is ListType):570 isinstance(cmd_class.help_options, list)): 566 571 help_option_found=0 567 572 for (help_option, short, desc, func) in cmd_class.help_options: 568 573 if hasattr(opts, parser.get_attr_name(help_option)): 569 574 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): 575 if hasattr(func, '__call__'): 574 576 func() 575 577 else: … … 590 592 return args 591 593 592 # _parse_command_opts () 593 594 def finalize_options (self): 594 def finalize_options(self): 595 595 """Set final values for all the options on the Distribution 596 596 instance, analogous to the .finalize_options() method of Command 597 597 objects. 598 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=[]): 599 for attr in ('keywords', 'platforms'): 600 value = getattr(self.metadata, attr) 601 if value is None: 602 continue 603 if isinstance(value, str): 604 value = [elm.strip() for elm in value.split(',')] 605 setattr(self.metadata, attr, value) 606 607 def _show_help(self, parser, global_options=1, display_options=1, 608 commands=[]): 617 609 """Show help for the setup script command-line in the form of 618 610 several lists of command-line options. 'parser' should be a … … 638 630 parser.set_option_table(options) 639 631 parser.print_help(self.common_usage + "\nGlobal options:") 640 print 632 print('') 641 633 642 634 if display_options: … … 645 637 "Information display options (just display " + 646 638 "information, ignore any commands)") 647 print 639 print('') 648 640 649 641 for command in self.commands: 650 if type(command) is ClassTypeand issubclass(command, Command):642 if isinstance(command, type) and issubclass(command, Command): 651 643 klass = command 652 644 else: 653 645 klass = self.get_command_class(command) 654 646 if (hasattr(klass, 'help_options') and 655 type(klass.help_options) is ListType):647 isinstance(klass.help_options, list)): 656 648 parser.set_option_table(klass.user_options + 657 649 fix_help_options(klass.help_options)) … … 659 651 parser.set_option_table(klass.user_options) 660 652 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): 653 print('') 654 655 print(gen_usage(self.script_name)) 656 657 def handle_display_options(self, option_order): 670 658 """If there were any non-global "display-only" options 671 659 (--help-commands or the metadata display options) on the command … … 680 668 if self.help_commands: 681 669 self.print_commands() 682 print 683 print gen_usage(self.script_name)670 print('') 671 print(gen_usage(self.script_name)) 684 672 return 1 685 673 … … 697 685 value = getattr(self.metadata, "get_"+opt)() 698 686 if opt in ['keywords', 'platforms']: 699 print string.join(value, ',')687 print(','.join(value)) 700 688 elif opt in ('classifiers', 'provides', 'requires', 701 689 'obsoletes'): 702 print string.join(value, '\n')690 print('\n'.join(value)) 703 691 else: 704 print value692 print(value) 705 693 any_display_options = 1 706 694 707 695 return any_display_options 708 696 709 # handle_display_options() 710 711 def print_command_list (self, commands, header, max_length): 697 def print_command_list(self, commands, header, max_length): 712 698 """Print a subset of the list of all commands -- used by 713 699 'print_commands()'. 714 700 """ 715 716 print header + ":" 701 print(header + ":") 717 702 718 703 for cmd in commands: … … 725 710 description = "(no description available)" 726 711 727 print " %-*s %s" % (max_length, cmd, description) 728 729 # print_command_list () 730 731 732 def print_commands (self): 712 print(" %-*s %s" % (max_length, cmd, description)) 713 714 def print_commands(self): 733 715 """Print out a help message listing all available commands with a 734 716 description of each. The list is divided into "standard commands" … … 738 720 'description'. 739 721 """ 740 741 722 import distutils.command 742 723 std_commands = distutils.command.__all__ … … 764 745 max_length) 765 746 766 # print_commands () 767 768 def get_command_list (self): 747 def get_command_list(self): 769 748 """Get a list of (command, description) tuples. 770 749 The list is divided into "standard commands" (listed in … … 801 780 # -- Command class/object methods ---------------------------------- 802 781 803 def get_command_packages 782 def get_command_packages(self): 804 783 """Return a list of packages from which commands are loaded.""" 805 784 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) 785 if not isinstance(pkgs, list): 786 if pkgs is None: 787 pkgs = '' 788 pkgs = [pkg.strip() for pkg in pkgs.split(',') if pkg != ''] 811 789 if "distutils.command" not in pkgs: 812 790 pkgs.insert(0, "distutils.command") … … 814 792 return pkgs 815 793 816 def get_command_class 794 def get_command_class(self, command): 817 795 """Return the class that implements the Distutils command named by 818 796 'command'. First we check the 'cmdclass' dictionary; if the … … 853 831 854 832 855 # get_command_class () 856 857 def get_command_obj (self, command, create=1): 833 def get_command_obj(self, command, create=1): 858 834 """Return the command object for 'command'. Normally this object 859 835 is cached on a previous call to 'get_command_obj()'; if no command … … 864 840 if not cmd_obj and create: 865 841 if DEBUG: 866 print"Distribution.get_command_obj(): " \867 "creating '%s' command object" % command842 self.announce("Distribution.get_command_obj(): " \ 843 "creating '%s' command object" % command) 868 844 869 845 klass = self.get_command_class(command) … … 882 858 return cmd_obj 883 859 884 def _set_command_options 860 def _set_command_options(self, command_obj, option_dict=None): 885 861 """Set the options for 'command_obj' from 'option_dict'. Basically 886 862 this means copying elements of a dictionary ('option_dict') to … … 895 871 option_dict = self.get_option_dict(command_name) 896 872 897 if DEBUG: print " setting options for '%s' command:" % command_name 873 if DEBUG: 874 self.announce(" setting options for '%s' command:" % command_name) 898 875 for (option, (source, value)) in option_dict.items(): 899 if DEBUG: print " %s = %s (from %s)" % (option, value, source) 876 if DEBUG: 877 self.announce(" %s = %s (from %s)" % (option, value, 878 source)) 900 879 try: 901 880 bool_opts = map(translate_longopt, command_obj.boolean_options) … … 908 887 909 888 try: 910 is_string = type(value) is StringType889 is_string = isinstance(value, str) 911 890 if option in neg_opt and is_string: 912 891 setattr(command_obj, neg_opt[option], not strtobool(value)) … … 922 901 raise DistutilsOptionError, msg 923 902 924 def reinitialize_command 903 def reinitialize_command(self, command, reinit_subcommands=0): 925 904 """Reinitializes a command to the state it was in when first 926 905 returned by 'get_command_obj()': ie., initialized but not yet … … 961 940 return command 962 941 963 964 942 # -- Methods that operate on the Distribution ---------------------- 965 943 966 def announce (self, msg, level=1):967 log. debug(msg)968 969 def run_commands 944 def announce(self, msg, level=log.INFO): 945 log.log(level, msg) 946 947 def run_commands(self): 970 948 """Run each command that was seen on the setup script command line. 971 949 Uses the list of commands found and cache of command objects … … 975 953 self.run_command(cmd) 976 954 977 978 955 # -- Methods that operate on its Commands -------------------------- 979 956 980 def run_command 957 def run_command(self, command): 981 958 """Do whatever it takes to run a command (including nothing at all, 982 959 if the command has already been run). Specifically: if we have … … 999 976 # -- Distribution query methods ------------------------------------ 1000 977 1001 def has_pure_modules 978 def has_pure_modules(self): 1002 979 return len(self.packages or self.py_modules or []) > 0 1003 980 1004 def has_ext_modules 981 def has_ext_modules(self): 1005 982 return self.ext_modules and len(self.ext_modules) > 0 1006 983 1007 def has_c_libraries 984 def has_c_libraries(self): 1008 985 return self.libraries and len(self.libraries) > 0 1009 986 1010 def has_modules 987 def has_modules(self): 1011 988 return self.has_pure_modules() or self.has_ext_modules() 1012 989 1013 def has_headers 990 def has_headers(self): 1014 991 return self.headers and len(self.headers) > 0 1015 992 1016 def has_scripts 993 def has_scripts(self): 1017 994 return self.scripts and len(self.scripts) > 0 1018 995 1019 def has_data_files 996 def has_data_files(self): 1020 997 return self.data_files and len(self.data_files) > 0 1021 998 1022 def is_pure 999 def is_pure(self): 1023 1000 return (self.has_pure_modules() and 1024 1001 not self.has_ext_modules() and … … 1031 1008 # to self.metadata.get_XXX. The actual code is in the 1032 1009 # DistributionMetadata class, below. 1033 1034 # class Distribution1035 1036 1010 1037 1011 class DistributionMetadata: … … 1050 1024 ) 1051 1025 1052 def __init__ (self): 1053 self.name = None 1054 self.version = None 1055 self.author = None 1056 self.author_email = None 1026 def __init__(self, path=None): 1027 if path is not None: 1028 self.read_pkg_file(open(path)) 1029 else: 1030 self.name = None 1031 self.version = None 1032 self.author = None 1033 self.author_email = None 1034 self.maintainer = None 1035 self.maintainer_email = None 1036 self.url = None 1037 self.license = None 1038 self.description = None 1039 self.long_description = None 1040 self.keywords = None 1041 self.platforms = None 1042 self.classifiers = None 1043 self.download_url = None 1044 # PEP 314 1045 self.provides = None 1046 self.requires = None 1047 self.obsoletes = None 1048 1049 def read_pkg_file(self, file): 1050 """Reads the metadata values from a file object.""" 1051 msg = message_from_file(file) 1052 1053 def _read_field(name): 1054 value = msg[name] 1055 if value == 'UNKNOWN': 1056 return None 1057 return value 1058 1059 def _read_list(name): 1060 values = msg.get_all(name, None) 1061 if values == []: 1062 return None 1063 return values 1064 1065 metadata_version = msg['metadata-version'] 1066 self.name = _read_field('name') 1067 self.version = _read_field('version') 1068 self.description = _read_field('summary') 1069 # we are filling author only. 1070 self.author = _read_field('author') 1057 1071 self.maintainer = None 1072 self.author_email = _read_field('author-email') 1058 1073 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): 1074 self.url = _read_field('home-page') 1075 self.license = _read_field('license') 1076 1077 if 'download-url' in msg: 1078 self.download_url = _read_field('download-url') 1079 else: 1080 self.download_url = None 1081 1082 self.long_description = _read_field('description') 1083 self.description = _read_field('summary') 1084 1085 if 'keywords' in msg: 1086 self.keywords = _read_field('keywords').split(',') 1087 1088 self.platforms = _read_list('platform') 1089 self.classifiers = _read_list('classifier') 1090 1091 # PEP 314 - these fields only exist in 1.1 1092 if metadata_version == '1.1': 1093 self.requires = _read_list('requires') 1094 self.provides = _read_list('provides') 1095 self.obsoletes = _read_list('obsoletes') 1096 else: 1097 self.requires = None 1098 self.provides = None 1099 self.obsoletes = None 1100 1101 def write_pkg_info(self, base_dir): 1073 1102 """Write the PKG-INFO file into the release tree. 1074 1103 """ 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): 1104 pkg_info = open(os.path.join(base_dir, 'PKG-INFO'), 'w') 1105 try: 1106 self.write_pkg_file(pkg_info) 1107 finally: 1108 pkg_info.close() 1109 1110 def write_pkg_file(self, file): 1084 1111 """Write the PKG-INFO format data to a file object. 1085 1112 """ 1086 1113 version = '1.0' 1087 if self.provides or self.requires or self.obsoletes: 1114 if (self.provides or self.requires or self.obsoletes or 1115 self.classifiers or self.download_url): 1088 1116 version = '1.1' 1089 1117 … … 1099 1127 self._write_field(file, 'Download-URL', self.download_url) 1100 1128 1101 long_desc = rfc822_escape( 1129 long_desc = rfc822_escape(self.get_long_description()) 1102 1130 self._write_field(file, 'Description', long_desc) 1103 1131 1104 keywords = string.join( self.get_keywords(), ',')1132 keywords = ','.join(self.get_keywords()) 1105 1133 if keywords: 1106 1134 self._write_field(file, 'Keywords', keywords) … … 1118 1146 1119 1147 def _write_list (self, file, name, values): 1120 1121 1148 for value in values: 1122 1149 self._write_field(file, name, value) … … 1131 1158 # -- Metadata query methods ---------------------------------------- 1132 1159 1133 def get_name 1160 def get_name(self): 1134 1161 return self.name or "UNKNOWN" 1135 1162 … … 1137 1164 return self.version or "0.0.0" 1138 1165 1139 def get_fullname 1166 def get_fullname(self): 1140 1167 return "%s-%s" % (self.get_name(), self.get_version()) 1141 1168 … … 1157 1184 1158 1185 def get_contact_email(self): 1159 return (self.maintainer_email or 1160 self.author_email or 1161 "UNKNOWN") 1186 return self.maintainer_email or self.author_email or "UNKNOWN" 1162 1187 1163 1188 def get_url(self): … … 1187 1212 1188 1213 # PEP 314 1189 1190 1214 def get_requires(self): 1191 1215 return self.requires or [] … … 1216 1240 self.obsoletes = value 1217 1241 1218 # class DistributionMetadata 1219 1220 1221 def fix_help_options (options): 1242 def fix_help_options(options): 1222 1243 """Convert a 4-tuple 'help_options' list as found in various command 1223 1244 classes to the 3-tuple form required by FancyGetopt. … … 1227 1248 new_options.append(help_tuple[0:3]) 1228 1249 return new_options 1229 1230 1231 if __name__ == "__main__":1232 dist = Distribution()1233 print "ok"
Note:
See TracChangeset
for help on using the changeset viewer.