Skip to content

Commit 4fee4b8

Browse files
committed
Respond to code review; partially disable heuristics when strict-optional is disabled
1 parent bcecfe5 commit 4fee4b8

File tree

4 files changed

+208
-83
lines changed

4 files changed

+208
-83
lines changed

mypy/checker.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,14 +3347,30 @@ def visit_with_stmt(self, s: WithStmt) -> None:
33473347
exit_ret_type = self.check_async_with_item(expr, target, s.unanalyzed_type is None)
33483348
else:
33493349
exit_ret_type = self.check_with_item(expr, target, s.unanalyzed_type is None)
3350+
3351+
# Based on the return type, determine if this context manager 'swallows'
3352+
# exceptions or not. We determine this using a heuristic based on the
3353+
# return type of the __exit__ method -- see the discussion in
3354+
# https://github.com/python/mypy/issues/7214 and the section about context managers
3355+
# in https://github.com/python/typeshed/blob/master/CONTRIBUTING.md#conventions
3356+
# for more details.
3357+
3358+
exit_ret_type = get_proper_type(exit_ret_type)
33503359
if is_literal_type(exit_ret_type, "builtins.bool", False):
33513360
continue
3352-
if is_literal_type(exit_ret_type, "builtins.bool", True):
3353-
exceptions_maybe_suppressed = True
3354-
elif (isinstance(exit_ret_type, Instance)
3355-
and exit_ret_type.type.fullname() == 'builtins.bool'):
3361+
3362+
if (is_literal_type(exit_ret_type, "builtins.bool", True)
3363+
or (isinstance(exit_ret_type, Instance)
3364+
and exit_ret_type.type.fullname() == 'builtins.bool'
3365+
and state.strict_optional)):
3366+
# Note: if strict-optional is disabled, this bool instance
3367+
# could actually be an Optional[bool].
33563368
exceptions_maybe_suppressed = True
3369+
33573370
if exceptions_maybe_suppressed:
3371+
# Treat this 'with' block in the same way we'd treat a 'try: BODY; except: pass'
3372+
# block. This means control flow can continue after the 'with' even if the 'with'
3373+
# block immediately returns.
33583374
with self.binder.frame_context(can_skip=True, try_frame=True):
33593375
self.accept(s.body)
33603376
else:

mypy/types.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,10 +2406,8 @@ def remove_optional(typ: Type) -> ProperType:
24062406
return typ
24072407

24082408

2409-
def is_literal_type(typ: Type, fallback_fullname: str, value: LiteralValue) -> bool:
2410-
"""Returns 'true' if this type is a LiteralType with the given value
2411-
and underlying base fallback type.
2412-
"""
2409+
def is_literal_type(typ: ProperType, fallback_fullname: str, value: LiteralValue) -> bool:
2410+
"""Check if this type is a LiteralType with the given fallback type and value."""
24132411
if isinstance(typ, Instance) and typ.last_known_value:
24142412
typ = typ.last_known_value
24152413
if not isinstance(typ, LiteralType):

0 commit comments

Comments
 (0)