1import re 2import sys 3import copy 4import types 5import inspect 6import keyword 7import builtins 8import functools 9import itertools 10import abc 11import _thread 12from types import FunctionType, GenericAlias 13 14 15__all__ = ['dataclass', 16 'field', 17 'Field', 18 'FrozenInstanceError', 19 'InitVar', 20 'KW_ONLY', 21 'MISSING', 22 23 # Helper functions. 24 'fields', 25 'asdict', 26 'astuple', 27 'make_dataclass', 28 'replace', 29 'is_dataclass', 30 ] 31 32# Conditions for adding methods. The boxes indicate what action the 33# dataclass decorator takes. For all of these tables, when I talk 34# about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I'm 35# referring to the arguments to the @dataclass decorator. When 36# checking if a dunder method already exists, I mean check for an 37# entry in the class's __dict__. I never check to see if an attribute 38# is defined in a base class. 39 40# Key: 41# +=========+=========================================+ 42# + Value | Meaning | 43# +=========+=========================================+ 44# | <blank> | No action: no method is added. | 45# +---------+-----------------------------------------+ 46# | add | Generated method is added. | 47# +---------+-----------------------------------------+ 48# | raise | TypeError is raised. | 49# +---------+-----------------------------------------+ 50# | None | Attribute is set to None. | 51# +=========+=========================================+ 52 53# __init__ 54# 55# +--- init= parameter 56# | 57# v | | | 58# | no | yes | <--- class has __init__ in __dict__? 59# +=======+=======+=======+ 60# | False | | | 61# +-------+-------+-------+ 62# | True | add | | <- the default 63# +=======+=======+=======+ 64 65# __repr__ 66# 67# +--- repr= parameter 68# | 69# v | | | 70# | no | yes | <--- class has __repr__ in __dict__? 71# +=======+=======+=======+ 72# | False | | | 73# +-------+-------+-------+ 74# | True | add | | <- the default 75# +=======+=======+=======+ 76 77 78# __setattr__ 79# __delattr__ 80# 81# +--- frozen= parameter 82# | 83# v | | | 84# | no | yes | <--- class has __setattr__ or __delattr__ in __dict__? 85# +=======+=======+=======+ 86# | False | | | <- the default 87# +-------+-------+-------+ 88# | True | add | raise | 89# +=======+=======+=======+ 90# Raise because not adding these methods would break the "frozen-ness" 91# of the class. 92 93# __eq__ 94# 95# +--- eq= parameter 96# | 97# v | | | 98# | no | yes | <--- class has __eq__ in __dict__? 99# +=======+=======+=======+ 100# | False | | | 101# +-------+-------+-------+ 102# | True | add | | <- the default 103# +=======+=======+=======+ 104 105# __lt__ 106# __le__ 107# __gt__ 108# __ge__ 109# 110# +--- order= parameter 111# | 112# v | | | 113# | no | yes | <--- class has any comparison method in __dict__? 114# +=======+=======+=======+ 115# | False | | | <- the default 116# +-------+-------+-------+ 117# | True | add | raise | 118# +=======+=======+=======+ 119# Raise because to allow this case would interfere with using 120# functools.total_ordering. 121 122# __hash__ 123 124# +------------------- unsafe_hash= parameter 125# | +----------- eq= parameter 126# | | +--- frozen= parameter 127# | | | 128# v v v | | | 129# | no | yes | <--- class has explicitly defined __hash__ 130# +=======+=======+=======+========+========+ 131# | False | False | False | | | No __eq__, use the base class __hash__ 132# +-------+-------+-------+--------+--------+ 133# | False | False | True | | | No __eq__, use the base class __hash__ 134# +-------+-------+-------+--------+--------+ 135# | False | True | False | None | | <-- the default, not hashable 136# +-------+-------+-------+--------+--------+ 137# | False | True | True | add | | Frozen, so hashable, allows override 138# +-------+-------+-------+--------+--------+ 139# | True | False | False | add | raise | Has no __eq__, but hashable 140# +-------+-------+-------+--------+--------+ 141# | True | False | True | add | raise | Has no __eq__, but hashable 142# +-------+-------+-------+--------+--------+ 143# | True | True | False | add | raise | Not frozen, but hashable 144# +-------+-------+-------+--------+--------+ 145# | True | True | True | add | raise | Frozen, so hashable 146# +=======+=======+=======+========+========+ 147# For boxes that are blank, __hash__ is untouched and therefore 148# inherited from the base class. If the base is object, then 149# id-based hashing is used. 150# 151# Note that a class may already have __hash__=None if it specified an 152# __eq__ method in the class body (not one that was created by 153# @dataclass). 154# 155# See _hash_action (below) for a coded version of this table. 156 157# __match_args__ 158# 159# +--- match_args= parameter 160# | 161# v | | | 162# | no | yes | <--- class has __match_args__ in __dict__? 163# +=======+=======+=======+ 164# | False | | | 165# +-------+-------+-------+ 166# | True | add | | <- the default 167# +=======+=======+=======+ 168# __match_args__ is always added unless the class already defines it. It is a 169# tuple of __init__ parameter names; non-init fields must be matched by keyword. 170 171 172# Raised when an attempt is made to modify a frozen class. 173class FrozenInstanceError(AttributeError): pass 174 175# A sentinel object for default values to signal that a default 176# factory will be used. This is given a nice repr() which will appear 177# in the function signature of dataclasses' constructors. 178class _HAS_DEFAULT_FACTORY_CLASS: 179 def __repr__(self): 180 return '<factory>' 181_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS() 182 183# A sentinel object to detect if a parameter is supplied or not. Use 184# a class to give it a better repr. 185class _MISSING_TYPE: 186 pass 187MISSING = _MISSING_TYPE() 188 189# A sentinel object to indicate that following fields are keyword-only by 190# default. Use a class to give it a better repr. 191class _KW_ONLY_TYPE: 192 pass 193KW_ONLY = _KW_ONLY_TYPE() 194 195# Since most per-field metadata will be unused, create an empty 196# read-only proxy that can be shared among all fields. 197_EMPTY_METADATA = types.MappingProxyType({}) 198 199# Markers for the various kinds of fields and pseudo-fields. 200class _FIELD_BASE: 201 def __init__(self, name): 202 self.name = name 203 def __repr__(self): 204 return self.name 205_FIELD = _FIELD_BASE('_FIELD') 206_FIELD_CLASSVAR = _FIELD_BASE('_FIELD_CLASSVAR') 207_FIELD_INITVAR = _FIELD_BASE('_FIELD_INITVAR') 208 209# The name of an attribute on the class where we store the Field 210# objects. Also used to check if a class is a Data Class. 211_FIELDS = '__dataclass_fields__' 212 213# The name of an attribute on the class that stores the parameters to 214# @dataclass. 215_PARAMS = '__dataclass_params__' 216 217# The name of the function, that if it exists, is called at the end of 218# __init__. 219_POST_INIT_NAME = '__post_init__' 220 221# String regex that string annotations for ClassVar or InitVar must match. 222# Allows "identifier.identifier[" or "identifier[". 223# https://bugs.python.org/issue33453 for details. 224_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)') 225 226# This function's logic is copied from "recursive_repr" function in 227# reprlib module to avoid dependency. 228def _recursive_repr(user_function): 229 # Decorator to make a repr function return "..." for a recursive 230 # call. 231 repr_running = set() 232 233 @functools.wraps(user_function) 234 def wrapper(self): 235 key = id(self), _thread.get_ident() 236 if key in repr_running: 237 return '...' 238 repr_running.add(key) 239 try: 240 result = user_function(self) 241 finally: 242 repr_running.discard(key) 243 return result 244 return wrapper 245 246class InitVar: 247 __slots__ = ('type', ) 248 249 def __init__(self, type): 250 self.type = type 251 252 def __repr__(self): 253 if isinstance(self.type, type): 254 type_name = self.type.__name__ 255 else: 256 # typing objects, e.g. List[int] 257 type_name = repr(self.type) 258 return f'dataclasses.InitVar[{type_name}]' 259 260 def __class_getitem__(cls, type): 261 return InitVar(type) 262 263# Instances of Field are only ever created from within this module, 264# and only from the field() function, although Field instances are 265# exposed externally as (conceptually) read-only objects. 266# 267# name and type are filled in after the fact, not in __init__. 268# They're not known at the time this class is instantiated, but it's 269# convenient if they're available later. 270# 271# When cls._FIELDS is filled in with a list of Field objects, the name 272# and type fields will have been populated. 273class Field: 274 __slots__ = ('name', 275 'type', 276 'default', 277 'default_factory', 278 'repr', 279 'hash', 280 'init', 281 'compare', 282 'metadata', 283 'kw_only', 284 '_field_type', # Private: not to be used by user code. 285 ) 286 287 def __init__(self, default, default_factory, init, repr, hash, compare, 288 metadata, kw_only): 289 self.name = None 290 self.type = None 291 self.default = default 292 self.default_factory = default_factory 293 self.init = init 294 self.repr = repr 295 self.hash = hash 296 self.compare = compare 297 self.metadata = (_EMPTY_METADATA 298 if metadata is None else 299 types.MappingProxyType(metadata)) 300 self.kw_only = kw_only 301 self._field_type = None 302 303 @_recursive_repr 304 def __repr__(self): 305 return ('Field(' 306 f'name={self.name!r},' 307 f'type={self.type!r},' 308 f'default={self.default!r},' 309 f'default_factory={self.default_factory!r},' 310 f'init={self.init!r},' 311 f'repr={self.repr!r},' 312 f'hash={self.hash!r},' 313 f'compare={self.compare!r},' 314 f'metadata={self.metadata!r},' 315 f'kw_only={self.kw_only!r},' 316 f'_field_type={self._field_type}' 317 ')') 318 319 # This is used to support the PEP 487 __set_name__ protocol in the 320 # case where we're using a field that contains a descriptor as a 321 # default value. For details on __set_name__, see 322 # https://peps.python.org/pep-0487/#implementation-details. 323 # 324 # Note that in _process_class, this Field object is overwritten 325 # with the default value, so the end result is a descriptor that 326 # had __set_name__ called on it at the right time. 327 def __set_name__(self, owner, name): 328 func = getattr(type(self.default), '__set_name__', None) 329 if func: 330 # There is a __set_name__ method on the descriptor, call 331 # it. 332 func(self.default, owner, name) 333 334 __class_getitem__ = classmethod(GenericAlias) 335 336 337class _DataclassParams: 338 __slots__ = ('init', 339 'repr', 340 'eq', 341 'order', 342 'unsafe_hash', 343 'frozen', 344 ) 345 346 def __init__(self, init, repr, eq, order, unsafe_hash, frozen): 347 self.init = init 348 self.repr = repr 349 self.eq = eq 350 self.order = order 351 self.unsafe_hash = unsafe_hash 352 self.frozen = frozen 353 354 def __repr__(self): 355 return ('_DataclassParams(' 356 f'init={self.init!r},' 357 f'repr={self.repr!r},' 358 f'eq={self.eq!r},' 359 f'order={self.order!r},' 360 f'unsafe_hash={self.unsafe_hash!r},' 361 f'frozen={self.frozen!r}' 362 ')') 363 364 365# This function is used instead of exposing Field creation directly, 366# so that a type checker can be told (via overloads) that this is a 367# function whose type depends on its parameters. 368def field(*, default=MISSING, default_factory=MISSING, init=True, repr=True, 369 hash=None, compare=True, metadata=None, kw_only=MISSING): 370 """Return an object to identify dataclass fields. 371 372 default is the default value of the field. default_factory is a 373 0-argument function called to initialize a field's value. If init 374 is true, the field will be a parameter to the class's __init__() 375 function. If repr is true, the field will be included in the 376 object's repr(). If hash is true, the field will be included in the 377 object's hash(). If compare is true, the field will be used in 378 comparison functions. metadata, if specified, must be a mapping 379 which is stored but not otherwise examined by dataclass. If kw_only 380 is true, the field will become a keyword-only parameter to 381 __init__(). 382 383 It is an error to specify both default and default_factory. 384 """ 385 386 if default is not MISSING and default_factory is not MISSING: 387 raise ValueError('cannot specify both default and default_factory') 388 return Field(default, default_factory, init, repr, hash, compare, 389 metadata, kw_only) 390 391 392def _fields_in_init_order(fields): 393 # Returns the fields as __init__ will output them. It returns 2 tuples: 394 # the first for normal args, and the second for keyword args. 395 396 return (tuple(f for f in fields if f.init and not f.kw_only), 397 tuple(f for f in fields if f.init and f.kw_only) 398 ) 399 400 401def _tuple_str(obj_name, fields): 402 # Return a string representing each field of obj_name as a tuple 403 # member. So, if fields is ['x', 'y'] and obj_name is "self", 404 # return "(self.x,self.y)". 405 406 # Special case for the 0-tuple. 407 if not fields: 408 return '()' 409 # Note the trailing comma, needed if this turns out to be a 1-tuple. 410 return f'({",".join([f"{obj_name}.{f.name}" for f in fields])},)' 411 412 413def _create_fn(name, args, body, *, globals=None, locals=None, 414 return_type=MISSING): 415 # Note that we may mutate locals. Callers beware! 416 # The only callers are internal to this module, so no 417 # worries about external callers. 418 if locals is None: 419 locals = {} 420 return_annotation = '' 421 if return_type is not MISSING: 422 locals['_return_type'] = return_type 423 return_annotation = '->_return_type' 424 args = ','.join(args) 425 body = '\n'.join(f' {b}' for b in body) 426 427 # Compute the text of the entire function. 428 txt = f' def {name}({args}){return_annotation}:\n{body}' 429 430 local_vars = ', '.join(locals.keys()) 431 txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}" 432 ns = {} 433 exec(txt, globals, ns) 434 return ns['__create_fn__'](**locals) 435 436 437def _field_assign(frozen, name, value, self_name): 438 # If we're a frozen class, then assign to our fields in __init__ 439 # via object.__setattr__. Otherwise, just use a simple 440 # assignment. 441 # 442 # self_name is what "self" is called in this function: don't 443 # hard-code "self", since that might be a field name. 444 if frozen: 445 return f'__dataclass_builtins_object__.__setattr__({self_name},{name!r},{value})' 446 return f'{self_name}.{name}={value}' 447 448 449def _field_init(f, frozen, globals, self_name, slots): 450 # Return the text of the line in the body of __init__ that will 451 # initialize this field. 452 453 default_name = f'_dflt_{f.name}' 454 if f.default_factory is not MISSING: 455 if f.init: 456 # This field has a default factory. If a parameter is 457 # given, use it. If not, call the factory. 458 globals[default_name] = f.default_factory 459 value = (f'{default_name}() ' 460 f'if {f.name} is _HAS_DEFAULT_FACTORY ' 461 f'else {f.name}') 462 else: 463 # This is a field that's not in the __init__ params, but 464 # has a default factory function. It needs to be 465 # initialized here by calling the factory function, 466 # because there's no other way to initialize it. 467 468 # For a field initialized with a default=defaultvalue, the 469 # class dict just has the default value 470 # (cls.fieldname=defaultvalue). But that won't work for a 471 # default factory, the factory must be called in __init__ 472 # and we must assign that to self.fieldname. We can't 473 # fall back to the class dict's value, both because it's 474 # not set, and because it might be different per-class 475 # (which, after all, is why we have a factory function!). 476 477 globals[default_name] = f.default_factory 478 value = f'{default_name}()' 479 else: 480 # No default factory. 481 if f.init: 482 if f.default is MISSING: 483 # There's no default, just do an assignment. 484 value = f.name 485 elif f.default is not MISSING: 486 globals[default_name] = f.default 487 value = f.name 488 else: 489 # If the class has slots, then initialize this field. 490 if slots and f.default is not MISSING: 491 globals[default_name] = f.default 492 value = default_name 493 else: 494 # This field does not need initialization: reading from it will 495 # just use the class attribute that contains the default. 496 # Signify that to the caller by returning None. 497 return None 498 499 # Only test this now, so that we can create variables for the 500 # default. However, return None to signify that we're not going 501 # to actually do the assignment statement for InitVars. 502 if f._field_type is _FIELD_INITVAR: 503 return None 504 505 # Now, actually generate the field assignment. 506 return _field_assign(frozen, f.name, value, self_name) 507 508 509def _init_param(f): 510 # Return the __init__ parameter string for this field. For 511 # example, the equivalent of 'x:int=3' (except instead of 'int', 512 # reference a variable set to int, and instead of '3', reference a 513 # variable set to 3). 514 if f.default is MISSING and f.default_factory is MISSING: 515 # There's no default, and no default_factory, just output the 516 # variable name and type. 517 default = '' 518 elif f.default is not MISSING: 519 # There's a default, this will be the name that's used to look 520 # it up. 521 default = f'=_dflt_{f.name}' 522 elif f.default_factory is not MISSING: 523 # There's a factory function. Set a marker. 524 default = '=_HAS_DEFAULT_FACTORY' 525 return f'{f.name}:_type_{f.name}{default}' 526 527 528def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init, 529 self_name, globals, slots): 530 # fields contains both real fields and InitVar pseudo-fields. 531 532 # Make sure we don't have fields without defaults following fields 533 # with defaults. This actually would be caught when exec-ing the 534 # function source code, but catching it here gives a better error 535 # message, and future-proofs us in case we build up the function 536 # using ast. 537 538 seen_default = False 539 for f in std_fields: 540 # Only consider the non-kw-only fields in the __init__ call. 541 if f.init: 542 if not (f.default is MISSING and f.default_factory is MISSING): 543 seen_default = True 544 elif seen_default: 545 raise TypeError(f'non-default argument {f.name!r} ' 546 'follows default argument') 547 548 locals = {f'_type_{f.name}': f.type for f in fields} 549 locals.update({ 550 'MISSING': MISSING, 551 '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY, 552 '__dataclass_builtins_object__': object, 553 }) 554 555 body_lines = [] 556 for f in fields: 557 line = _field_init(f, frozen, locals, self_name, slots) 558 # line is None means that this field doesn't require 559 # initialization (it's a pseudo-field). Just skip it. 560 if line: 561 body_lines.append(line) 562 563 # Does this class have a post-init function? 564 if has_post_init: 565 params_str = ','.join(f.name for f in fields 566 if f._field_type is _FIELD_INITVAR) 567 body_lines.append(f'{self_name}.{_POST_INIT_NAME}({params_str})') 568 569 # If no body lines, use 'pass'. 570 if not body_lines: 571 body_lines = ['pass'] 572 573 _init_params = [_init_param(f) for f in std_fields] 574 if kw_only_fields: 575 # Add the keyword-only args. Because the * can only be added if 576 # there's at least one keyword-only arg, there needs to be a test here 577 # (instead of just concatenting the lists together). 578 _init_params += ['*'] 579 _init_params += [_init_param(f) for f in kw_only_fields] 580 return _create_fn('__init__', 581 [self_name] + _init_params, 582 body_lines, 583 locals=locals, 584 globals=globals, 585 return_type=None) 586 587 588def _repr_fn(fields, globals): 589 fn = _create_fn('__repr__', 590 ('self',), 591 ['return self.__class__.__qualname__ + f"(' + 592 ', '.join([f"{f.name}={{self.{f.name}!r}}" 593 for f in fields]) + 594 ')"'], 595 globals=globals) 596 return _recursive_repr(fn) 597 598 599def _frozen_get_del_attr(cls, fields, globals): 600 locals = {'cls': cls, 601 'FrozenInstanceError': FrozenInstanceError} 602 if fields: 603 fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)' 604 else: 605 # Special case for the zero-length tuple. 606 fields_str = '()' 607 return (_create_fn('__setattr__', 608 ('self', 'name', 'value'), 609 (f'if type(self) is cls or name in {fields_str}:', 610 ' raise FrozenInstanceError(f"cannot assign to field {name!r}")', 611 f'super(cls, self).__setattr__(name, value)'), 612 locals=locals, 613 globals=globals), 614 _create_fn('__delattr__', 615 ('self', 'name'), 616 (f'if type(self) is cls or name in {fields_str}:', 617 ' raise FrozenInstanceError(f"cannot delete field {name!r}")', 618 f'super(cls, self).__delattr__(name)'), 619 locals=locals, 620 globals=globals), 621 ) 622 623 624def _cmp_fn(name, op, self_tuple, other_tuple, globals): 625 # Create a comparison function. If the fields in the object are 626 # named 'x' and 'y', then self_tuple is the string 627 # '(self.x,self.y)' and other_tuple is the string 628 # '(other.x,other.y)'. 629 630 return _create_fn(name, 631 ('self', 'other'), 632 [ 'if other.__class__ is self.__class__:', 633 f' return {self_tuple}{op}{other_tuple}', 634 'return NotImplemented'], 635 globals=globals) 636 637 638def _hash_fn(fields, globals): 639 self_tuple = _tuple_str('self', fields) 640 return _create_fn('__hash__', 641 ('self',), 642 [f'return hash({self_tuple})'], 643 globals=globals) 644 645 646def _is_classvar(a_type, typing): 647 # This test uses a typing internal class, but it's the best way to 648 # test if this is a ClassVar. 649 return (a_type is typing.ClassVar 650 or (type(a_type) is typing._GenericAlias 651 and a_type.__origin__ is typing.ClassVar)) 652 653 654def _is_initvar(a_type, dataclasses): 655 # The module we're checking against is the module we're 656 # currently in (dataclasses.py). 657 return (a_type is dataclasses.InitVar 658 or type(a_type) is dataclasses.InitVar) 659 660def _is_kw_only(a_type, dataclasses): 661 return a_type is dataclasses.KW_ONLY 662 663 664def _is_type(annotation, cls, a_module, a_type, is_type_predicate): 665 # Given a type annotation string, does it refer to a_type in 666 # a_module? For example, when checking that annotation denotes a 667 # ClassVar, then a_module is typing, and a_type is 668 # typing.ClassVar. 669 670 # It's possible to look up a_module given a_type, but it involves 671 # looking in sys.modules (again!), and seems like a waste since 672 # the caller already knows a_module. 673 674 # - annotation is a string type annotation 675 # - cls is the class that this annotation was found in 676 # - a_module is the module we want to match 677 # - a_type is the type in that module we want to match 678 # - is_type_predicate is a function called with (obj, a_module) 679 # that determines if obj is of the desired type. 680 681 # Since this test does not do a local namespace lookup (and 682 # instead only a module (global) lookup), there are some things it 683 # gets wrong. 684 685 # With string annotations, cv0 will be detected as a ClassVar: 686 # CV = ClassVar 687 # @dataclass 688 # class C0: 689 # cv0: CV 690 691 # But in this example cv1 will not be detected as a ClassVar: 692 # @dataclass 693 # class C1: 694 # CV = ClassVar 695 # cv1: CV 696 697 # In C1, the code in this function (_is_type) will look up "CV" in 698 # the module and not find it, so it will not consider cv1 as a 699 # ClassVar. This is a fairly obscure corner case, and the best 700 # way to fix it would be to eval() the string "CV" with the 701 # correct global and local namespaces. However that would involve 702 # a eval() penalty for every single field of every dataclass 703 # that's defined. It was judged not worth it. 704 705 match = _MODULE_IDENTIFIER_RE.match(annotation) 706 if match: 707 ns = None 708 module_name = match.group(1) 709 if not module_name: 710 # No module name, assume the class's module did 711 # "from dataclasses import InitVar". 712 ns = sys.modules.get(cls.__module__).__dict__ 713 else: 714 # Look up module_name in the class's module. 715 module = sys.modules.get(cls.__module__) 716 if module and module.__dict__.get(module_name) is a_module: 717 ns = sys.modules.get(a_type.__module__).__dict__ 718 if ns and is_type_predicate(ns.get(match.group(2)), a_module): 719 return True 720 return False 721 722 723def _get_field(cls, a_name, a_type, default_kw_only): 724 # Return a Field object for this field name and type. ClassVars and 725 # InitVars are also returned, but marked as such (see f._field_type). 726 # default_kw_only is the value of kw_only to use if there isn't a field() 727 # that defines it. 728 729 # If the default value isn't derived from Field, then it's only a 730 # normal default value. Convert it to a Field(). 731 default = getattr(cls, a_name, MISSING) 732 if isinstance(default, Field): 733 f = default 734 else: 735 if isinstance(default, types.MemberDescriptorType): 736 # This is a field in __slots__, so it has no default value. 737 default = MISSING 738 f = field(default=default) 739 740 # Only at this point do we know the name and the type. Set them. 741 f.name = a_name 742 f.type = a_type 743 744 # Assume it's a normal field until proven otherwise. We're next 745 # going to decide if it's a ClassVar or InitVar, everything else 746 # is just a normal field. 747 f._field_type = _FIELD 748 749 # In addition to checking for actual types here, also check for 750 # string annotations. get_type_hints() won't always work for us 751 # (see https://github.com/python/typing/issues/508 for example), 752 # plus it's expensive and would require an eval for every string 753 # annotation. So, make a best effort to see if this is a ClassVar 754 # or InitVar using regex's and checking that the thing referenced 755 # is actually of the correct type. 756 757 # For the complete discussion, see https://bugs.python.org/issue33453 758 759 # If typing has not been imported, then it's impossible for any 760 # annotation to be a ClassVar. So, only look for ClassVar if 761 # typing has been imported by any module (not necessarily cls's 762 # module). 763 typing = sys.modules.get('typing') 764 if typing: 765 if (_is_classvar(a_type, typing) 766 or (isinstance(f.type, str) 767 and _is_type(f.type, cls, typing, typing.ClassVar, 768 _is_classvar))): 769 f._field_type = _FIELD_CLASSVAR 770 771 # If the type is InitVar, or if it's a matching string annotation, 772 # then it's an InitVar. 773 if f._field_type is _FIELD: 774 # The module we're checking against is the module we're 775 # currently in (dataclasses.py). 776 dataclasses = sys.modules[__name__] 777 if (_is_initvar(a_type, dataclasses) 778 or (isinstance(f.type, str) 779 and _is_type(f.type, cls, dataclasses, dataclasses.InitVar, 780 _is_initvar))): 781 f._field_type = _FIELD_INITVAR 782 783 # Validations for individual fields. This is delayed until now, 784 # instead of in the Field() constructor, since only here do we 785 # know the field name, which allows for better error reporting. 786 787 # Special restrictions for ClassVar and InitVar. 788 if f._field_type in (_FIELD_CLASSVAR, _FIELD_INITVAR): 789 if f.default_factory is not MISSING: 790 raise TypeError(f'field {f.name} cannot have a ' 791 'default factory') 792 # Should I check for other field settings? default_factory 793 # seems the most serious to check for. Maybe add others. For 794 # example, how about init=False (or really, 795 # init=<not-the-default-init-value>)? It makes no sense for 796 # ClassVar and InitVar to specify init=<anything>. 797 798 # kw_only validation and assignment. 799 if f._field_type in (_FIELD, _FIELD_INITVAR): 800 # For real and InitVar fields, if kw_only wasn't specified use the 801 # default value. 802 if f.kw_only is MISSING: 803 f.kw_only = default_kw_only 804 else: 805 # Make sure kw_only isn't set for ClassVars 806 assert f._field_type is _FIELD_CLASSVAR 807 if f.kw_only is not MISSING: 808 raise TypeError(f'field {f.name} is a ClassVar but specifies ' 809 'kw_only') 810 811 # For real fields, disallow mutable defaults. Use unhashable as a proxy 812 # indicator for mutability. Read the __hash__ attribute from the class, 813 # not the instance. 814 if f._field_type is _FIELD and f.default.__class__.__hash__ is None: 815 raise ValueError(f'mutable default {type(f.default)} for field ' 816 f'{f.name} is not allowed: use default_factory') 817 818 return f 819 820def _set_qualname(cls, value): 821 # Ensure that the functions returned from _create_fn uses the proper 822 # __qualname__ (the class they belong to). 823 if isinstance(value, FunctionType): 824 value.__qualname__ = f"{cls.__qualname__}.{value.__name__}" 825 return value 826 827def _set_new_attribute(cls, name, value): 828 # Never overwrites an existing attribute. Returns True if the 829 # attribute already exists. 830 if name in cls.__dict__: 831 return True 832 _set_qualname(cls, value) 833 setattr(cls, name, value) 834 return False 835 836 837# Decide if/how we're going to create a hash function. Key is 838# (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to 839# take. The common case is to do nothing, so instead of providing a 840# function that is a no-op, use None to signify that. 841 842def _hash_set_none(cls, fields, globals): 843 return None 844 845def _hash_add(cls, fields, globals): 846 flds = [f for f in fields if (f.compare if f.hash is None else f.hash)] 847 return _set_qualname(cls, _hash_fn(flds, globals)) 848 849def _hash_exception(cls, fields, globals): 850 # Raise an exception. 851 raise TypeError(f'Cannot overwrite attribute __hash__ ' 852 f'in class {cls.__name__}') 853 854# 855# +-------------------------------------- unsafe_hash? 856# | +------------------------------- eq? 857# | | +------------------------ frozen? 858# | | | +---------------- has-explicit-hash? 859# | | | | 860# | | | | +------- action 861# | | | | | 862# v v v v v 863_hash_action = {(False, False, False, False): None, 864 (False, False, False, True ): None, 865 (False, False, True, False): None, 866 (False, False, True, True ): None, 867 (False, True, False, False): _hash_set_none, 868 (False, True, False, True ): None, 869 (False, True, True, False): _hash_add, 870 (False, True, True, True ): None, 871 (True, False, False, False): _hash_add, 872 (True, False, False, True ): _hash_exception, 873 (True, False, True, False): _hash_add, 874 (True, False, True, True ): _hash_exception, 875 (True, True, False, False): _hash_add, 876 (True, True, False, True ): _hash_exception, 877 (True, True, True, False): _hash_add, 878 (True, True, True, True ): _hash_exception, 879 } 880# See https://bugs.python.org/issue32929#msg312829 for an if-statement 881# version of this table. 882 883 884def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, 885 match_args, kw_only, slots, weakref_slot): 886 # Now that dicts retain insertion order, there's no reason to use 887 # an ordered dict. I am leveraging that ordering here, because 888 # derived class fields overwrite base class fields, but the order 889 # is defined by the base class, which is found first. 890 fields = {} 891 892 if cls.__module__ in sys.modules: 893 globals = sys.modules[cls.__module__].__dict__ 894 else: 895 # Theoretically this can happen if someone writes 896 # a custom string to cls.__module__. In which case 897 # such dataclass won't be fully introspectable 898 # (w.r.t. typing.get_type_hints) but will still function 899 # correctly. 900 globals = {} 901 902 setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order, 903 unsafe_hash, frozen)) 904 905 # Find our base classes in reverse MRO order, and exclude 906 # ourselves. In reversed order so that more derived classes 907 # override earlier field definitions in base classes. As long as 908 # we're iterating over them, see if any are frozen. 909 any_frozen_base = False 910 has_dataclass_bases = False 911 for b in cls.__mro__[-1:0:-1]: 912 # Only process classes that have been processed by our 913 # decorator. That is, they have a _FIELDS attribute. 914 base_fields = getattr(b, _FIELDS, None) 915 if base_fields is not None: 916 has_dataclass_bases = True 917 for f in base_fields.values(): 918 fields[f.name] = f 919 if getattr(b, _PARAMS).frozen: 920 any_frozen_base = True 921 922 # Annotations that are defined in this class (not in base 923 # classes). If __annotations__ isn't present, then this class 924 # adds no new annotations. We use this to compute fields that are 925 # added by this class. 926 # 927 # Fields are found from cls_annotations, which is guaranteed to be 928 # ordered. Default values are from class attributes, if a field 929 # has a default. If the default value is a Field(), then it 930 # contains additional info beyond (and possibly including) the 931 # actual default value. Pseudo-fields ClassVars and InitVars are 932 # included, despite the fact that they're not real fields. That's 933 # dealt with later. 934 cls_annotations = cls.__dict__.get('__annotations__', {}) 935 936 # Now find fields in our class. While doing so, validate some 937 # things, and set the default values (as class attributes) where 938 # we can. 939 cls_fields = [] 940 # Get a reference to this module for the _is_kw_only() test. 941 KW_ONLY_seen = False 942 dataclasses = sys.modules[__name__] 943 for name, type in cls_annotations.items(): 944 # See if this is a marker to change the value of kw_only. 945 if (_is_kw_only(type, dataclasses) 946 or (isinstance(type, str) 947 and _is_type(type, cls, dataclasses, dataclasses.KW_ONLY, 948 _is_kw_only))): 949 # Switch the default to kw_only=True, and ignore this 950 # annotation: it's not a real field. 951 if KW_ONLY_seen: 952 raise TypeError(f'{name!r} is KW_ONLY, but KW_ONLY ' 953 'has already been specified') 954 KW_ONLY_seen = True 955 kw_only = True 956 else: 957 # Otherwise it's a field of some type. 958 cls_fields.append(_get_field(cls, name, type, kw_only)) 959 960 for f in cls_fields: 961 fields[f.name] = f 962 963 # If the class attribute (which is the default value for this 964 # field) exists and is of type 'Field', replace it with the 965 # real default. This is so that normal class introspection 966 # sees a real default value, not a Field. 967 if isinstance(getattr(cls, f.name, None), Field): 968 if f.default is MISSING: 969 # If there's no default, delete the class attribute. 970 # This happens if we specify field(repr=False), for 971 # example (that is, we specified a field object, but 972 # no default value). Also if we're using a default 973 # factory. The class attribute should not be set at 974 # all in the post-processed class. 975 delattr(cls, f.name) 976 else: 977 setattr(cls, f.name, f.default) 978 979 # Do we have any Field members that don't also have annotations? 980 for name, value in cls.__dict__.items(): 981 if isinstance(value, Field) and not name in cls_annotations: 982 raise TypeError(f'{name!r} is a field but has no type annotation') 983 984 # Check rules that apply if we are derived from any dataclasses. 985 if has_dataclass_bases: 986 # Raise an exception if any of our bases are frozen, but we're not. 987 if any_frozen_base and not frozen: 988 raise TypeError('cannot inherit non-frozen dataclass from a ' 989 'frozen one') 990 991 # Raise an exception if we're frozen, but none of our bases are. 992 if not any_frozen_base and frozen: 993 raise TypeError('cannot inherit frozen dataclass from a ' 994 'non-frozen one') 995 996 # Remember all of the fields on our class (including bases). This 997 # also marks this class as being a dataclass. 998 setattr(cls, _FIELDS, fields) 999 1000 # Was this class defined with an explicit __hash__? Note that if 1001 # __eq__ is defined in this class, then python will automatically 1002 # set __hash__ to None. This is a heuristic, as it's possible 1003 # that such a __hash__ == None was not auto-generated, but it 1004 # close enough. 1005 class_hash = cls.__dict__.get('__hash__', MISSING) 1006 has_explicit_hash = not (class_hash is MISSING or 1007 (class_hash is None and '__eq__' in cls.__dict__)) 1008 1009 # If we're generating ordering methods, we must be generating the 1010 # eq methods. 1011 if order and not eq: 1012 raise ValueError('eq must be true if order is true') 1013 1014 # Include InitVars and regular fields (so, not ClassVars). This is 1015 # initialized here, outside of the "if init:" test, because std_init_fields 1016 # is used with match_args, below. 1017 all_init_fields = [f for f in fields.values() 1018 if f._field_type in (_FIELD, _FIELD_INITVAR)] 1019 (std_init_fields, 1020 kw_only_init_fields) = _fields_in_init_order(all_init_fields) 1021 1022 if init: 1023 # Does this class have a post-init function? 1024 has_post_init = hasattr(cls, _POST_INIT_NAME) 1025 1026 _set_new_attribute(cls, '__init__', 1027 _init_fn(all_init_fields, 1028 std_init_fields, 1029 kw_only_init_fields, 1030 frozen, 1031 has_post_init, 1032 # The name to use for the "self" 1033 # param in __init__. Use "self" 1034 # if possible. 1035 '__dataclass_self__' if 'self' in fields 1036 else 'self', 1037 globals, 1038 slots, 1039 )) 1040 1041 # Get the fields as a list, and include only real fields. This is 1042 # used in all of the following methods. 1043 field_list = [f for f in fields.values() if f._field_type is _FIELD] 1044 1045 if repr: 1046 flds = [f for f in field_list if f.repr] 1047 _set_new_attribute(cls, '__repr__', _repr_fn(flds, globals)) 1048 1049 if eq: 1050 # Create __eq__ method. There's no need for a __ne__ method, 1051 # since python will call __eq__ and negate it. 1052 flds = [f for f in field_list if f.compare] 1053 self_tuple = _tuple_str('self', flds) 1054 other_tuple = _tuple_str('other', flds) 1055 _set_new_attribute(cls, '__eq__', 1056 _cmp_fn('__eq__', '==', 1057 self_tuple, other_tuple, 1058 globals=globals)) 1059 1060 if order: 1061 # Create and set the ordering methods. 1062 flds = [f for f in field_list if f.compare] 1063 self_tuple = _tuple_str('self', flds) 1064 other_tuple = _tuple_str('other', flds) 1065 for name, op in [('__lt__', '<'), 1066 ('__le__', '<='), 1067 ('__gt__', '>'), 1068 ('__ge__', '>='), 1069 ]: 1070 if _set_new_attribute(cls, name, 1071 _cmp_fn(name, op, self_tuple, other_tuple, 1072 globals=globals)): 1073 raise TypeError(f'Cannot overwrite attribute {name} ' 1074 f'in class {cls.__name__}. Consider using ' 1075 'functools.total_ordering') 1076 1077 if frozen: 1078 for fn in _frozen_get_del_attr(cls, field_list, globals): 1079 if _set_new_attribute(cls, fn.__name__, fn): 1080 raise TypeError(f'Cannot overwrite attribute {fn.__name__} ' 1081 f'in class {cls.__name__}') 1082 1083 # Decide if/how we're going to create a hash function. 1084 hash_action = _hash_action[bool(unsafe_hash), 1085 bool(eq), 1086 bool(frozen), 1087 has_explicit_hash] 1088 if hash_action: 1089 # No need to call _set_new_attribute here, since by the time 1090 # we're here the overwriting is unconditional. 1091 cls.__hash__ = hash_action(cls, field_list, globals) 1092 1093 if not getattr(cls, '__doc__'): 1094 # Create a class doc-string. 1095 try: 1096 # In some cases fetching a signature is not possible. 1097 # But, we surely should not fail in this case. 1098 text_sig = str(inspect.signature(cls)).replace(' -> None', '') 1099 except (TypeError, ValueError): 1100 text_sig = '' 1101 cls.__doc__ = (cls.__name__ + text_sig) 1102 1103 if match_args: 1104 # I could probably compute this once 1105 _set_new_attribute(cls, '__match_args__', 1106 tuple(f.name for f in std_init_fields)) 1107 1108 # It's an error to specify weakref_slot if slots is False. 1109 if weakref_slot and not slots: 1110 raise TypeError('weakref_slot is True but slots is False') 1111 if slots: 1112 cls = _add_slots(cls, frozen, weakref_slot) 1113 1114 abc.update_abstractmethods(cls) 1115 1116 return cls 1117 1118 1119# _dataclass_getstate and _dataclass_setstate are needed for pickling frozen 1120# classes with slots. These could be slightly more performant if we generated 1121# the code instead of iterating over fields. But that can be a project for 1122# another day, if performance becomes an issue. 1123def _dataclass_getstate(self): 1124 return [getattr(self, f.name) for f in fields(self)] 1125 1126 1127def _dataclass_setstate(self, state): 1128 for field, value in zip(fields(self), state): 1129 # use setattr because dataclass may be frozen 1130 object.__setattr__(self, field.name, value) 1131 1132 1133def _get_slots(cls): 1134 match cls.__dict__.get('__slots__'): 1135 case None: 1136 return 1137 case str(slot): 1138 yield slot 1139 # Slots may be any iterable, but we cannot handle an iterator 1140 # because it will already be (partially) consumed. 1141 case iterable if not hasattr(iterable, '__next__'): 1142 yield from iterable 1143 case _: 1144 raise TypeError(f"Slots of '{cls.__name__}' cannot be determined") 1145 1146 1147def _add_slots(cls, is_frozen, weakref_slot): 1148 # Need to create a new class, since we can't set __slots__ 1149 # after a class has been created. 1150 1151 # Make sure __slots__ isn't already set. 1152 if '__slots__' in cls.__dict__: 1153 raise TypeError(f'{cls.__name__} already specifies __slots__') 1154 1155 # Create a new dict for our new class. 1156 cls_dict = dict(cls.__dict__) 1157 field_names = tuple(f.name for f in fields(cls)) 1158 # Make sure slots don't overlap with those in base classes. 1159 inherited_slots = set( 1160 itertools.chain.from_iterable(map(_get_slots, cls.__mro__[1:-1])) 1161 ) 1162 # The slots for our class. Remove slots from our base classes. Add 1163 # '__weakref__' if weakref_slot was given, unless it is already present. 1164 cls_dict["__slots__"] = tuple( 1165 itertools.filterfalse( 1166 inherited_slots.__contains__, 1167 itertools.chain( 1168 # gh-93521: '__weakref__' also needs to be filtered out if 1169 # already present in inherited_slots 1170 field_names, ('__weakref__',) if weakref_slot else () 1171 ) 1172 ), 1173 ) 1174 1175 for field_name in field_names: 1176 # Remove our attributes, if present. They'll still be 1177 # available in _MARKER. 1178 cls_dict.pop(field_name, None) 1179 1180 # Remove __dict__ itself. 1181 cls_dict.pop('__dict__', None) 1182 1183 # Clear existing `__weakref__` descriptor, it belongs to a previous type: 1184 cls_dict.pop('__weakref__', None) # gh-102069 1185 1186 # And finally create the class. 1187 qualname = getattr(cls, '__qualname__', None) 1188 cls = type(cls)(cls.__name__, cls.__bases__, cls_dict) 1189 if qualname is not None: 1190 cls.__qualname__ = qualname 1191 1192 if is_frozen: 1193 # Need this for pickling frozen classes with slots. 1194 if '__getstate__' not in cls_dict: 1195 cls.__getstate__ = _dataclass_getstate 1196 if '__setstate__' not in cls_dict: 1197 cls.__setstate__ = _dataclass_setstate 1198 1199 return cls 1200 1201 1202def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, 1203 unsafe_hash=False, frozen=False, match_args=True, 1204 kw_only=False, slots=False, weakref_slot=False): 1205 """Add dunder methods based on the fields defined in the class. 1206 1207 Examines PEP 526 __annotations__ to determine fields. 1208 1209 If init is true, an __init__() method is added to the class. If repr 1210 is true, a __repr__() method is added. If order is true, rich 1211 comparison dunder methods are added. If unsafe_hash is true, a 1212 __hash__() method is added. If frozen is true, fields may not be 1213 assigned to after instance creation. If match_args is true, the 1214 __match_args__ tuple is added. If kw_only is true, then by default 1215 all fields are keyword-only. If slots is true, a new class with a 1216 __slots__ attribute is returned. 1217 """ 1218 1219 def wrap(cls): 1220 return _process_class(cls, init, repr, eq, order, unsafe_hash, 1221 frozen, match_args, kw_only, slots, 1222 weakref_slot) 1223 1224 # See if we're being called as @dataclass or @dataclass(). 1225 if cls is None: 1226 # We're called with parens. 1227 return wrap 1228 1229 # We're called as @dataclass without parens. 1230 return wrap(cls) 1231 1232 1233def fields(class_or_instance): 1234 """Return a tuple describing the fields of this dataclass. 1235 1236 Accepts a dataclass or an instance of one. Tuple elements are of 1237 type Field. 1238 """ 1239 1240 # Might it be worth caching this, per class? 1241 try: 1242 fields = getattr(class_or_instance, _FIELDS) 1243 except AttributeError: 1244 raise TypeError('must be called with a dataclass type or instance') from None 1245 1246 # Exclude pseudo-fields. Note that fields is sorted by insertion 1247 # order, so the order of the tuple is as the fields were defined. 1248 return tuple(f for f in fields.values() if f._field_type is _FIELD) 1249 1250 1251def _is_dataclass_instance(obj): 1252 """Returns True if obj is an instance of a dataclass.""" 1253 return hasattr(type(obj), _FIELDS) 1254 1255 1256def is_dataclass(obj): 1257 """Returns True if obj is a dataclass or an instance of a 1258 dataclass.""" 1259 cls = obj if isinstance(obj, type) else type(obj) 1260 return hasattr(cls, _FIELDS) 1261 1262 1263def asdict(obj, *, dict_factory=dict): 1264 """Return the fields of a dataclass instance as a new dictionary mapping 1265 field names to field values. 1266 1267 Example usage:: 1268 1269 @dataclass 1270 class C: 1271 x: int 1272 y: int 1273 1274 c = C(1, 2) 1275 assert asdict(c) == {'x': 1, 'y': 2} 1276 1277 If given, 'dict_factory' will be used instead of built-in dict. 1278 The function applies recursively to field values that are 1279 dataclass instances. This will also look into built-in containers: 1280 tuples, lists, and dicts. 1281 """ 1282 if not _is_dataclass_instance(obj): 1283 raise TypeError("asdict() should be called on dataclass instances") 1284 return _asdict_inner(obj, dict_factory) 1285 1286 1287def _asdict_inner(obj, dict_factory): 1288 if _is_dataclass_instance(obj): 1289 result = [] 1290 for f in fields(obj): 1291 value = _asdict_inner(getattr(obj, f.name), dict_factory) 1292 result.append((f.name, value)) 1293 return dict_factory(result) 1294 elif isinstance(obj, tuple) and hasattr(obj, '_fields'): 1295 # obj is a namedtuple. Recurse into it, but the returned 1296 # object is another namedtuple of the same type. This is 1297 # similar to how other list- or tuple-derived classes are 1298 # treated (see below), but we just need to create them 1299 # differently because a namedtuple's __init__ needs to be 1300 # called differently (see bpo-34363). 1301 1302 # I'm not using namedtuple's _asdict() 1303 # method, because: 1304 # - it does not recurse in to the namedtuple fields and 1305 # convert them to dicts (using dict_factory). 1306 # - I don't actually want to return a dict here. The main 1307 # use case here is json.dumps, and it handles converting 1308 # namedtuples to lists. Admittedly we're losing some 1309 # information here when we produce a json list instead of a 1310 # dict. Note that if we returned dicts here instead of 1311 # namedtuples, we could no longer call asdict() on a data 1312 # structure where a namedtuple was used as a dict key. 1313 1314 return type(obj)(*[_asdict_inner(v, dict_factory) for v in obj]) 1315 elif isinstance(obj, (list, tuple)): 1316 # Assume we can create an object of this type by passing in a 1317 # generator (which is not true for namedtuples, handled 1318 # above). 1319 return type(obj)(_asdict_inner(v, dict_factory) for v in obj) 1320 elif isinstance(obj, dict): 1321 return type(obj)((_asdict_inner(k, dict_factory), 1322 _asdict_inner(v, dict_factory)) 1323 for k, v in obj.items()) 1324 else: 1325 return copy.deepcopy(obj) 1326 1327 1328def astuple(obj, *, tuple_factory=tuple): 1329 """Return the fields of a dataclass instance as a new tuple of field values. 1330 1331 Example usage:: 1332 1333 @dataclass 1334 class C: 1335 x: int 1336 y: int 1337 1338 c = C(1, 2) 1339 assert astuple(c) == (1, 2) 1340 1341 If given, 'tuple_factory' will be used instead of built-in tuple. 1342 The function applies recursively to field values that are 1343 dataclass instances. This will also look into built-in containers: 1344 tuples, lists, and dicts. 1345 """ 1346 1347 if not _is_dataclass_instance(obj): 1348 raise TypeError("astuple() should be called on dataclass instances") 1349 return _astuple_inner(obj, tuple_factory) 1350 1351 1352def _astuple_inner(obj, tuple_factory): 1353 if _is_dataclass_instance(obj): 1354 result = [] 1355 for f in fields(obj): 1356 value = _astuple_inner(getattr(obj, f.name), tuple_factory) 1357 result.append(value) 1358 return tuple_factory(result) 1359 elif isinstance(obj, tuple) and hasattr(obj, '_fields'): 1360 # obj is a namedtuple. Recurse into it, but the returned 1361 # object is another namedtuple of the same type. This is 1362 # similar to how other list- or tuple-derived classes are 1363 # treated (see below), but we just need to create them 1364 # differently because a namedtuple's __init__ needs to be 1365 # called differently (see bpo-34363). 1366 return type(obj)(*[_astuple_inner(v, tuple_factory) for v in obj]) 1367 elif isinstance(obj, (list, tuple)): 1368 # Assume we can create an object of this type by passing in a 1369 # generator (which is not true for namedtuples, handled 1370 # above). 1371 return type(obj)(_astuple_inner(v, tuple_factory) for v in obj) 1372 elif isinstance(obj, dict): 1373 return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory)) 1374 for k, v in obj.items()) 1375 else: 1376 return copy.deepcopy(obj) 1377 1378 1379def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, 1380 repr=True, eq=True, order=False, unsafe_hash=False, 1381 frozen=False, match_args=True, kw_only=False, slots=False, 1382 weakref_slot=False): 1383 """Return a new dynamically created dataclass. 1384 1385 The dataclass name will be 'cls_name'. 'fields' is an iterable 1386 of either (name), (name, type) or (name, type, Field) objects. If type is 1387 omitted, use the string 'typing.Any'. Field objects are created by 1388 the equivalent of calling 'field(name, type [, Field-info])'.:: 1389 1390 C = make_dataclass('C', ['x', ('y', int), ('z', int, field(init=False))], bases=(Base,)) 1391 1392 is equivalent to:: 1393 1394 @dataclass 1395 class C(Base): 1396 x: 'typing.Any' 1397 y: int 1398 z: int = field(init=False) 1399 1400 For the bases and namespace parameters, see the builtin type() function. 1401 1402 The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to 1403 dataclass(). 1404 """ 1405 1406 if namespace is None: 1407 namespace = {} 1408 1409 # While we're looking through the field names, validate that they 1410 # are identifiers, are not keywords, and not duplicates. 1411 seen = set() 1412 annotations = {} 1413 defaults = {} 1414 for item in fields: 1415 if isinstance(item, str): 1416 name = item 1417 tp = 'typing.Any' 1418 elif len(item) == 2: 1419 name, tp, = item 1420 elif len(item) == 3: 1421 name, tp, spec = item 1422 defaults[name] = spec 1423 else: 1424 raise TypeError(f'Invalid field: {item!r}') 1425 1426 if not isinstance(name, str) or not name.isidentifier(): 1427 raise TypeError(f'Field names must be valid identifiers: {name!r}') 1428 if keyword.iskeyword(name): 1429 raise TypeError(f'Field names must not be keywords: {name!r}') 1430 if name in seen: 1431 raise TypeError(f'Field name duplicated: {name!r}') 1432 1433 seen.add(name) 1434 annotations[name] = tp 1435 1436 # Update 'ns' with the user-supplied namespace plus our calculated values. 1437 def exec_body_callback(ns): 1438 ns.update(namespace) 1439 ns.update(defaults) 1440 ns['__annotations__'] = annotations 1441 1442 # We use `types.new_class()` instead of simply `type()` to allow dynamic creation 1443 # of generic dataclasses. 1444 cls = types.new_class(cls_name, bases, {}, exec_body_callback) 1445 1446 # Apply the normal decorator. 1447 return dataclass(cls, init=init, repr=repr, eq=eq, order=order, 1448 unsafe_hash=unsafe_hash, frozen=frozen, 1449 match_args=match_args, kw_only=kw_only, slots=slots, 1450 weakref_slot=weakref_slot) 1451 1452 1453def replace(obj, /, **changes): 1454 """Return a new object replacing specified fields with new values. 1455 1456 This is especially useful for frozen classes. Example usage:: 1457 1458 @dataclass(frozen=True) 1459 class C: 1460 x: int 1461 y: int 1462 1463 c = C(1, 2) 1464 c1 = replace(c, x=3) 1465 assert c1.x == 3 and c1.y == 2 1466 """ 1467 1468 # We're going to mutate 'changes', but that's okay because it's a 1469 # new dict, even if called with 'replace(obj, **my_changes)'. 1470 1471 if not _is_dataclass_instance(obj): 1472 raise TypeError("replace() should be called on dataclass instances") 1473 1474 # It's an error to have init=False fields in 'changes'. 1475 # If a field is not in 'changes', read its value from the provided obj. 1476 1477 for f in getattr(obj, _FIELDS).values(): 1478 # Only consider normal fields or InitVars. 1479 if f._field_type is _FIELD_CLASSVAR: 1480 continue 1481 1482 if not f.init: 1483 # Error if this field is specified in changes. 1484 if f.name in changes: 1485 raise ValueError(f'field {f.name} is declared with ' 1486 'init=False, it cannot be specified with ' 1487 'replace()') 1488 continue 1489 1490 if f.name not in changes: 1491 if f._field_type is _FIELD_INITVAR and f.default is MISSING: 1492 raise ValueError(f"InitVar {f.name!r} " 1493 'must be specified with replace()') 1494 changes[f.name] = getattr(obj, f.name) 1495 1496 # Create the new object, which calls __init__() and 1497 # __post_init__() (if defined), using all of the init fields we've 1498 # added and/or left in 'changes'. If there are values supplied in 1499 # changes that aren't fields, this will correctly raise a 1500 # TypeError. 1501 return obj.__class__(**changes) 1502