aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Lib/dataclasses.py
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:39 +0300
commite9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch)
tree64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/tools/python3/src/Lib/dataclasses.py
parent2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff)
downloadydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Lib/dataclasses.py')
-rw-r--r--contrib/tools/python3/src/Lib/dataclasses.py178
1 files changed, 89 insertions, 89 deletions
diff --git a/contrib/tools/python3/src/Lib/dataclasses.py b/contrib/tools/python3/src/Lib/dataclasses.py
index 09982bcc3e..5ff67ad2ea 100644
--- a/contrib/tools/python3/src/Lib/dataclasses.py
+++ b/contrib/tools/python3/src/Lib/dataclasses.py
@@ -7,7 +7,7 @@ import keyword
import builtins
import functools
import _thread
-from types import GenericAlias
+from types import GenericAlias
__all__ = ['dataclass',
@@ -200,24 +200,24 @@ _POST_INIT_NAME = '__post_init__'
# https://bugs.python.org/issue33453 for details.
_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
-class InitVar:
- __slots__ = ('type', )
-
- def __init__(self, type):
- self.type = type
-
- def __repr__(self):
- if isinstance(self.type, type) and not isinstance(self.type, GenericAlias):
- type_name = self.type.__name__
- else:
- # typing objects, e.g. List[int]
- type_name = repr(self.type)
- return f'dataclasses.InitVar[{type_name}]'
-
- def __class_getitem__(cls, type):
- return InitVar(type)
-
-
+class InitVar:
+ __slots__ = ('type', )
+
+ def __init__(self, type):
+ self.type = type
+
+ def __repr__(self):
+ if isinstance(self.type, type) and not isinstance(self.type, GenericAlias):
+ type_name = self.type.__name__
+ else:
+ # typing objects, e.g. List[int]
+ type_name = repr(self.type)
+ return f'dataclasses.InitVar[{type_name}]'
+
+ def __class_getitem__(cls, type):
+ return InitVar(type)
+
+
# Instances of Field are only ever created from within this module,
# and only from the field() function, although Field instances are
# exposed externally as (conceptually) read-only objects.
@@ -285,9 +285,9 @@ class Field:
# it.
func(self.default, owner, name)
- __class_getitem__ = classmethod(GenericAlias)
+ __class_getitem__ = classmethod(GenericAlias)
+
-
class _DataclassParams:
__slots__ = ('init',
'repr',
@@ -381,26 +381,26 @@ def _create_fn(name, args, body, *, globals=None, locals=None,
# worries about external callers.
if locals is None:
locals = {}
- if 'BUILTINS' not in locals:
- locals['BUILTINS'] = builtins
+ if 'BUILTINS' not in locals:
+ locals['BUILTINS'] = builtins
return_annotation = ''
if return_type is not MISSING:
locals['_return_type'] = return_type
return_annotation = '->_return_type'
args = ','.join(args)
- body = '\n'.join(f' {b}' for b in body)
+ body = '\n'.join(f' {b}' for b in body)
# Compute the text of the entire function.
- txt = f' def {name}({args}){return_annotation}:\n{body}'
+ txt = f' def {name}({args}){return_annotation}:\n{body}'
+
+ local_vars = ', '.join(locals.keys())
+ txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}"
- local_vars = ', '.join(locals.keys())
- txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}"
+ ns = {}
+ exec(txt, globals, ns)
+ return ns['__create_fn__'](**locals)
- ns = {}
- exec(txt, globals, ns)
- return ns['__create_fn__'](**locals)
-
def _field_assign(frozen, name, value, self_name):
# If we're a frozen class, then assign to our fields in __init__
# via object.__setattr__. Otherwise, just use a simple
@@ -409,7 +409,7 @@ def _field_assign(frozen, name, value, self_name):
# self_name is what "self" is called in this function: don't
# hard-code "self", since that might be a field name.
if frozen:
- return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
+ return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
return f'{self_name}.{name}={value}'
@@ -486,7 +486,7 @@ def _init_param(f):
return f'{f.name}:_type_{f.name}{default}'
-def _init_fn(fields, frozen, has_post_init, self_name, globals):
+def _init_fn(fields, frozen, has_post_init, self_name, globals):
# fields contains both real fields and InitVar pseudo-fields.
# Make sure we don't have fields without defaults following fields
@@ -504,15 +504,15 @@ def _init_fn(fields, frozen, has_post_init, self_name, globals):
raise TypeError(f'non-default argument {f.name!r} '
'follows default argument')
- locals = {f'_type_{f.name}': f.type for f in fields}
- locals.update({
- 'MISSING': MISSING,
- '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
- })
+ locals = {f'_type_{f.name}': f.type for f in fields}
+ locals.update({
+ 'MISSING': MISSING,
+ '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
+ })
body_lines = []
for f in fields:
- line = _field_init(f, frozen, locals, self_name)
+ line = _field_init(f, frozen, locals, self_name)
# line is None means that this field doesn't require
# initialization (it's a pseudo-field). Just skip it.
if line:
@@ -536,19 +536,19 @@ def _init_fn(fields, frozen, has_post_init, self_name, globals):
return_type=None)
-def _repr_fn(fields, globals):
+def _repr_fn(fields, globals):
fn = _create_fn('__repr__',
('self',),
['return self.__class__.__qualname__ + f"(' +
', '.join([f"{f.name}={{self.{f.name}!r}}"
for f in fields]) +
- ')"'],
- globals=globals)
+ ')"'],
+ globals=globals)
return _recursive_repr(fn)
-def _frozen_get_del_attr(cls, fields, globals):
- locals = {'cls': cls,
+def _frozen_get_del_attr(cls, fields, globals):
+ locals = {'cls': cls,
'FrozenInstanceError': FrozenInstanceError}
if fields:
fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)'
@@ -560,19 +560,19 @@ def _frozen_get_del_attr(cls, fields, globals):
(f'if type(self) is cls or name in {fields_str}:',
' raise FrozenInstanceError(f"cannot assign to field {name!r}")',
f'super(cls, self).__setattr__(name, value)'),
- locals=locals,
+ locals=locals,
globals=globals),
_create_fn('__delattr__',
('self', 'name'),
(f'if type(self) is cls or name in {fields_str}:',
' raise FrozenInstanceError(f"cannot delete field {name!r}")',
f'super(cls, self).__delattr__(name)'),
- locals=locals,
+ locals=locals,
globals=globals),
)
-def _cmp_fn(name, op, self_tuple, other_tuple, globals):
+def _cmp_fn(name, op, self_tuple, other_tuple, globals):
# Create a comparison function. If the fields in the object are
# named 'x' and 'y', then self_tuple is the string
# '(self.x,self.y)' and other_tuple is the string
@@ -582,16 +582,16 @@ def _cmp_fn(name, op, self_tuple, other_tuple, globals):
('self', 'other'),
[ 'if other.__class__ is self.__class__:',
f' return {self_tuple}{op}{other_tuple}',
- 'return NotImplemented'],
- globals=globals)
+ 'return NotImplemented'],
+ globals=globals)
-def _hash_fn(fields, globals):
+def _hash_fn(fields, globals):
self_tuple = _tuple_str('self', fields)
return _create_fn('__hash__',
('self',),
- [f'return hash({self_tuple})'],
- globals=globals)
+ [f'return hash({self_tuple})'],
+ globals=globals)
def _is_classvar(a_type, typing):
@@ -605,8 +605,8 @@ def _is_classvar(a_type, typing):
def _is_initvar(a_type, dataclasses):
# The module we're checking against is the module we're
# currently in (dataclasses.py).
- return (a_type is dataclasses.InitVar
- or type(a_type) is dataclasses.InitVar)
+ return (a_type is dataclasses.InitVar
+ or type(a_type) is dataclasses.InitVar)
def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
@@ -696,7 +696,7 @@ def _get_field(cls, a_name, a_type):
# In addition to checking for actual types here, also check for
# string annotations. get_type_hints() won't always work for us
# (see https://github.com/python/typing/issues/508 for example),
- # plus it's expensive and would require an eval for every string
+ # plus it's expensive and would require an eval for every string
# annotation. So, make a best effort to see if this is a ClassVar
# or InitVar using regex's and checking that the thing referenced
# is actually of the correct type.
@@ -764,14 +764,14 @@ def _set_new_attribute(cls, name, value):
# take. The common case is to do nothing, so instead of providing a
# function that is a no-op, use None to signify that.
-def _hash_set_none(cls, fields, globals):
+def _hash_set_none(cls, fields, globals):
return None
-def _hash_add(cls, fields, globals):
+def _hash_add(cls, fields, globals):
flds = [f for f in fields if (f.compare if f.hash is None else f.hash)]
- return _hash_fn(flds, globals)
+ return _hash_fn(flds, globals)
-def _hash_exception(cls, fields, globals):
+def _hash_exception(cls, fields, globals):
# Raise an exception.
raise TypeError(f'Cannot overwrite attribute __hash__ '
f'in class {cls.__name__}')
@@ -813,16 +813,16 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
# is defined by the base class, which is found first.
fields = {}
- if cls.__module__ in sys.modules:
- globals = sys.modules[cls.__module__].__dict__
- else:
- # Theoretically this can happen if someone writes
- # a custom string to cls.__module__. In which case
- # such dataclass won't be fully introspectable
- # (w.r.t. typing.get_type_hints) but will still function
- # correctly.
- globals = {}
-
+ if cls.__module__ in sys.modules:
+ globals = sys.modules[cls.__module__].__dict__
+ else:
+ # Theoretically this can happen if someone writes
+ # a custom string to cls.__module__. In which case
+ # such dataclass won't be fully introspectable
+ # (w.r.t. typing.get_type_hints) but will still function
+ # correctly.
+ globals = {}
+
setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
unsafe_hash, frozen))
@@ -836,7 +836,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
# Only process classes that have been processed by our
# decorator. That is, they have a _FIELDS attribute.
base_fields = getattr(b, _FIELDS, None)
- if base_fields is not None:
+ if base_fields is not None:
has_dataclass_bases = True
for f in base_fields.values():
fields[f.name] = f
@@ -932,7 +932,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
# if possible.
'__dataclass_self__' if 'self' in fields
else 'self',
- globals,
+ globals,
))
# Get the fields as a list, and include only real fields. This is
@@ -941,18 +941,18 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
if repr:
flds = [f for f in field_list if f.repr]
- _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals))
+ _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals))
if eq:
- # Create __eq__ method. There's no need for a __ne__ method,
+ # Create __eq__ method. There's no need for a __ne__ method,
# since python will call __eq__ and negate it.
flds = [f for f in field_list if f.compare]
self_tuple = _tuple_str('self', flds)
other_tuple = _tuple_str('other', flds)
_set_new_attribute(cls, '__eq__',
_cmp_fn('__eq__', '==',
- self_tuple, other_tuple,
- globals=globals))
+ self_tuple, other_tuple,
+ globals=globals))
if order:
# Create and set the ordering methods.
@@ -965,14 +965,14 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
('__ge__', '>='),
]:
if _set_new_attribute(cls, name,
- _cmp_fn(name, op, self_tuple, other_tuple,
- globals=globals)):
+ _cmp_fn(name, op, self_tuple, other_tuple,
+ globals=globals)):
raise TypeError(f'Cannot overwrite attribute {name} '
f'in class {cls.__name__}. Consider using '
'functools.total_ordering')
if frozen:
- for fn in _frozen_get_del_attr(cls, field_list, globals):
+ for fn in _frozen_get_del_attr(cls, field_list, globals):
if _set_new_attribute(cls, fn.__name__, fn):
raise TypeError(f'Cannot overwrite attribute {fn.__name__} '
f'in class {cls.__name__}')
@@ -985,7 +985,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
if hash_action:
# No need to call _set_new_attribute here, since by the time
# we're here the overwriting is unconditional.
- cls.__hash__ = hash_action(cls, field_list, globals)
+ cls.__hash__ = hash_action(cls, field_list, globals)
if not getattr(cls, '__doc__'):
# Create a class doc-string.
@@ -995,7 +995,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen):
return cls
-def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
+def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
unsafe_hash=False, frozen=False):
"""Returns the same class as was passed in, with dunder methods
added based on the fields defined in the class.
@@ -1013,12 +1013,12 @@ def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
# See if we're being called as @dataclass or @dataclass().
- if cls is None:
+ if cls is None:
# We're called with parens.
return wrap
# We're called as @dataclass without parens.
- return wrap(cls)
+ return wrap(cls)
def fields(class_or_instance):
@@ -1041,14 +1041,14 @@ def fields(class_or_instance):
def _is_dataclass_instance(obj):
"""Returns True if obj is an instance of a dataclass."""
- return hasattr(type(obj), _FIELDS)
+ return hasattr(type(obj), _FIELDS)
def is_dataclass(obj):
"""Returns True if obj is a dataclass or an instance of a
dataclass."""
- cls = obj if isinstance(obj, type) and not isinstance(obj, GenericAlias) else type(obj)
- return hasattr(cls, _FIELDS)
+ cls = obj if isinstance(obj, type) and not isinstance(obj, GenericAlias) else type(obj)
+ return hasattr(cls, _FIELDS)
def asdict(obj, *, dict_factory=dict):
@@ -1094,7 +1094,7 @@ def _asdict_inner(obj, dict_factory):
# method, because:
# - it does not recurse in to the namedtuple fields and
# convert them to dicts (using dict_factory).
- # - I don't actually want to return a dict here. The main
+ # - I don't actually want to return a dict here. The main
# use case here is json.dumps, and it handles converting
# namedtuples to lists. Admittedly we're losing some
# information here when we produce a json list instead of a
@@ -1216,7 +1216,7 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
raise TypeError(f'Invalid field: {item!r}')
if not isinstance(name, str) or not name.isidentifier():
- raise TypeError(f'Field names must be valid identifiers: {name!r}')
+ raise TypeError(f'Field names must be valid identifiers: {name!r}')
if keyword.iskeyword(name):
raise TypeError(f'Field names must not be keywords: {name!r}')
if name in seen:
@@ -1233,7 +1233,7 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True,
unsafe_hash=unsafe_hash, frozen=frozen)
-def replace(obj, /, **changes):
+def replace(obj, /, **changes):
"""Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@@ -1271,7 +1271,7 @@ def replace(obj, /, **changes):
continue
if f.name not in changes:
- if f._field_type is _FIELD_INITVAR and f.default is MISSING:
+ if f._field_type is _FIELD_INITVAR and f.default is MISSING:
raise ValueError(f"InitVar {f.name!r} "
'must be specified with replace()')
changes[f.name] = getattr(obj, f.name)