diff -r 39f33c15243b Lib/collections/__init__.py --- a/Lib/collections/__init__.py Sat Oct 29 10:50:00 2016 +0300 +++ b/Lib/collections/__init__.py Tue Nov 08 14:48:00 2016 +0200 @@ -411,6 +411,7 @@ def namedtuple(typename, field_names, *, seen.add(name) # Fill-in the class template + arg_list = repr(tuple(field_names)).replace("'", "")[1:-1] class_definition = _class_template.format( typename = typename, field_names = tuple(field_names), @@ -424,9 +425,68 @@ def namedtuple(typename, field_names, *, # Execute the template string in a temporary namespace and support # tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(__name__='namedtuple_%s' % typename) - exec(class_definition, namespace) - result = namespace[typename] + #namespace = dict(__name__='namedtuple_%s' % typename) + #exec(class_definition, namespace) + #result = namespace[typename] + + class result(tuple): + __slots__ = () + + def __new__(_cls, *args, **kwds): + if len(args) + len(kwds) != len(_cls._fields): + raise TypeError('Expected %d arguments, got %d' % (len(_cls._fields), len(args) + len(kwds))) + try: + args += tuple(kwds.pop(_cls._fields[i]) for i in range(len(args), len(_cls._fields))) + except KeyError as err: + raise TypeError('Got unexpected field name: %r' % str(err)) + if kwds: + raise TypeError('Got unexpected field names: %r' % list(kwds)) + return tuple.__new__(_cls, args) + + @classmethod + def _make(cls, iterable, new=tuple.__new__, len=len): + result = new(cls, iterable) + if len(result) != len(cls._fields): + raise TypeError('Expected %d arguments, got %d' % (len(cls._fields), len(result))) + return result + + def _replace(_self, **kwds): + result = _self._make(map(kwds.pop, _self._fields, _self)) + if kwds: + raise ValueError('Got unexpected field names: %r' % list(kwds)) + return result + + def __repr__(self): + 'Return a nicely formatted representation string' + repr_fmt = ', '.join(f'{name}=%r' for name in self._fields) + return '%s(%s)' % (self.__class__.__name__, repr_fmt % self) + + def _asdict(self): + 'Return a new OrderedDict which maps field names to their values.' + return OrderedDict(zip(self._fields, self)) + + def __getnewargs__(self): + 'Return self as a plain tuple. Used by copy and pickle.' + return tuple(self) + + result.__name__ = typename + result.__qualname__ = typename + result.__doc__ = f'{typename}({arg_list})' + result._fields = tuple(field_names) + #result.__new__ = eval(f'lambda _cls, {arg_list}: _tuple.__new__(_cls, ({arg_list}))', {'_tuple': tuple}) + result.__new__.__doc__ = f'Create new instance of {typename}({arg_list})' + def _make(cls, iterable, new=tuple.__new__, len=len): + result = new(cls, iterable) + if len(result) != len(cls._fields): + raise TypeError('Expected %d arguments, got %d' % (len(cls._fields), len(result))) + return result + _make.__doc__ = f'Make a new {typename} object from a sequence or iterable' + result._make = classmethod(_make) + #result._make.__doc__ = f'Make a new {typename} object from a sequence or iterable' + result._replace.__doc__ = f'Return a new {typename} object replacing specified fields with new values' + for index, name in enumerate(field_names): + setattr(result, name, property(_itemgetter(index), doc=f'Alias for field number {index:d}')) + result._source = class_definition if verbose: print(result._source) diff -r 39f33c15243b Lib/site.py --- a/Lib/site.py Sat Oct 29 10:50:00 2016 +0300 +++ b/Lib/site.py Tue Nov 08 14:48:00 2016 +0200 @@ -422,8 +422,6 @@ def enablerlcompleter(): sys.__interactivehook__ = register_readline -CONFIG_LINE = r'^(?P(\w|[-_])+)\s*=\s*(?P.*)\s*$' - def venv(known_paths): global PREFIXES, ENABLE_USER_SITE @@ -445,19 +443,16 @@ def venv(known_paths): ] if candidate_confs: - import re - config_line = re.compile(CONFIG_LINE) virtual_conf = candidate_confs[0] system_site = "true" # Issue 25185: Use UTF-8, as that's what the venv module uses when # writing the file. with open(virtual_conf, encoding='utf-8') as f: for line in f: - line = line.strip() - m = config_line.match(line) - if m: - d = m.groupdict() - key, value = d['key'].lower(), d['value'] + if '=' in line: + key, _, value = line.partition('=') + key = key.strip().lower() + value = value.strip() if key == 'include-system-site-packages': system_site = value.lower() elif key == 'home':