| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| 1 """Access to Python's configuration information.""" | 1 """Access to Python's configuration information.""" |
| 2 | |
| 3 import os | 2 import os |
| 4 import re | 3 import re |
| 5 import sys | 4 import sys |
| 6 from os.path import pardir, realpath | 5 from os.path import pardir, realpath |
| 7 from configparser import RawConfigParser | |
| 8 | 6 |
| 9 __all__ = [ | 7 __all__ = [ |
| 10 'get_config_h_filename', | 8 'get_config_h_filename', |
| 11 'get_config_var', | 9 'get_config_var', |
| 12 'get_config_vars', | 10 'get_config_vars', |
| 13 'get_makefile_filename', | 11 'get_makefile_filename', |
| 14 'get_path', | 12 'get_path', |
| 15 'get_path_names', | 13 'get_path_names', |
| 16 'get_paths', | 14 'get_paths', |
| 17 'get_platform', | 15 'get_platform', |
| 18 'get_python_version', | 16 'get_python_version', |
| 19 'get_scheme_names', | 17 'get_scheme_names', |
| 20 'parse_config_h', | 18 'parse_config_h', |
| 21 ] | 19 ] |
| 20 | |
| 21 class SectionProxy: | |
| 22 def __init__(self, parser, name): | |
| 23 self._parser = parser | |
| 24 self._name = name | |
| 25 | |
| 26 def __iter__(self): | |
| 27 return iter(self._parser.options(self._name)) | |
| 28 | |
| 29 class _ConfigParser: | |
| 30 """ | |
| 31 configparser.RawConfigParser copy specialized for sysconfig: | |
| 32 - read-only | |
| 33 - use dict | |
| 34 - only support "#" prefix for comments | |
| 35 - only support "=" option name/value separator | |
| 36 - don't use custom exceptions | |
| 37 """ | |
| 38 | |
| 39 def __init__(self): | |
| 40 self._sections = dict() | |
| 41 self._proxies = dict() | |
| 42 | |
| 43 def sections(self): | |
| 44 return list(self._sections.keys()) | |
| 45 | |
| 46 def add_section(self, section): | |
| 47 if section in self._sections: | |
| 48 raise Exception("Section %s already exists" % section) | |
| 49 self._sections[section] = dict() | |
| 50 self._proxies[section] = SectionProxy(self, section) | |
| 51 | |
| 52 def has_section(self, section): | |
| 53 return section in self._sections | |
| 54 | |
| 55 def options(self, section): | |
| 56 return list(self._sections[section].keys()) | |
| 57 | |
| 58 def items(self, section): | |
| 59 return self._sections[section].items() | |
| 60 | |
| 61 def has_option(self, section, option): | |
| 62 if section not in self._sections: | |
| 63 return False | |
| 64 else: | |
| 65 option = option | |
| 66 return option in self._sections[section] | |
| 67 | |
| 68 def set(self, section, option, value=None): | |
| 69 self._sections[section][option] = value | |
| 70 | |
| 71 def remove_section(self, section): | |
| 72 existed = section in self._sections | |
| 73 if existed: | |
| 74 del self._sections[section] | |
| 75 del self._proxies[section] | |
| 76 return existed | |
| 77 | |
| 78 def __getitem__(self, key): | |
| 79 return self._proxies[key] | |
| 80 | |
| 81 def __iter__(self): | |
| 82 return iter(self._sections.keys()) | |
| 83 | |
| 84 def read(self, filename): | |
| 85 with open(filename, encoding="ASCII") as fp: | |
| 86 self._read(fp, filename) | |
| 87 | |
| 88 def _read(self, fp, fpname): | |
| 89 cursect = None # None, or a dictionary | |
| 90 sectname = None | |
| 91 optname = None | |
| 92 lineno = 0 | |
| 93 for lineno, line in enumerate(fp, start=1): | |
| 94 value = line.strip() | |
| 95 if value.startswith('#'): | |
| 96 continue | |
| 97 if not value: | |
| 98 continue | |
| 99 | |
| 100 # is it a section header? | |
| 101 if value.startswith('[') and value.endswith(']'): | |
| 102 sectname = value[1:-1] | |
| 103 if sectname in self._sections: | |
| 104 raise Exception("%s:%s: Section %s already exists" | |
| 105 % (fpname, lineno, sectname)) | |
| 106 else: | |
| 107 cursect = dict() | |
| 108 self._sections[sectname] = cursect | |
| 109 self._proxies[sectname] = SectionProxy(self, sectname) | |
| 110 # So sections can't start with a continuation line | |
| 111 optname = None | |
| 112 # no section header in the file? | |
| 113 elif cursect is None: | |
| 114 raise Exception('%s:%s: File contains no section headers' | |
| 115 % (fpname, lineno)) | |
| 116 # an option line? | |
| 117 else: | |
| 118 optname, optval = value.split('=', 1) | |
| 119 optname = optname.rstrip() | |
| 120 optval = optval.lstrip() | |
|
gregory.p.smith
2012/03/20 05:13:35
do we need to preserve trailing spaces on a value?
haypo
2012/03/20 10:22:22
line.strip() is supposed to have already removed t
| |
| 121 if not optname: | |
| 122 raise ValueError("%s:%s: Empty option name" | |
| 123 % (fpname, lineno)) | |
| 124 optname = optname.rstrip() | |
|
gregory.p.smith
2012/03/20 05:13:35
you already did this above.
haypo
2012/03/20 10:22:22
Ah yes, I forgot it in the cleanup.
| |
| 125 if optname in cursect: | |
| 126 raise DuplicateOptionError(sectname, optname, | |
| 127 fpname, lineno) | |
| 128 cursect[optname] = optval | |
| 22 | 129 |
| 23 # let's read the configuration file | 130 # let's read the configuration file |
| 24 # XXX _CONFIG_DIR will be set by the Makefile later | 131 # XXX _CONFIG_DIR will be set by the Makefile later |
| 25 _CONFIG_DIR = os.path.normpath(os.path.dirname(__file__)) | 132 _CONFIG_DIR = os.path.normpath(os.path.dirname(__file__)) |
| 26 _CONFIG_FILE = os.path.join(_CONFIG_DIR, 'sysconfig.cfg') | 133 _CONFIG_FILE = os.path.join(_CONFIG_DIR, 'sysconfig.cfg') |
| 27 _SCHEMES = RawConfigParser(dict_type=dict) # Faster than OrderedDict | 134 _SCHEMES = _ConfigParser() |
| 28 _SCHEMES.read(_CONFIG_FILE) | 135 _SCHEMES.read(_CONFIG_FILE) |
| 29 _VAR_REPL = re.compile(r'\{([^{]*?)\}') | 136 _VAR_REPL = re.compile(r'\{([^{]*?)\}') |
| 30 | 137 |
| 31 | 138 |
| 32 def _expand_globals(config): | 139 def _expand_globals(config): |
| 33 if config.has_section('globals'): | 140 if config.has_section('globals'): |
| 34 globals = config.items('globals') | 141 globals = config.items('globals') |
| 35 else: | 142 else: |
| 36 globals = tuple() | 143 globals = tuple() |
| 37 | 144 |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 777 print('Python version: "%s"' % get_python_version()) | 884 print('Python version: "%s"' % get_python_version()) |
| 778 print('Current installation scheme: "%s"' % _get_default_scheme()) | 885 print('Current installation scheme: "%s"' % _get_default_scheme()) |
| 779 print() | 886 print() |
| 780 _print_dict('Paths', get_paths()) | 887 _print_dict('Paths', get_paths()) |
| 781 print() | 888 print() |
| 782 _print_dict('Variables', get_config_vars()) | 889 _print_dict('Variables', get_config_vars()) |
| 783 | 890 |
| 784 | 891 |
| 785 if __name__ == '__main__': | 892 if __name__ == '__main__': |
| 786 _main() | 893 _main() |
| 894 | |
| OLD | NEW |