1616 'Field' ,
1717 'FrozenInstanceError' ,
1818 'InitVar' ,
19+ 'KW_ONLY' ,
1920 'MISSING' ,
2021
2122 # Helper functions.
163164# +-------+-------+-------+
164165# | True | add | | <- the default
165166# +=======+=======+=======+
166- # __match_args__ is a tuple of __init__ parameter names; non-init fields must
167- # be matched by keyword.
167+ # __match_args__ is always added unless the class already defines it. It is a
168+ # tuple of __init__ parameter names; non-init fields must be matched by keyword.
168169
169170
170171# Raised when an attempt is made to modify a frozen class.
@@ -184,6 +185,12 @@ class _MISSING_TYPE:
184185 pass
185186MISSING = _MISSING_TYPE ()
186187
188+ # A sentinel object to indicate that following fields are keyword-only by
189+ # default. Use a class to give it a better repr.
190+ class _KW_ONLY_TYPE :
191+ pass
192+ KW_ONLY = _KW_ONLY_TYPE ()
193+
187194# Since most per-field metadata will be unused, create an empty
188195# read-only proxy that can be shared among all fields.
189196_EMPTY_METADATA = types .MappingProxyType ({})
@@ -232,7 +239,6 @@ def __repr__(self):
232239 def __class_getitem__ (cls , type ):
233240 return InitVar (type )
234241
235-
236242# Instances of Field are only ever created from within this module,
237243# and only from the field() function, although Field instances are
238244# exposed externally as (conceptually) read-only objects.
@@ -253,11 +259,12 @@ class Field:
253259 'init' ,
254260 'compare' ,
255261 'metadata' ,
262+ 'kw_only' ,
256263 '_field_type' , # Private: not to be used by user code.
257264 )
258265
259266 def __init__ (self , default , default_factory , init , repr , hash , compare ,
260- metadata ):
267+ metadata , kw_only ):
261268 self .name = None
262269 self .type = None
263270 self .default = default
@@ -269,6 +276,7 @@ def __init__(self, default, default_factory, init, repr, hash, compare,
269276 self .metadata = (_EMPTY_METADATA
270277 if metadata is None else
271278 types .MappingProxyType (metadata ))
279+ self .kw_only = kw_only
272280 self ._field_type = None
273281
274282 def __repr__ (self ):
@@ -282,6 +290,7 @@ def __repr__(self):
282290 f'hash={ self .hash !r} ,'
283291 f'compare={ self .compare !r} ,'
284292 f'metadata={ self .metadata !r} ,'
293+ f'kw_only={ self .kw_only !r} ,'
285294 f'_field_type={ self ._field_type } '
286295 ')' )
287296
@@ -335,25 +344,36 @@ def __repr__(self):
335344# so that a type checker can be told (via overloads) that this is a
336345# function whose type depends on its parameters.
337346def field (* , default = MISSING , default_factory = MISSING , init = True , repr = True ,
338- hash = None , compare = True , metadata = None ):
347+ hash = None , compare = True , metadata = None , kw_only = MISSING ):
339348 """Return an object to identify dataclass fields.
340349
341350 default is the default value of the field. default_factory is a
342351 0-argument function called to initialize a field's value. If init
343- is True, the field will be a parameter to the class's __init__()
344- function. If repr is True, the field will be included in the
345- object's repr(). If hash is True, the field will be included in
346- the object's hash(). If compare is True, the field will be used
347- in comparison functions. metadata, if specified, must be a
348- mapping which is stored but not otherwise examined by dataclass.
352+ is true, the field will be a parameter to the class's __init__()
353+ function. If repr is true, the field will be included in the
354+ object's repr(). If hash is true, the field will be included in the
355+ object's hash(). If compare is true, the field will be used in
356+ comparison functions. metadata, if specified, must be a mapping
357+ which is stored but not otherwise examined by dataclass. If kw_only
358+ is true, the field will become a keyword-only parameter to
359+ __init__().
349360
350361 It is an error to specify both default and default_factory.
351362 """
352363
353364 if default is not MISSING and default_factory is not MISSING :
354365 raise ValueError ('cannot specify both default and default_factory' )
355366 return Field (default , default_factory , init , repr , hash , compare ,
356- metadata )
367+ metadata , kw_only )
368+
369+
370+ def _fields_in_init_order (fields ):
371+ # Returns the fields as __init__ will output them. It returns 2 tuples:
372+ # the first for normal args, and the second for keyword args.
373+
374+ return (tuple (f for f in fields if f .init and not f .kw_only ),
375+ tuple (f for f in fields if f .init and f .kw_only )
376+ )
357377
358378
359379def _tuple_str (obj_name , fields ):
@@ -410,7 +430,6 @@ def _create_fn(name, args, body, *, globals=None, locals=None,
410430
411431 local_vars = ', ' .join (locals .keys ())
412432 txt = f"def __create_fn__({ local_vars } ):\n { txt } \n return { name } "
413-
414433 ns = {}
415434 exec (txt , globals , ns )
416435 return ns ['__create_fn__' ](** locals )
@@ -501,17 +520,19 @@ def _init_param(f):
501520 return f'{ f .name } :_type_{ f .name } { default } '
502521
503522
504- def _init_fn (fields , frozen , has_post_init , self_name , globals ):
523+ def _init_fn (fields , std_fields , kw_only_fields , frozen , has_post_init ,
524+ self_name , globals ):
505525 # fields contains both real fields and InitVar pseudo-fields.
506526
507527 # Make sure we don't have fields without defaults following fields
508528 # with defaults. This actually would be caught when exec-ing the
509529 # function source code, but catching it here gives a better error
510530 # message, and future-proofs us in case we build up the function
511531 # using ast.
532+
512533 seen_default = False
513- for f in fields :
514- # Only consider fields in the __init__ call.
534+ for f in std_fields :
535+ # Only consider the non-kw-only fields in the __init__ call.
515536 if f .init :
516537 if not (f .default is MISSING and f .default_factory is MISSING ):
517538 seen_default = True
@@ -543,8 +564,15 @@ def _init_fn(fields, frozen, has_post_init, self_name, globals):
543564 if not body_lines :
544565 body_lines = ['pass' ]
545566
567+ _init_params = [_init_param (f ) for f in std_fields ]
568+ if kw_only_fields :
569+ # Add the keyword-only args. Because the * can only be added if
570+ # there's at least one keyword-only arg, there needs to be a test here
571+ # (instead of just concatenting the lists together).
572+ _init_params += ['*' ]
573+ _init_params += [_init_param (f ) for f in kw_only_fields ]
546574 return _create_fn ('__init__' ,
547- [self_name ] + [ _init_param ( f ) for f in fields if f . init ] ,
575+ [self_name ] + _init_params ,
548576 body_lines ,
549577 locals = locals ,
550578 globals = globals ,
@@ -623,6 +651,9 @@ def _is_initvar(a_type, dataclasses):
623651 return (a_type is dataclasses .InitVar
624652 or type (a_type ) is dataclasses .InitVar )
625653
654+ def _is_kw_only (a_type , dataclasses ):
655+ return a_type is dataclasses .KW_ONLY
656+
626657
627658def _is_type (annotation , cls , a_module , a_type , is_type_predicate ):
628659 # Given a type annotation string, does it refer to a_type in
@@ -683,10 +714,11 @@ def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
683714 return False
684715
685716
686- def _get_field (cls , a_name , a_type ):
687- # Return a Field object for this field name and type. ClassVars
688- # and InitVars are also returned, but marked as such (see
689- # f._field_type).
717+ def _get_field (cls , a_name , a_type , default_kw_only ):
718+ # Return a Field object for this field name and type. ClassVars and
719+ # InitVars are also returned, but marked as such (see f._field_type).
720+ # default_kw_only is the value of kw_only to use if there isn't a field()
721+ # that defines it.
690722
691723 # If the default value isn't derived from Field, then it's only a
692724 # normal default value. Convert it to a Field().
@@ -757,6 +789,19 @@ def _get_field(cls, a_name, a_type):
757789 # init=<not-the-default-init-value>)? It makes no sense for
758790 # ClassVar and InitVar to specify init=<anything>.
759791
792+ # kw_only validation and assignment.
793+ if f ._field_type in (_FIELD , _FIELD_INITVAR ):
794+ # For real and InitVar fields, if kw_only wasn't specified use the
795+ # default value.
796+ if f .kw_only is MISSING :
797+ f .kw_only = default_kw_only
798+ else :
799+ # Make sure kw_only isn't set for ClassVars
800+ assert f ._field_type is _FIELD_CLASSVAR
801+ if f .kw_only is not MISSING :
802+ raise TypeError (f'field { f .name } is a ClassVar but specifies '
803+ 'kw_only' )
804+
760805 # For real fields, disallow mutable defaults for known types.
761806 if f ._field_type is _FIELD and isinstance (f .default , (list , dict , set )):
762807 raise ValueError (f'mutable default { type (f .default )} for field '
@@ -829,7 +874,7 @@ def _hash_exception(cls, fields, globals):
829874
830875
831876def _process_class (cls , init , repr , eq , order , unsafe_hash , frozen ,
832- match_args ):
877+ match_args , kw_only ):
833878 # Now that dicts retain insertion order, there's no reason to use
834879 # an ordered dict. I am leveraging that ordering here, because
835880 # derived class fields overwrite base class fields, but the order
@@ -883,8 +928,22 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
883928 # Now find fields in our class. While doing so, validate some
884929 # things, and set the default values (as class attributes) where
885930 # we can.
886- cls_fields = [_get_field (cls , name , type )
887- for name , type in cls_annotations .items ()]
931+ cls_fields = []
932+ # Get a reference to this module for the _is_kw_only() test.
933+ dataclasses = sys .modules [__name__ ]
934+ for name , type in cls_annotations .items ():
935+ # See if this is a marker to change the value of kw_only.
936+ if (_is_kw_only (type , dataclasses )
937+ or (isinstance (type , str )
938+ and _is_type (type , cls , dataclasses , dataclasses .KW_ONLY ,
939+ _is_kw_only ))):
940+ # Switch the default to kw_only=True, and ignore this
941+ # annotation: it's not a real field.
942+ kw_only = True
943+ else :
944+ # Otherwise it's a field of some type.
945+ cls_fields .append (_get_field (cls , name , type , kw_only ))
946+
888947 for f in cls_fields :
889948 fields [f .name ] = f
890949
@@ -939,15 +998,22 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
939998 if order and not eq :
940999 raise ValueError ('eq must be true if order is true' )
9411000
1001+ # Include InitVars and regular fields (so, not ClassVars). This is
1002+ # initialized here, outside of the "if init:" test, because std_init_fields
1003+ # is used with match_args, below.
1004+ all_init_fields = [f for f in fields .values ()
1005+ if f ._field_type in (_FIELD , _FIELD_INITVAR )]
1006+ (std_init_fields ,
1007+ kw_only_init_fields ) = _fields_in_init_order (all_init_fields )
1008+
9421009 if init :
9431010 # Does this class have a post-init function?
9441011 has_post_init = hasattr (cls , _POST_INIT_NAME )
9451012
946- # Include InitVars and regular fields (so, not ClassVars).
947- flds = [f for f in fields .values ()
948- if f ._field_type in (_FIELD , _FIELD_INITVAR )]
9491013 _set_new_attribute (cls , '__init__' ,
950- _init_fn (flds ,
1014+ _init_fn (all_init_fields ,
1015+ std_init_fields ,
1016+ kw_only_init_fields ,
9511017 frozen ,
9521018 has_post_init ,
9531019 # The name to use for the "self"
@@ -1016,16 +1082,18 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
10161082 str (inspect .signature (cls )).replace (' -> None' , '' ))
10171083
10181084 if match_args :
1085+ # I could probably compute this once
10191086 _set_new_attribute (cls , '__match_args__' ,
1020- tuple (f .name for f in field_list if f . init ))
1087+ tuple (f .name for f in std_init_fields ))
10211088
10221089 abc .update_abstractmethods (cls )
10231090
10241091 return cls
10251092
10261093
10271094def dataclass (cls = None , / , * , init = True , repr = True , eq = True , order = False ,
1028- unsafe_hash = False , frozen = False , match_args = True ):
1095+ unsafe_hash = False , frozen = False , match_args = True ,
1096+ kw_only = False ):
10291097 """Returns the same class as was passed in, with dunder methods
10301098 added based on the fields defined in the class.
10311099
@@ -1036,12 +1104,13 @@ def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
10361104 comparison dunder methods are added. If unsafe_hash is true, a
10371105 __hash__() method function is added. If frozen is true, fields may
10381106 not be assigned to after instance creation. If match_args is true,
1039- the __match_args__ tuple is added.
1107+ the __match_args__ tuple is added. If kw_only is true, then by
1108+ default all fields are keyword-only.
10401109 """
10411110
10421111 def wrap (cls ):
10431112 return _process_class (cls , init , repr , eq , order , unsafe_hash ,
1044- frozen , match_args )
1113+ frozen , match_args , kw_only )
10451114
10461115 # See if we're being called as @dataclass or @dataclass().
10471116 if cls is None :
0 commit comments