MCPcopy Index your code
hub / github.com/python/mypy / assign_type

Method assign_type

mypy/binder.py:465–542  ·  view source on GitHub ↗

Narrow type of expression through an assignment. Do nothing if the expression doesn't support narrowing. When not narrowing though an assignment (isinstance() etc.), use put() directly. This omits some special-casing logic for assignments.

(self, expr: Expression, type: Type, declared_type: Type | None)

Source from the content-addressed store, hash-verified

463 self.type_assignments = old_assignments
464
465 def assign_type(self, expr: Expression, type: Type, declared_type: Type | None) -> None:
466 """Narrow type of expression through an assignment.
467
468 Do nothing if the expression doesn't support narrowing.
469
470 When not narrowing though an assignment (isinstance() etc.), use put()
471 directly. This omits some special-casing logic for assignments.
472 """
473 # We should erase last known value in binder, because if we are using it,
474 # it means that the target is not final, and therefore can't hold a literal.
475 type = remove_instance_last_known_values(type)
476
477 if self.type_assignments is not None:
478 # We are in a multiassign from union, defer the actual binding,
479 # just collect the types.
480 self.type_assignments[expr].append((type, declared_type))
481 return
482 if not isinstance(expr, (IndexExpr, MemberExpr, NameExpr)):
483 return
484 if not literal(expr):
485 return
486 self.invalidate_dependencies(expr)
487
488 if declared_type is None:
489 # Not sure why this happens. It seems to mainly happen in
490 # member initialization.
491 return
492 if not is_subtype(type, declared_type):
493 # Pretty sure this is only happens when there's a type error.
494
495 # Ideally this function wouldn't be called if the
496 # expression has a type error, though -- do other kinds of
497 # errors cause this function to get called at invalid
498 # times?
499 return
500
501 p_declared = get_proper_type(declared_type)
502 p_type = get_proper_type(type)
503 if isinstance(p_type, AnyType):
504 # Any type requires some special casing, for both historical reasons,
505 # and to optimise user experience without sacrificing correctness too much.
506 if isinstance(expr, RefExpr) and isinstance(expr.node, Var) and expr.node.is_inferred:
507 # First case: a local/global variable without explicit annotation,
508 # in this case we just assign Any (essentially following the SSA logic).
509 self.put(expr, type)
510 elif isinstance(p_declared, UnionType):
511 all_items = flatten_nested_unions(p_declared.items)
512 if any(isinstance(get_proper_type(item), NoneType) for item in all_items):
513 # Second case: explicit optional type, in this case we optimize for
514 # a common pattern when an untyped value used as a fallback replacing None.
515 new_items = [
516 type if isinstance(get_proper_type(item), NoneType) else item
517 for item in all_items
518 ]
519 self.put(expr, UnionType(new_items))
520 elif any(isinstance(get_proper_type(item), AnyType) for item in all_items):
521 # Third case: a union already containing Any (most likely from
522 # an un-imported name), in this case we allow assigning Any as well.

Callers 9

check_func_defMethod · 0.80
check_assignmentMethod · 0.80
infer_variable_typeMethod · 0.80
replace_partial_typeMethod · 0.80
visit_del_stmtMethod · 0.80
visit_global_declMethod · 0.80

Calls 12

putMethod · 0.95
allow_jumpMethod · 0.95
literalFunction · 0.90
is_subtypeFunction · 0.90
get_proper_typeFunction · 0.90
flatten_nested_unionsFunction · 0.90
UnionTypeClass · 0.90
isinstanceFunction · 0.85
anyFunction · 0.85
appendMethod · 0.80

Tested by

no test coverage detected