Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/ConfigParser.py

    r2 r391  
    8888"""
    8989
     90try:
     91    from collections import OrderedDict as _default_dict
     92except ImportError:
     93    # fallback for setup.py which hasn't yet built _collections
     94    _default_dict = dict
     95
    9096import re
    9197
     
    137143        Error.__init__(self, 'No section: %r' % (section,))
    138144        self.section = section
     145        self.args = (section, )
    139146
    140147class DuplicateSectionError(Error):
     
    144151        Error.__init__(self, "Section %r already exists" % section)
    145152        self.section = section
     153        self.args = (section, )
    146154
    147155class NoOptionError(Error):
     
    153161        self.option = option
    154162        self.section = section
     163        self.args = (option, section)
    155164
    156165class InterpolationError(Error):
     
    161170        self.option = option
    162171        self.section = section
     172        self.args = (option, section, msg)
    163173
    164174class InterpolationMissingOptionError(InterpolationError):
     
    174184        InterpolationError.__init__(self, option, section, msg)
    175185        self.reference = reference
     186        self.args = (option, section, rawval, reference)
    176187
    177188class InterpolationSyntaxError(InterpolationError):
     
    189200               % (section, option, rawval))
    190201        InterpolationError.__init__(self, option, section, msg)
     202        self.args = (option, section, rawval)
    191203
    192204class ParsingError(Error):
     
    197209        self.filename = filename
    198210        self.errors = []
     211        self.args = (filename, )
    199212
    200213    def append(self, lineno, line):
     
    213226        self.lineno = lineno
    214227        self.line = line
     228        self.args = (filename, lineno, line)
    215229
    216230
    217231class RawConfigParser:
    218     def __init__(self, defaults=None, dict_type=dict):
     232    def __init__(self, defaults=None, dict_type=_default_dict,
     233                 allow_no_value=False):
    219234        self._dict = dict_type
    220235        self._sections = self._dict()
    221236        self._defaults = self._dict()
     237        if allow_no_value:
     238            self._optcre = self.OPTCRE_NV
     239        else:
     240            self._optcre = self.OPTCRE
    222241        if defaults:
    223242            for key, value in defaults.items():
     
    367386                    or option in self._defaults)
    368387
    369     def set(self, section, option, value):
     388    def set(self, section, option, value=None):
    370389        """Set an option."""
    371390        if not section or section == DEFAULTSECT:
     
    388407            fp.write("[%s]\n" % section)
    389408            for (key, value) in self._sections[section].items():
    390                 if key != "__name__":
    391                     fp.write("%s = %s\n" %
    392                              (key, str(value).replace('\n', '\n\t')))
     409                if key == "__name__":
     410                    continue
     411                if (value is not None) or (self._optcre == self.OPTCRE):
     412                    key = " = ".join((key, str(value).replace('\n', '\n\t')))
     413                fp.write("%s\n" % (key))
    393414            fp.write("\n")
    394415
     
    431452        r'(?P<value>.*)$'                     # everything up to eol
    432453        )
     454    OPTCRE_NV = re.compile(
     455        r'(?P<option>[^:=\s][^:=]*)'          # very permissive!
     456        r'\s*(?:'                             # any number of space/tab,
     457        r'(?P<vi>[:=])\s*'                    # optionally followed by
     458                                              # separator (either : or
     459                                              # =), followed by any #
     460                                              # space/tab
     461        r'(?P<value>.*))?$'                   # everything up to eol
     462        )
    433463
    434464    def _read(self, fp, fpname):
     
    442472        and just about everything else are ignored.
    443473        """
    444         cursect = None                            # None, or a dictionary
     474        cursect = None                        # None, or a dictionary
    445475        optname = None
    446476        lineno = 0
    447         e = None                                  # None, or an exception
     477        e = None                              # None, or an exception
    448478        while True:
    449479            line = fp.readline()
     
    461491                value = line.strip()
    462492                if value:
    463                     cursect[optname] = "%s\n%s" % (cursect[optname], value)
     493                    cursect[optname].append(value)
    464494            # a section header or option header?
    465495            else:
     
    483513                # an option line?
    484514                else:
    485                     mo = self.OPTCRE.match(line)
     515                    mo = self._optcre.match(line)
    486516                    if mo:
    487517                        optname, vi, optval = mo.group('option', 'vi', 'value')
    488                         if vi in ('=', ':') and ';' in optval:
    489                             # ';' is a comment delimiter only if it follows
    490                             # a spacing character
    491                             pos = optval.find(';')
    492                             if pos != -1 and optval[pos-1].isspace():
    493                                 optval = optval[:pos]
    494                         optval = optval.strip()
    495                         # allow empty values
    496                         if optval == '""':
    497                             optval = ''
    498518                        optname = self.optionxform(optname.rstrip())
    499                         cursect[optname] = optval
     519                        # This check is fine because the OPTCRE cannot
     520                        # match if it would set optval to None
     521                        if optval is not None:
     522                            if vi in ('=', ':') and ';' in optval:
     523                                # ';' is a comment delimiter only if it follows
     524                                # a spacing character
     525                                pos = optval.find(';')
     526                                if pos != -1 and optval[pos-1].isspace():
     527                                    optval = optval[:pos]
     528                            optval = optval.strip()
     529                            # allow empty values
     530                            if optval == '""':
     531                                optval = ''
     532                            cursect[optname] = [optval]
     533                        else:
     534                            # valueless option handling
     535                            cursect[optname] = optval
    500536                    else:
    501537                        # a non-fatal parsing error occurred.  set up the
     
    510546            raise e
    511547
     548        # join the multi-line values collected while reading
     549        all_sections = [self._defaults]
     550        all_sections.extend(self._sections.values())
     551        for options in all_sections:
     552            for name, val in options.items():
     553                if isinstance(val, list):
     554                    options[name] = '\n'.join(val)
     555
     556import UserDict as _UserDict
     557
     558class _Chainmap(_UserDict.DictMixin):
     559    """Combine multiple mappings for successive lookups.
     560
     561    For example, to emulate Python's normal lookup sequence:
     562
     563        import __builtin__
     564        pylookup = _Chainmap(locals(), globals(), vars(__builtin__))
     565    """
     566
     567    def __init__(self, *maps):
     568        self._maps = maps
     569
     570    def __getitem__(self, key):
     571        for mapping in self._maps:
     572            try:
     573                return mapping[key]
     574            except KeyError:
     575                pass
     576        raise KeyError(key)
     577
     578    def keys(self):
     579        result = []
     580        seen = set()
     581        for mapping in self._maps:
     582            for key in mapping:
     583                if key not in seen:
     584                    result.append(key)
     585                    seen.add(key)
     586        return result
    512587
    513588class ConfigParser(RawConfigParser):
     
    516591        """Get an option value for a given section.
    517592
    518         All % interpolations are expanded in the return values, based on the
    519         defaults passed into the constructor, unless the optional argument
    520         `raw' is true.  Additional substitutions may be provided using the
    521         `vars' argument, which must be a dictionary whose contents overrides
    522         any pre-existing defaults.
     593        If `vars' is provided, it must be a dictionary. The option is looked up
     594        in `vars' (if provided), `section', and in `defaults' in that order.
     595
     596        All % interpolations are expanded in the return values, unless the
     597        optional argument `raw' is true. Values for interpolation keys are
     598        looked up in the same manner as the option.
    523599
    524600        The section DEFAULT is special.
    525601        """
    526         d = self._defaults.copy()
     602        sectiondict = {}
    527603        try:
    528             d.update(self._sections[section])
     604            sectiondict = self._sections[section]
    529605        except KeyError:
    530606            if section != DEFAULTSECT:
    531607                raise NoSectionError(section)
    532608        # Update with the entry specific variables
     609        vardict = {}
    533610        if vars:
    534611            for key, value in vars.items():
    535                 d[self.optionxform(key)] = value
     612                vardict[self.optionxform(key)] = value
     613        d = _Chainmap(vardict, sectiondict, self._defaults)
    536614        option = self.optionxform(option)
    537615        try:
     
    540618            raise NoOptionError(option, section)
    541619
    542         if raw:
     620        if raw or value is None:
    543621            return value
    544622        else:
     
    583661        while depth:                    # Loop through this until it's done
    584662            depth -= 1
    585             if "%(" in value:
     663            if value and "%(" in value:
    586664                value = self._KEYCRE.sub(self._interpolation_replace, value)
    587665                try:
     
    592670            else:
    593671                break
    594         if "%(" in value:
     672        if value and "%(" in value:
    595673            raise InterpolationDepthError(option, section, rawval)
    596674        return value
     
    654732                    "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
    655733
    656     def set(self, section, option, value):
     734    def set(self, section, option, value=None):
    657735        """Set an option.  Extend ConfigParser.set: check for string values."""
    658         if not isinstance(value, basestring):
    659             raise TypeError("option values must be strings")
    660         # check for bad percent signs:
    661         # first, replace all "good" interpolations
    662         tmp_value = value.replace('%%', '')
    663         tmp_value = self._interpvar_re.sub('', tmp_value)
    664         # then, check if there's a lone percent sign left
    665         percent_index = tmp_value.find('%')
    666         if percent_index != -1:
    667             raise ValueError("invalid interpolation syntax in %r at "
    668                              "position %d" % (value, percent_index))
     736        # The only legal non-string value if we allow valueless
     737        # options is None, so we need to check if the value is a
     738        # string if:
     739        # - we do not allow valueless options, or
     740        # - we allow valueless options but the value is not None
     741        if self._optcre is self.OPTCRE or value:
     742            if not isinstance(value, basestring):
     743                raise TypeError("option values must be strings")
     744        if value is not None:
     745            # check for bad percent signs:
     746            # first, replace all "good" interpolations
     747            tmp_value = value.replace('%%', '')
     748            tmp_value = self._interpvar_re.sub('', tmp_value)
     749            # then, check if there's a lone percent sign left
     750            if '%' in tmp_value:
     751                raise ValueError("invalid interpolation syntax in %r at "
     752                                "position %d" % (value, tmp_value.find('%')))
    669753        ConfigParser.set(self, section, option, value)
Note: See TracChangeset for help on using the changeset viewer.