@@ -711,22 +711,20 @@ def _is_kw_only(a_type, dataclasses):
711711 return a_type is dataclasses .KW_ONLY
712712
713713
714- def _is_type (annotation , cls , a_module , a_type , is_type_predicate ):
715- # Given a type annotation string, does it refer to a_type in
716- # a_module? For example, when checking that annotation denotes a
717- # ClassVar, then a_module is typing, and a_type is
718- # typing.ClassVar.
714+ def _is_type (annotation , cls , is_type_predicate , * is_type_predicate_args ):
715+ # Loosely parse a string annotation and pass the result to is_type_predicate,
716+ # along with any additional arguments it might require.
719717
720- # It's possible to look up a_module given a_type, but it involves
721- # looking in sys.modules (again!), and seems like a waste since
722- # the caller already knows a_module.
718+ # We can't perform a full type hint evaluation at the point where @dataclass
719+ # was invoked because class's module is not fully initialized yet. So we resort
720+ # to parsing string annotation using regexp, and extracting a type before
721+ # the first square bracket.
723722
724723 # - annotation is a string type annotation
725724 # - cls is the class that this annotation was found in
726- # - a_module is the module we want to match
727- # - a_type is the type in that module we want to match
728- # - is_type_predicate is a function called with (obj, a_module)
725+ # - is_type_predicate is a function called with (obj, *is_type_predicate_args)
729726 # that determines if obj is of the desired type.
727+ # - is_type_predicate_args is additional arguments forwarded to is_type_predicate
730728
731729 # Since this test does not do a local namespace lookup (and
732730 # instead only a module (global) lookup), there are some things it
@@ -756,30 +754,19 @@ def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
756754 if not match :
757755 return False
758756
759- ns = None
760757 module_name = match .group (1 )
761758 type_name = match .group (2 )
762759
763760 if not module_name :
764761 # No module name, assume the class's module did
765762 # "from dataclasses import InitVar".
766- ns = sys .modules .get (cls .__module__ ). __dict__
763+ ns = sys .modules .get (cls .__module__ )
767764 else :
768765 # Look up module_name in the class's module.
769766 cls_module = sys .modules .get (cls .__module__ )
770- if not cls_module :
771- return False
767+ ns = cls_module .__dict__ .get (module_name )
772768
773- a_type_module = cls_module .__dict__ .get (module_name )
774- if (
775- isinstance (a_type_module , types .ModuleType )
776- # Handle cases when a_type is not defined in
777- # the referenced module, e.g. 'dataclasses.ClassVar[int]'
778- and a_type_module .__dict__ .get (type_name ) is a_type
779- ):
780- ns = sys .modules .get (a_type .__module__ ).__dict__
781-
782- return ns and is_type_predicate (ns .get (type_name ), a_module )
769+ return is_type_predicate (getattr (ns , type_name , None ), * is_type_predicate_args )
783770
784771
785772def _get_field (cls , a_name , a_type , default_kw_only ):
@@ -826,8 +813,7 @@ def _get_field(cls, a_name, a_type, default_kw_only):
826813 if typing :
827814 if (_is_classvar (a_type , typing )
828815 or (isinstance (f .type , str )
829- and _is_type (f .type , cls , typing , typing .ClassVar ,
830- _is_classvar ))):
816+ and _is_type (f .type , cls , _is_classvar , typing ))):
831817 f ._field_type = _FIELD_CLASSVAR
832818
833819 # If the type is InitVar, or if it's a matching string annotation,
@@ -838,8 +824,7 @@ def _get_field(cls, a_name, a_type, default_kw_only):
838824 dataclasses = sys .modules [__name__ ]
839825 if (_is_initvar (a_type , dataclasses )
840826 or (isinstance (f .type , str )
841- and _is_type (f .type , cls , dataclasses , dataclasses .InitVar ,
842- _is_initvar ))):
827+ and _is_type (f .type , cls , _is_initvar , dataclasses ))):
843828 f ._field_type = _FIELD_INITVAR
844829
845830 # Validations for individual fields. This is delayed until now,
@@ -1012,8 +997,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,
1012997 # See if this is a marker to change the value of kw_only.
1013998 if (_is_kw_only (type , dataclasses )
1014999 or (isinstance (type , str )
1015- and _is_type (type , cls , dataclasses , dataclasses .KW_ONLY ,
1016- _is_kw_only ))):
1000+ and _is_type (type , cls , _is_kw_only , dataclasses ))):
10171001 # Switch the default to kw_only=True, and ignore this
10181002 # annotation: it's not a real field.
10191003 if KW_ONLY_seen :
0 commit comments