def transform_typing_type(type_annotation): if type_annotation is typing.List: return List elif type_annotation is typing.Set: return Set elif type_annotation is typing.Tuple: return Tuple elif type_annotation is typing.Dict: return Dict elif is_closed_python_list_type(type_annotation): return List[transform_typing_type(get_list_inner_type(type_annotation))] elif is_closed_python_set_type(type_annotation): return Set[transform_typing_type(get_set_inner_type(type_annotation))] elif is_closed_python_tuple_type(type_annotation): transformed_types = [ transform_typing_type(tt) for tt in get_tuple_type_params(type_annotation) ] return create_typed_tuple(*transformed_types) elif is_closed_python_optional_type(type_annotation): return Optional[transform_typing_type(get_optional_inner_type(type_annotation))] elif is_closed_python_dict_type(type_annotation): key_type, value_type = get_dict_key_value_types(type_annotation) return create_typed_runtime_dict( transform_typing_type(key_type), transform_typing_type(value_type) ) else: return type_annotation
def transform_typing_type(type_annotation): from dagster.core.types.runtime.python_dict import create_typed_runtime_dict if type_annotation is typing.List: return List elif type_annotation is typing.Set: return Set elif type_annotation is typing.Tuple: return Tuple elif type_annotation is typing.Dict: return Dict elif is_closed_python_list_type(type_annotation): return WrappingListType( transform_typing_type(get_list_inner_type(type_annotation))) elif is_closed_python_set_type(type_annotation): return WrappingSetType( transform_typing_type(get_set_inner_type(type_annotation))) elif is_closed_python_tuple_type(type_annotation): transformed_types = [ transform_typing_type(tt) for tt in get_tuple_type_params(type_annotation) ] return WrappingTupleType(tuple(transformed_types)) elif is_closed_python_optional_type(type_annotation): return WrappingNullableType( transform_typing_type(get_optional_inner_type(type_annotation))) elif is_closed_python_dict_type(type_annotation): key_type, value_type = get_dict_key_value_types(type_annotation) return create_typed_runtime_dict(transform_typing_type(key_type), transform_typing_type(value_type)) else: return type_annotation
def test_is_typing_optional_py_3(): assert is_closed_python_optional_type(typing.Optional[int]) assert not is_closed_python_optional_type(typing.Optional) assert not is_closed_python_optional_type(None) assert not is_closed_python_optional_type(int) assert not is_closed_python_optional_type(list) assert not is_closed_python_optional_type("foobar")
def resolve_to_config_type(dagster_type) -> Union[ConfigType, bool]: from .field_utils import convert_fields_to_dict_type # Short circuit if it's already a Config Type if isinstance(dagster_type, ConfigType): return dagster_type if isinstance(dagster_type, dict): return convert_fields_to_dict_type(dagster_type) if isinstance(dagster_type, list): if len(dagster_type) != 1: raise DagsterInvalidDefinitionError( "Array specifications must only be of length 1") inner_type = resolve_to_config_type(dagster_type[0]) if not inner_type: raise DagsterInvalidDefinitionError( "Invalid member of array specification: {value} in list {the_list}" .format(value=repr(dagster_type[0]), the_list=dagster_type)) return Array(inner_type) from dagster.core.types.dagster_type import DagsterType, List, ListType from dagster.core.types.python_set import Set, _TypedPythonSet from dagster.core.types.python_tuple import Tuple, _TypedPythonTuple if _is_config_type_class(dagster_type): check.param_invariant( False, "dagster_type", f"Cannot pass config type class {dagster_type} to resolve_to_config_type. " "This error usually occurs when you pass a dagster config type class instead of a class instance into " 'another dagster config type. E.g. "Noneable(Permissive)" should instead be "Noneable(Permissive())".', ) if isinstance(dagster_type, type) and issubclass(dagster_type, DagsterType): raise DagsterInvalidDefinitionError( "You have passed a DagsterType class {dagster_type} to the config system. " "The DagsterType and config schema systems are separate. " "Valid config values are:\n{desc}".format( dagster_type=repr(dagster_type), desc=VALID_CONFIG_DESC, )) if is_closed_python_optional_type(dagster_type): raise DagsterInvalidDefinitionError( "Cannot use typing.Optional as a config type. If you want this field to be " "optional, please use Field(<type>, is_required=False), and if you want this field to " "be required, but accept a value of None, use dagster.Noneable(<type>)." ) if is_typing_type(dagster_type): raise DagsterInvalidDefinitionError(( "You have passed in {dagster_type} to the config system. Types from " "the typing module in python are not allowed in the config system. " "You must use types that are imported from dagster or primitive types " "such as bool, int, etc.").format(dagster_type=dagster_type)) if dagster_type is List or isinstance(dagster_type, ListType): raise DagsterInvalidDefinitionError( "Cannot use List in the context of config. " + helpful_list_error_string()) if dagster_type is Set or isinstance(dagster_type, _TypedPythonSet): raise DagsterInvalidDefinitionError( "Cannot use Set in the context of a config field. " + helpful_list_error_string()) if dagster_type is Tuple or isinstance(dagster_type, _TypedPythonTuple): raise DagsterInvalidDefinitionError( "Cannot use Tuple in the context of a config field. " + helpful_list_error_string()) if isinstance(dagster_type, DagsterType): raise DagsterInvalidDefinitionError(( "You have passed an instance of DagsterType {type_name} to the config " "system (Repr of type: {dagster_type}). " "The DagsterType and config schema systems are separate. " "Valid config values are:\n{desc}").format( type_name=dagster_type.display_name, dagster_type=repr(dagster_type), desc=VALID_CONFIG_DESC, ), ) # If we are passed here either: # 1) We have been passed a python builtin # 2) We have been a dagster wrapping type that needs to be convert its config variant # e.g. dagster.List # 2) We have been passed an invalid thing. We return False to signify this. It is # up to callers to report a reasonable error. from dagster.primitive_mapping import ( remap_python_builtin_for_config, is_supported_config_python_builtin, ) if BuiltinEnum.contains(dagster_type): return ConfigType.from_builtin_enum(dagster_type) if is_supported_config_python_builtin(dagster_type): return remap_python_builtin_for_config(dagster_type) if dagster_type is None: return ConfigAnyInstance # This means that this is an error and we are return False to a callsite # We do the error reporting there because those callsites have more context return False