@@ -453,16 +453,16 @@ def get_generator_yield_type(self, return_type: Type) -> Type:
453453 if isinstance (return_type , AnyType ):
454454 return AnyType ()
455455 elif not self .is_generator_return_type (return_type ):
456- # if the function doesn't have a proper Generator (or superclass)
457- # return type, anything is permissible
456+ # If the function doesn't have a proper Generator (or superclass) return type, anything
457+ # is permissible.
458458 return AnyType ()
459459 elif not isinstance (return_type , Instance ):
460- # same as above, but written as a separate branch so the typechecker can understand
460+ # Same as above, but written as a separate branch so the typechecker can understand.
461461 return AnyType ()
462462 elif return_type .args :
463463 return return_type .args [0 ]
464464 else :
465- # if the function's declared supertype of Generator has no type
465+ # If the function's declared supertype of Generator has no type
466466 # parameters (i.e. is `object`), then the yielded values can't
467467 # be accessed so any type is acceptable.
468468 return AnyType ()
@@ -471,35 +471,37 @@ def get_generator_receive_type(self, return_type: Type) -> Type:
471471 if isinstance (return_type , AnyType ):
472472 return AnyType ()
473473 elif not self .is_generator_return_type (return_type ):
474- # if the function doesn't have a proper Generator (or superclass)
475- # return type, anything is permissible
474+ # If the function doesn't have a proper Generator (or superclass) return type, anything
475+ # is permissible.
476476 return AnyType ()
477477 elif not isinstance (return_type , Instance ):
478- # same as above, but written as a separate branch so the typechecker can understand
478+ # Same as above, but written as a separate branch so the typechecker can understand.
479479 return AnyType ()
480480 elif return_type .type .fullname () == 'typing.Generator' :
481- # Generator is the only type which specifies the type of values it can receive
481+ # Generator is the only type which specifies the type of values it can receive.
482482 return return_type .args [1 ]
483483 else :
484- # it's a supertype of Generator, so callers won't be able to see send it values
484+ # `return_type` is a supertype of Generator, so callers won't be able to send it
485+ # values.
485486 return Void ()
486487
487488 def get_generator_return_type (self , return_type : Type ) -> Type :
488489 if isinstance (return_type , AnyType ):
489490 return AnyType ()
490491 elif not self .is_generator_return_type (return_type ):
491- # if the function doesn't have a proper Generator (or superclass)
492- # return type, anything is permissible
492+ # If the function doesn't have a proper Generator (or superclass) return type, anything
493+ # is permissible.
493494 return AnyType ()
494495 elif not isinstance (return_type , Instance ):
495- # same as above, but written as a separate branch so the typechecker can understand
496+ # Same as above, but written as a separate branch so the typechecker can understand.
496497 return AnyType ()
497498 elif return_type .type .fullname () == 'typing.Generator' :
498- # Generator is the only type which specifies the type of values it
499- # returns into `yield from` expressions
499+ # Generator is the only type which specifies the type of values it returns into
500+ # `yield from` expressions.
500501 return return_type .args [2 ]
501502 else :
502- # it's a supertype of Generator, so callers won't be able to see the return type
503+ # `return_type` is supertype of Generator, so callers won't be able to see the return
504+ # type when used in a `yield from` expression.
503505 return AnyType ()
504506
505507 def visit_func_def (self , defn : FuncDef ) -> Type :
@@ -612,12 +614,12 @@ def check_func_def(self, defn: FuncItem, typ: CallableType, name: str) -> None:
612614 self .fail (messages .RETURN_TYPE_CANNOT_BE_CONTRAVARIANT ,
613615 typ .ret_type )
614616
615- # check that Generator functions have the appropriate return type
617+ # Check that Generator functions have the appropriate return type.
616618 if defn .is_generator :
617619 if not self .is_generator_return_type (typ .ret_type ):
618620 self .fail (messages .INVALID_RETURN_TYPE_FOR_GENERATOR , typ )
619621
620- # Python 2 generators aren't allowed to return values
622+ # Python 2 generators aren't allowed to return values.
621623 if (self .pyversion [0 ] == 2 and
622624 isinstance (typ .ret_type , Instance ) and
623625 typ .ret_type .type .fullname () == 'typing.Generator' ):
@@ -1484,11 +1486,10 @@ def visit_return_stmt(self, s: ReturnStmt) -> Type:
14841486 return None
14851487
14861488 if isinstance (return_type , Void ):
1487- # FuncExpr (lambda) may have a Void return.
1488- # Function returning a value of type None may have a Void return.
1489+ # Lambdas are allowed to have a Void return.
1490+ # Functions returning a value of type None are allowed to have a Void return.
14891491 if isinstance (self .function_stack [- 1 ], FuncExpr ) or isinstance (typ , NoneTyp ):
14901492 return None
1491-
14921493 self .fail (messages .NO_RETURN_VALUE_EXPECTED , s )
14931494 else :
14941495 self .check_subtype (
@@ -1497,7 +1498,7 @@ def visit_return_stmt(self, s: ReturnStmt) -> Type:
14971498 + ": expected {}, got {}" .format (return_type , typ )
14981499 )
14991500 else :
1500- # empty returns are valid in Generators with Any typed returns
1501+ # Empty returns are valid in Generators with Any typed returns.
15011502 if (self .function_stack [- 1 ].is_generator and isinstance (return_type , AnyType )):
15021503 return None
15031504
@@ -1861,9 +1862,11 @@ def visit_yield_from_expr(self, e: YieldFromExpr) -> Type:
18611862 return_type = self .return_types [- 1 ]
18621863 subexpr_type = self .accept (e .expr , return_type )
18631864
1864- # check that the expr is an instance of Iterable and get the type of
1865- # the iterator produced by __iter__
1866- if (isinstance (subexpr_type , Instance ) and
1865+ # Check that the expr is an instance of Iterable and get the type of the iterator produced
1866+ # by __iter__.
1867+ if isinstance (subexpr_type , AnyType ):
1868+ iter_type = AnyType ()
1869+ elif (isinstance (subexpr_type , Instance ) and
18671870 is_subtype (subexpr_type , self .named_type ('typing.Iterable' ))):
18681871 iter_method_type = self .expr_checker .analyze_external_member_access (
18691872 '__iter__' ,
@@ -1874,27 +1877,25 @@ def visit_yield_from_expr(self, e: YieldFromExpr) -> Type:
18741877 [AnyType (), AnyType (), AnyType ()])
18751878 iter_type , _ = self .expr_checker .check_call (iter_method_type , [], [],
18761879 context = generic_generator_type )
1877- elif isinstance (subexpr_type , AnyType ):
1878- iter_type = AnyType ()
18791880 else :
18801881 self .msg .yield_from_invalid_operand_type (subexpr_type , e )
18811882 iter_type = AnyType ()
18821883
1883- # check that the iterator's item type matches the type yielded by the
1884- # Generator function containing this yield from
1884+ # Check that the iterator's item type matches the type yielded by the Generator function
1885+ # containing this ` yield from` expression.
18851886 expected_item_type = self .get_generator_yield_type (return_type )
18861887 actual_item_type = self .get_generator_yield_type (iter_type )
18871888
18881889 self .check_subtype (actual_item_type , expected_item_type , e ,
18891890 messages .INCOMPATIBLE_TYPES_IN_YIELD_FROM ,
18901891 'actual type' , 'expected type' )
18911892
1892- # determine the type of the entire yield from expression
1893+ # Determine the type of the entire yield from expression.
18931894 if (isinstance (iter_type , Instance ) and
18941895 iter_type .type .fullname () == 'typing.Generator' ):
18951896 return self .get_generator_return_type (iter_type )
18961897 else :
1897- # non -Generators don't return anything from " yield from" expressions
1898+ # Non -Generators don't return anything from ` yield from` expressions.
18981899 return Void ()
18991900
19001901 def visit_member_expr (self , e : MemberExpr ) -> Type :
0 commit comments