コード例 #1
0
ファイル: subtypes.py プロジェクト: greatmazinger/mypy
 def visit_typeddict_type(self, left: TypedDictType) -> bool:
     right = self.right
     if isinstance(right, Instance):
         return is_subtype(left.fallback, right, self.check_type_parameter)
     elif isinstance(right, TypedDictType):
         if not left.names_are_wider_than(right):
             return False
         for name, l, r in left.zip(right):
             if not is_equivalent(l, r, self.check_type_parameter):
                 return False
             # Non-required key is not compatible with a required key since
             # indexing may fail unexpectedly if a required key is missing.
             # Required key is not compatible with a non-required key since
             # the prior doesn't support 'del' but the latter should support
             # it.
             #
             # NOTE: 'del' support is currently not implemented (#3550). We
             #       don't want to have to change subtyping after 'del' support
             #       lands so here we are anticipating that change.
             if (name in left.required_keys) != (name in right.required_keys):
                 return False
         # (NOTE: Fallbacks don't matter.)
         return True
     else:
         return False
コード例 #2
0
ファイル: subtypes.py プロジェクト: GigonicMan/mypy
 def visit_typeddict_type(self, left: TypedDictType) -> bool:
     right = self.right
     if isinstance(right, Instance):
         return is_subtype(left.fallback, right, self.check_type_parameter)
     elif isinstance(right, TypedDictType):
         if not left.names_are_wider_than(right):
             return False
         for name, l, r in left.zip(right):
             if not is_equivalent(l, r, self.check_type_parameter):
                 return False
             # Non-required key is not compatible with a required key since
             # indexing may fail unexpectedly if a required key is missing.
             # Required key is not compatible with a non-required key since
             # the prior doesn't support 'del' but the latter should support
             # it.
             #
             # NOTE: 'del' support is currently not implemented (#3550). We
             #       don't want to have to change subtyping after 'del' support
             #       lands so here we are anticipating that change.
             if (name in left.required_keys) != (name in right.required_keys):
                 return False
         # (NOTE: Fallbacks don't matter.)
         return True
     else:
         return False
コード例 #3
0
ファイル: subtypes.py プロジェクト: persianyagami/mypy
 def visit_typeddict_type(self, left: TypedDictType) -> bool:
     right = self.right
     if isinstance(right, Instance):
         return is_subtype(left.fallback, right, self.check_type_parameter)
     elif isinstance(right, TypedDictType):
         if not left.names_are_wider_than(right):
             return False
         for (_, l, r) in left.zip(right):
             if not is_equivalent(l, r, self.check_type_parameter):
                 return False
         # (NOTE: Fallbacks don't matter.)
         return True
     else:
         return False
コード例 #4
0
ファイル: plugin.py プロジェクト: mkurnikov/key-typeddict
def copy_modified(self, *, fallback: Optional[Instance] = None,
                  item_types: Optional[List[Type]] = None,
                  required_keys: Optional[Set[str]] = None) -> 'TypedDictType':
    if fallback is None:
        fallback = self.fallback
    if item_types is None:
        items = self.items
    else:
        items = OrderedDict(zip(self.items, item_types))
    if required_keys is None:
        required_keys = self.required_keys

    new_type = TypedDictType(items, required_keys, fallback, self.line, self.column)
    new_type.allow_extra = getattr(self, 'allow_extra', False)
    return new_type
コード例 #5
0
ファイル: __init__.py プロジェクト: kornicameister/axion
def get_typed_dict_type(
    ctx: FunctionContext,
    handler_arg_type: ProperType,
    oas_type: oas_model.OASObjectType,
) -> TypedDictType:

    if isinstance(handler_arg_type, UnionType):
        td_type_fallback = next(
            try_getting_instance_fallback(get_proper_type(x))
            for x in handler_arg_type.relevant_items())
    else:
        td_type_fallback = try_getting_instance_fallback(handler_arg_type)

    assert td_type_fallback is not None

    return TypedDictType(
        items=OrderedDict({
            oas_prop_name: transform_oas_type(oas_prop_type, handler_arg_type,
                                              ctx)
            for oas_prop_name, oas_prop_type in oas_type.properties.items()
        }),
        required_keys=oas_type.required,
        fallback=td_type_fallback,
        line=td_type_fallback.line,
        column=td_type_fallback.column,
    )
コード例 #6
0
def make_typeddict(api: TypeChecker, fields: 'OrderedDict[str, Type]',
                   required_keys: typing.Set[str]) -> Type:
    object_type = api.named_generic_type('mypy_extensions._TypedDict', [])
    typed_dict_type = TypedDictType(fields,
                                    required_keys=required_keys,
                                    fallback=object_type)
    return typed_dict_type
コード例 #7
0
ファイル: helpers.py プロジェクト: ytec-nl/django-stubs
def make_typeddict(api: CheckerPluginInterface,
                   fields: "OrderedDict[str, MypyType]",
                   required_keys: Set[str]) -> TypedDictType:
    object_type = api.named_generic_type("mypy_extensions._TypedDict", [])
    typed_dict_type = TypedDictType(fields,
                                    required_keys=required_keys,
                                    fallback=object_type)
    return typed_dict_type
コード例 #8
0
ファイル: astdiff.py プロジェクト: greatmazinger/mypy
 def visit_typeddict_type(self, left: TypedDictType) -> bool:
     if isinstance(self.right, TypedDictType):
         if left.items.keys() != self.right.items.keys():
             return False
         for (_, left_item_type, right_item_type) in left.zip(self.right):
             if not is_identical_type(left_item_type, right_item_type):
                 return False
         return True
     return False
コード例 #9
0
ファイル: semanal_pass3.py プロジェクト: yujiangheng/mypy
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     if self.check_recursion(t):
         return AnyType(TypeOfAny.from_error)
     items = OrderedDict([(item_name, item_type.accept(self))
                          for (item_name, item_type) in t.items.items()])
     fallback = self.visit_instance(t.fallback, from_fallback=True)
     assert isinstance(fallback, Instance)
     return TypedDictType(items, t.required_keys, fallback, t.line,
                          t.column)
コード例 #10
0
ファイル: astdiff.py プロジェクト: gknezevic/solution
 def visit_typeddict_type(self, left: TypedDictType) -> bool:
     if isinstance(self.right, TypedDictType):
         if left.items.keys() != self.right.items.keys():
             return False
         for (_, left_item_type, right_item_type) in left.zip(self.right):
             if not is_identical_type(left_item_type, right_item_type):
                 return False
         return True
     return False
コード例 #11
0
 def build_typeddict_typeinfo(self, name: str, items: List[str],
                              types: List[Type],
                              required_keys: Set[str]) -> TypeInfo:
     fallback = self.api.named_type_or_none('mypy_extensions._TypedDict', [])
     assert fallback is not None
     info = self.api.basic_new_typeinfo(name, fallback)
     info.typeddict_type = TypedDictType(OrderedDict(zip(items, types)), required_keys,
                                         fallback)
     return info
コード例 #12
0
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     items = OrderedDict([(item_name, item_type.accept(self))
                          for (item_name, item_type) in t.items.items()])
     return TypedDictType(
         items,
         t.required_keys,
         # TODO: This appears to be unsafe.
         cast(Any, t.fallback.accept(self)),
         t.line,
         t.column)
コード例 #13
0
 def build_typeddict_typeinfo(self, name: str, items: List[str],
                              types: List[Type],
                              required_keys: Set[str]) -> TypeInfo:
     fallback = (self.api.named_type_or_none('typing.Mapping', [
         self.api.named_type('__builtins__.str'),
         self.api.named_type('__builtins__.object')
     ]) or self.api.named_type('__builtins__.object'))
     info = self.api.basic_new_typeinfo(name, fallback)
     info.typeddict_type = TypedDictType(OrderedDict(zip(items, types)),
                                         required_keys, fallback)
     return info
コード例 #14
0
 def build_typeddict_typeinfo(self, name: str, items: List[str],
                              types: List[Type], required_keys: Set[str],
                              line: int) -> TypeInfo:
     # Prefer typing then typing_extensions if available.
     fallback = (
         self.api.named_type_or_none('typing._TypedDict', [])
         or self.api.named_type_or_none('typing_extensions._TypedDict', [])
         or self.api.named_type_or_none('mypy_extensions._TypedDict', []))
     assert fallback is not None
     info = self.api.basic_new_typeinfo(name, fallback, line)
     info.typeddict_type = TypedDictType(OrderedDict(zip(items, types)),
                                         required_keys, fallback)
     return info
コード例 #15
0
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     if isinstance(self.s, TypedDictType):
         for (_, l, r) in self.s.zip(t):
             if not is_equivalent(l, r):
                 return self.default(self.s)
         items = OrderedDict([(item_name, s_item_type or t_item_type)
                              for (item_name, s_item_type,
                                   t_item_type) in self.s.zipall(t)])
         mapping_value_type = join_type_list(list(items.values()))
         fallback = self.s.create_anonymous_fallback(
             value_type=mapping_value_type)
         return TypedDictType(items, fallback)
     else:
         return self.default(self.s)
コード例 #16
0
ファイル: plugin.py プロジェクト: untitaker/jsonschema-typed
    def object(
        self,
        ctx: AnalyzeTypeContext,
        schema: Dict[str, Any],
        outer: bool = False,
        **kwargs,
    ) -> Type:
        """Generate an annotation for an object, usually a TypedDict."""
        properties = schema.get("properties")

        if properties is None:
            return named_builtin_type(ctx, "dict")

        try:
            fallback = ctx.api.named_type("mypy_extensions._TypedDict", [])
        except AssertionError:
            fallback = named_builtin_type(ctx, "dict", [])
        items, types = zip(*filter(
            lambda o: o[1] is not None,
            [
                (prop, self.get_type(ctx, subschema))
                for prop, subschema in properties.items() if prop not in
                ["default", "const"]  # These are reserved names,
                # not properties.
            ],
        ))
        required_keys = set(schema.get("required", []))

        if outer:
            # We want to name the outer Type, so that we can support nested
            # references. Note that this may not be fully supported in mypy
            # at this time.
            info = self._build_typeddict_typeinfo(ctx, self.outer_name,
                                                  list(items), list(types),
                                                  required_keys)
            instance = Instance(info, [])
            td = info.typeddict_type
            assert td is not None
            typing_type = td.copy_modified(item_types=list(td.items.values()),
                                           fallback=instance)
            # # Resolve any forward (nested) references to this Type.
            # if self.forward_refs:
            #
            # for fw in self.forward_refs:
            #     fw.resolve(typing_type)
            return typing_type

        struct = OrderedDict(zip(items, types))
        return TypedDictType(struct, required_keys, fallback)
コード例 #17
0
ファイル: constraints.py プロジェクト: alexandrul/mypy
 def visit_typeddict_type(self, template: TypedDictType) -> List[Constraint]:
     actual = self.actual
     if isinstance(actual, TypedDictType):
         res = []  # type: List[Constraint]
         # NOTE: Non-matching keys are ignored. Compatibility is checked
         #       elsewhere so this shouldn't be unsafe.
         for (item_name, template_item_type, actual_item_type) in template.zip(actual):
             res.extend(infer_constraints(template_item_type,
                                          actual_item_type,
                                          self.direction))
         return res
     elif isinstance(actual, AnyType):
         return self.infer_against_any(template.items.values())
     else:
         return []
コード例 #18
0
ファイル: constraints.py プロジェクト: pixelb/mypy-mypyc
 def visit_typeddict_type(self, template: TypedDictType) -> List[Constraint]:
     actual = self.actual
     if isinstance(actual, TypedDictType):
         res = []  # type: List[Constraint]
         # NOTE: Non-matching keys are ignored. Compatibility is checked
         #       elsewhere so this shouldn't be unsafe.
         for (item_name, template_item_type, actual_item_type) in template.zip(actual):
             res.extend(infer_constraints(template_item_type,
                                          actual_item_type,
                                          self.direction))
         return res
     elif isinstance(actual, AnyType):
         return self.infer_against_any(template.items.values(), actual)
     else:
         return []
コード例 #19
0
ファイル: mypy_odoo.py プロジェクト: janverb/odoo-repl
def write_hook(ctx: MethodSigContext) -> CallableType:
    if not isinstance(ctx.type, Instance):
        return ctx.default_signature
    if ctx.type.type.name == "BaseModel":
        return ctx.default_signature
    vals = _build_vals_dict(ctx.type, ctx.api)
    fallback = ctx.api.named_type("typing._TypedDict")  # type: ignore
    vals_type = TypedDictType(vals, set(), fallback)
    return CallableType(
        [vals_type],
        [ARG_POS],
        ["vals"],
        ctx.default_signature.ret_type,
        ctx.default_signature.fallback,
    )
コード例 #20
0
    def _build_typeddict_typeinfo(self, ctx: AnalyzeTypeContext, name: str,
                                  items: List[str], types: List[Type],
                                  required_keys: Set[str]) -> TypeInfo:
        """
        Build a :class:`.TypeInfo` for a TypedDict.

        This was basically lifted from ``mypy.semanal_typeddict``.
        """
        try:
            fallback = ctx.api.named_type('mypy_extensions._TypedDict', [])
        except AssertionError:
            fallback = named_builtin_type(ctx, 'dict')
        info = self._basic_new_typeinfo(ctx, name, fallback)
        info.typeddict_type = TypedDictType(OrderedDict(zip(items, types)),
                                            required_keys, fallback)
        return info
コード例 #21
0
ファイル: join.py プロジェクト: zdszt/mypy
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     if isinstance(self.s, TypedDictType):
         items = OrderedDict([
             (item_name, s_item_type)
             for (item_name, s_item_type, t_item_type) in self.s.zip(t)
             if (is_equivalent(s_item_type, t_item_type) and
                 (item_name in t.required_keys) == (item_name in self.s.required_keys))
         ])
         mapping_value_type = join_type_list(list(items.values()))
         fallback = self.s.create_anonymous_fallback(value_type=mapping_value_type)
         # We need to filter by items.keys() since some required keys present in both t and
         # self.s might be missing from the join if the types are incompatible.
         required_keys = set(items.keys()) & t.required_keys & self.s.required_keys
         return TypedDictType(items, required_keys, fallback)
     elif isinstance(self.s, Instance):
         return join_types(self.s, t.fallback)
     else:
         return self.default(self.s)
コード例 #22
0
ファイル: meet.py プロジェクト: Teraisa/udacity_databases
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     if isinstance(self.s, TypedDictType):
         for (_, l, r) in self.s.zip(t):
             if not is_equivalent(l, r):
                 return self.default(self.s)
         item_list = []  # type: List[Tuple[str, Type]]
         for (item_name, s_item_type, t_item_type) in self.s.zipall(t):
             if s_item_type is not None:
                 item_list.append((item_name, s_item_type))
             else:
                 # at least one of s_item_type and t_item_type is not None
                 assert t_item_type is not None
                 item_list.append((item_name, t_item_type))
         items = OrderedDict(item_list)
         mapping_value_type = join_type_list(list(items.values()))
         fallback = self.s.create_anonymous_fallback(
             value_type=mapping_value_type)
         return TypedDictType(items, fallback)
     else:
         return self.default(self.s)
コード例 #23
0
    def build_typeddict_typeinfo(self, name: str, items: List[str],
                                 types: List[Type],
                                 required_keys: Set[str]) -> TypeInfo:
        fallback = (self.api.named_type_or_none('typing.Mapping',
                                                [self.api.named_type('__builtins__.str'),
                                                 self.api.named_type('__builtins__.object')])
                    or self.api.named_type('__builtins__.object'))
        info = self.api.basic_new_typeinfo(name, fallback)
        info.typeddict_type = TypedDictType(OrderedDict(zip(items, types)), required_keys,
                                            fallback)

        def patch() -> None:
            # Calculate the correct value type for the fallback Mapping.
            assert info.typeddict_type, "TypedDict type deleted before calling the patch"
            fallback.args[1] = join.join_type_list(list(info.typeddict_type.items.values()))

        # We can't calculate the complete fallback type until after semantic
        # analysis, since otherwise MROs might be incomplete. Postpone a callback
        # function that patches the fallback.
        self.api.schedule_patch(PRIORITY_FALLBACKS, patch)
        return info
コード例 #24
0
def add_tag_callback(ctx: MethodContext) -> Type:
    """Callback for the ``add_tag`` method of ``FixedMapping``.
    """
    (key, ), (value, ) = ctx.arg_types
    if not isinstance(key, Instance
                      ) or not isinstance(key.last_known_value, LiteralType):
        ctx.api.fail(
            'The key to FixedMapping.add_tag should be a literal',
            ctx.context,
        )
        return ctx.default_return_type

    dict_type = value
    if isinstance(value, Instance
                  ) and isinstance(value.last_known_value, LiteralType):
        dict_type = value.last_known_value

    key_value = key.last_known_value.value
    if not isinstance(key_value, str):  # pragma: no cover
        return ctx.default_return_type

    assert isinstance(ctx.default_return_type, Instance)
    typeddict = ctx.default_return_type.args[0]
    assert isinstance(typeddict, TypedDictType)

    items = OrderedDict(typeddict.items.items())
    items[key_value] = dict_type
    required = set([*typeddict.required_keys, key_value])

    args = [
        TypedDictType(
            items=items,
            required_keys=required,
            fallback=typeddict.fallback,
            line=typeddict.line,
            column=typeddict.column
        )
    ]

    return ctx.default_return_type.copy_modified(args=args)
コード例 #25
0
 def visit_typeddict_type(self, t: TypedDictType) -> ProperType:
     if isinstance(self.s, TypedDictType):
         for (name, l, r) in self.s.zip(t):
             if (not is_equivalent(l, r) or
                     (name in t.required_keys) != (name in self.s.required_keys)):
                 return self.default(self.s)
         item_list: List[Tuple[str, Type]] = []
         for (item_name, s_item_type, t_item_type) in self.s.zipall(t):
             if s_item_type is not None:
                 item_list.append((item_name, s_item_type))
             else:
                 # at least one of s_item_type and t_item_type is not None
                 assert t_item_type is not None
                 item_list.append((item_name, t_item_type))
         items = OrderedDict(item_list)
         fallback = self.s.create_anonymous_fallback()
         required_keys = t.required_keys | self.s.required_keys
         return TypedDictType(items, required_keys, fallback)
     elif isinstance(self.s, Instance) and is_subtype(t, self.s):
         return t
     else:
         return self.default(self.s)
コード例 #26
0
def combine_callback(ctx: MethodContext) -> Type:
    """Callback for the ``combine`` method on ``FixedMapping``.
    """
    assert isinstance(ctx.type, Instance)
    own_typeddict, = ctx.type.args
    (other, ), = ctx.arg_types

    assert isinstance(other, Instance)
    other_typeddict, = other.args
    assert isinstance(other_typeddict, TypedDictType)
    assert isinstance(own_typeddict, TypedDictType)

    for new_key in other_typeddict.items.keys():
        if new_key in own_typeddict.items:
            ctx.api.fail(
                'Cannot combine typeddict, got overlapping key {!r}'.
                format(new_key), ctx.context
            )
            return ctx.default_return_type
    items = list(
        itertools.chain(
            own_typeddict.items.items(),
            other_typeddict.items.items(),
        )
    )
    new_typeddict = TypedDictType(
        items=OrderedDict(items),
        required_keys={
            *own_typeddict.required_keys, *other_typeddict.required_keys
        },
        fallback=own_typeddict.fallback,
        line=own_typeddict.line,
        column=own_typeddict.column
    )
    assert isinstance(ctx.default_return_type, Instance)
    return ctx.default_return_type.copy_modified(args=[new_typeddict])
コード例 #27
0
ファイル: expandtype.py プロジェクト: Michael0x2a/mypy
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     return t.copy_modified(item_types=self.expand_types(t.items.values()))
コード例 #28
0
ファイル: typeanal.py プロジェクト: elarivie/mypy
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     items = OrderedDict([(item_name, self.anal_type(item_type))
                          for (item_name, item_type) in t.items.items()])
     return TypedDictType(items, set(t.required_keys), t.fallback)
コード例 #29
0
 def visit_typeddict_type(self, t: TypedDictType) -> ProperType:
     return self.copy_common(
         t, TypedDictType(t.items, t.required_keys, t.fallback))
コード例 #30
0
    def object(self,
               ctx: AnalyzeTypeContext,
               schema: Dict[str, Any],
               outer: bool = False,
               **kwargs) -> Type:
        """Generate an annotation for an object, usually a TypedDict."""
        properties = schema.get('properties')
        pattern_properties = schema.get('patternProperties')

        if pattern_properties is not None:
            if properties is not None:
                raise NotImplementedError(
                    'using `properties` in combination with `patternProperties`'
                    ' is not supported')
            # If we have pattern properties, we want Dict[str, Union[...]]
            # where ... is the types of all patternProperties subschemas
            return named_builtin_type(
                ctx,
                'dict',
                [
                    named_builtin_type(ctx, 'str'),
                    UnionType([
                        self.get_type(ctx, subschema)
                        for subschema in pattern_properties.values()
                    ]),
                ],
            )

        if properties is None:
            return named_builtin_type(ctx, 'dict')

        try:
            fallback = ctx.api.named_type('mypy_extensions._TypedDict', [])
        except AssertionError:
            fallback = named_builtin_type(ctx, 'dict', [])
        items, types = zip(*filter(
            lambda o: o[1] is not None,
            [
                (prop, self.get_type(ctx, subschema))
                for prop, subschema in properties.items() if prop not in
                ['default', 'const']  # These are reserved names,
                # not properties.
            ]))
        required_keys = set(schema.get('required', []))

        if outer:
            # We want to name the outer Type, so that we can support nested
            # references. Note that this may not be fully supported in mypy
            # at this time.
            info = self._build_typeddict_typeinfo(ctx, self.outer_name,
                                                  list(items), list(types),
                                                  required_keys)
            instance = Instance(info, [])
            td = info.typeddict_type
            typing_type = td.copy_modified(item_types=list(td.items.values()),
                                           fallback=instance)
            # # Resolve any forward (nested) references to this Type.
            # if self.forward_refs:
            #
            # for fw in self.forward_refs:
            #     fw.resolve(typing_type)
            return typing_type

        struct = OrderedDict(zip(items, types))
        return TypedDictType(struct, required_keys, fallback)
コード例 #31
0
ファイル: expandtype.py プロジェクト: suryansh2020/mypy
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     return t.copy_modified(item_types=self.expand_types(t.items.values()))
コード例 #32
0
def fixed_mapping_callback(ctx: FunctionContext) -> Type:
    """The callback to infer a better type for ``FixedMapping``.
    """
    fallback = ctx.api.named_generic_type('typing_extensions._TypedDict', [])

    required_keys = set()
    items = OrderedDict()

    for idx, arg in enumerate(ctx.arg_types[0]):
        if isinstance(arg, AnyType):
            ctx.api.fail((
                'Argument {} was an "Any" which is not allowed as an'
                ' argument to FixedMapping'
            ).format(idx + 1), ctx.context)
            continue
        if isinstance(arg, Instance):
            typ = arg.type.fullname
        else:  # pragma: no cover
            typ = '????'

        if typ not in (
            'cg_request_args.RequiredArgument',
            'cg_request_args.OptionalArgument'
        ):
            ctx.api.fail((
                'Argument {} provided was of wrong type, expected'
                ' cg_request_args._RequiredArgument or'
                ' cg_request_args._OptionalArgument, but got {}.'
            ).format(idx + 1, typ), ctx.context)
            continue

        assert isinstance(arg, Instance)
        key_typevar = arg.args[1]
        if not isinstance(key_typevar, LiteralType):
            ctx.api.fail((
                'Second parameter of the argument should be a literal, this'
                ' was not the case for argument {}'
            ).format(idx + 1), ctx.context)
            continue

        key = key_typevar.value
        if not isinstance(key, str):
            ctx.api.fail((
                'Key should be of type string, but was of type {} for argument'
                ' {}.'
            ).format(type(key).__name__, idx + 1), ctx.context)
            continue

        if key in items:
            ctx.api.fail((
                'Key {!r} was already present, but given again as argument {}.'
            ).format(key, idx + 1), ctx.context)
            continue

        required_keys.add(key)

        value_type = arg.args[0]
        if typ == 'cg_request_args.OptionalArgument':
            value_type = make_simplified_union([
                ctx.api.named_generic_type(
                    'cg_maybe.Just',
                    [value_type],
                ),
                ctx.api.named_generic_type(
                    'cg_maybe._Nothing',
                    [value_type],
                ),
            ])

        items[key] = value_type

    assert isinstance(ctx.default_return_type, Instance)
    return ctx.default_return_type.copy_modified(
        args=[
            TypedDictType(OrderedDict(items), required_keys, fallback),
        ]
    )
コード例 #33
0
 def visit_typeddict_type(self, t: TypedDictType) -> Type:
     items = OrderedDict([(item_name, item_type.accept(self))
                          for (item_name, item_type) in t.items.items()])
     return TypedDictType(items, t.fallback)
コード例 #34
0
ファイル: visitor.py プロジェクト: thepabloaguilar/returns
def translate_kind_instance(typ: Type) -> Type:  # noqa: WPS, C901
    """
    We use this ugly hack to translate ``KindN[x, y]`` into ``x[y]``.

    This is required due to the fact that ``KindN``
    can be nested in other types, like: ``List[KindN[...]]``.

    We will refactor this code after ``TypeTranslator``
    is released in ``[email protected]`` version.
    """
    typ = get_proper_type(typ)

    if isinstance(typ, _LEAF_TYPES):  # noqa: WPS223
        return typ
    elif isinstance(typ, Instance):
        last_known_value: Optional[LiteralType] = None
        if typ.last_known_value is not None:
            raw_last_known_value = translate_kind_instance(
                typ.last_known_value)
            assert isinstance(raw_last_known_value, LiteralType)
            last_known_value = raw_last_known_value
        instance = Instance(
            typ=typ.type,
            args=_translate_types(typ.args),
            line=typ.line,
            column=typ.column,
            last_known_value=last_known_value,
        )
        if typ.type.fullname == TYPED_KINDN:  # That's where we do the change
            return _process_kinded_type(instance)
        return instance

    elif isinstance(typ, CallableType):
        return typ.copy_modified(
            arg_types=_translate_types(typ.arg_types),
            ret_type=translate_kind_instance(typ.ret_type),
        )
    elif isinstance(typ, TupleType):
        return TupleType(
            _translate_types(typ.items),
            translate_kind_instance(typ.partial_fallback),  # type: ignore
            typ.line,
            typ.column,
        )
    elif isinstance(typ, TypedDictType):
        dict_items = {
            item_name: translate_kind_instance(item_type)
            for item_name, item_type in typ.items.items()
        }
        return TypedDictType(
            dict_items,
            typ.required_keys,
            translate_kind_instance(typ.fallback),  # type: ignore
            typ.line,
            typ.column,
        )
    elif isinstance(typ, LiteralType):
        fallback = translate_kind_instance(typ.fallback)
        assert isinstance(fallback, Instance)
        return LiteralType(
            value=typ.value,
            fallback=fallback,
            line=typ.line,
            column=typ.column,
        )
    elif isinstance(typ, UnionType):
        return UnionType(_translate_types(typ.items), typ.line, typ.column)
    elif isinstance(typ, Overloaded):
        functions: List[CallableType] = []
        for func in typ.items():
            new = translate_kind_instance(func)
            assert isinstance(new, CallableType)
            functions.append(new)
        return Overloaded(items=functions)
    elif isinstance(typ, TypeType):
        return TypeType.make_normalized(
            translate_kind_instance(typ.item),
            line=typ.line,
            column=typ.column,
        )
    return typ