(cls, a_name, a_type, default_kw_only)
| 823 | |
| 824 | |
| 825 | def _get_field(cls, a_name, a_type, default_kw_only): |
| 826 | # Return a Field object for this field name and type. ClassVars and |
| 827 | # InitVars are also returned, but marked as such (see f._field_type). |
| 828 | # default_kw_only is the value of kw_only to use if there isn't a field() |
| 829 | # that defines it. |
| 830 | |
| 831 | # If the default value isn't derived from Field, then it's only a |
| 832 | # normal default value. Convert it to a Field(). |
| 833 | default = getattr(cls, a_name, MISSING) |
| 834 | if isinstance(default, Field): |
| 835 | f = default |
| 836 | else: |
| 837 | if isinstance(default, types.MemberDescriptorType): |
| 838 | # This is a field in __slots__, so it has no default value. |
| 839 | default = MISSING |
| 840 | f = field(default=default) |
| 841 | |
| 842 | # Only at this point do we know the name and the type. Set them. |
| 843 | f.name = a_name |
| 844 | f.type = a_type |
| 845 | |
| 846 | # Assume it's a normal field until proven otherwise. We're next |
| 847 | # going to decide if it's a ClassVar or InitVar, everything else |
| 848 | # is just a normal field. |
| 849 | f._field_type = _FIELD |
| 850 | |
| 851 | # In addition to checking for actual types here, also check for |
| 852 | # string annotations. get_type_hints() won't always work for us |
| 853 | # (see https://github.com/python/typing/issues/508 for example), |
| 854 | # plus it's expensive and would require an eval for every string |
| 855 | # annotation. So, make a best effort to see if this is a ClassVar |
| 856 | # or InitVar using regex's and checking that the thing referenced |
| 857 | # is actually of the correct type. |
| 858 | |
| 859 | # For the complete discussion, see https://bugs.python.org/issue33453 |
| 860 | |
| 861 | # If typing has not been imported, then it's impossible for any |
| 862 | # annotation to be a ClassVar. So, only look for ClassVar if |
| 863 | # typing has been imported by any module (not necessarily cls's |
| 864 | # module). |
| 865 | typing = sys.modules.get('typing') |
| 866 | if typing: |
| 867 | if (_is_classvar(a_type, typing) |
| 868 | or (isinstance(f.type, str) |
| 869 | and _is_type(f.type, cls, typing, typing.ClassVar, |
| 870 | _is_classvar))): |
| 871 | f._field_type = _FIELD_CLASSVAR |
| 872 | |
| 873 | # If the type is InitVar, or if it's a matching string annotation, |
| 874 | # then it's an InitVar. |
| 875 | if f._field_type is _FIELD: |
| 876 | # The module we're checking against is the module we're |
| 877 | # currently in (dataclasses.py). |
| 878 | dataclasses = sys.modules[__name__] |
| 879 | if (_is_initvar(a_type, dataclasses) |
| 880 | or (isinstance(f.type, str) |
| 881 | and _is_type(f.type, cls, dataclasses, dataclasses.InitVar, |
| 882 | _is_initvar))): |
no test coverage detected
searching dependent graphs…