def test_mapping(self): self.assertTrue(typing_utils.is_mapping_type(typing.Mapping[str, int])) self.assertTrue(typing_utils.is_mapping_type(typing.Dict[str, int])) self.assertTrue(typing_utils.is_mapping_type(typing.Dict)) self.assertFalse(typing_utils.is_mapping_type(str)) self.assertFalse(typing_utils.is_mapping_type(int)) self.assertFalse(typing_utils.is_mapping_type(TypingTest)) self.assertEqual(typing_utils.get_mapping_value_type(typing.Mapping[str, int]), int) self.assertEqual(typing_utils.get_mapping_value_type(typing.Dict[str, int]), int) self.assertAnyTypeEquivalent(typing_utils.get_mapping_value_type(typing.Dict)) with self.assertRaises(ValueError): typing_utils.get_mapping_value_type(str)
def get_type_info(tp: type) -> TypeInfo: """ Reduce iterable and optional types to their 'base' types. """ is_final = typing_utils.is_final_type(tp) if is_final: tp = typing_utils.get_final_type(tp) if tp is typing.Any: # This used to be supported, but Python 3.10 raises in get_type_hints() if it encounters a plain Final hint. raise TypeError( 'Plain typing.Final is not valid as a type argument.') is_nullable = typing_utils.is_optional_type(tp) if is_nullable: tp = typing_utils.get_optional_type(tp) is_mapping = typing_utils.is_mapping_type(tp) is_many = typing_utils.is_iterable_type(tp) if is_mapping: tp = typing_utils.get_mapping_value_type(tp) elif is_many: # This must be elif (instead of if), as otherwise we'd reduce mappings twice as they're also iterable tp = typing_utils.get_iterable_element_type(tp) if typing_utils.is_type_variable(tp): tp = typing_utils.get_variable_type_substitute(tp) if tp is typing.Any: tp = None return TypeInfo(is_many, is_mapping, is_final, is_nullable, tp)
def get_type_info( tp: type, default_value_type: typing.Optional[type] = None) -> TypeInfo: """ Reduce iterable and optional types to their 'base' types. """ is_final = typing_utils.is_final_type(tp) if is_final: tp = typing_utils.get_final_type(tp) if tp is typing.Any and default_value_type is not None: tp = default_value_type is_optional = typing_utils.is_optional_type(tp) if is_optional: tp = typing_utils.get_optional_type(tp) is_mapping = typing_utils.is_mapping_type(tp) is_many = typing_utils.is_iterable_type(tp) if is_mapping: tp = typing_utils.get_mapping_value_type(tp) elif is_many: # This must be elif (instead of if), as otherwise we'd reduce mappings twice as they're also iterable tp = typing_utils.get_iterable_element_type(tp) if typing_utils.is_type_variable(tp): tp = typing_utils.get_variable_type_substitute(tp) if tp is typing.Any: tp = None return TypeInfo(is_many, is_mapping, is_final, is_optional, tp)
def test_pep585(self): self.assertTrue(typing_utils.is_iterable_type(list[int])) self.assertEqual(typing_utils.get_iterable_element_type(list[int]), int) self.assertTrue(typing_utils.is_mapping_type(dict[str, int])) self.assertTrue(typing_utils.get_mapping_value_type(dict[str, int]), int)
def get_type_info(tp: type) -> TypeInfo: """ Reduce iterable and optional types to their 'base' types. """ is_optional = typing_utils.is_optional_type(tp) if is_optional: tp = typing_utils.get_optional_type(tp) is_mapping = typing_utils.is_mapping_type(tp) is_many = typing_utils.is_iterable_type(tp) if is_mapping: tp = typing_utils.get_mapping_value_type(tp) elif is_many: # This must be elif (instead of if), as otherwise we'd reduce mappings twice tp = typing_utils.get_iterable_element_type(tp) return TypeInfo(is_many, is_mapping, is_optional, tp)