Skip to content

Commit cc787f0

Browse files
committed
Add support for tuple values on except clauses
Issue #1590
1 parent 529d098 commit cc787f0

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

mypy/checker.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,19 @@ def check_exception_type(self, type: Type, context: Context) -> Type:
18511851
return AnyType()
18521852
elif isinstance(type, AnyType):
18531853
return AnyType()
1854+
elif isinstance(type, TupleType):
1855+
t = None # type: Type
1856+
for item in type.items:
1857+
tt = self.check_exception_type(item, context)
1858+
if isinstance(tt, AnyType):
1859+
t = AnyType()
1860+
break
1861+
1862+
if t:
1863+
t = join_types(t, tt)
1864+
else:
1865+
t = tt
1866+
return t
18541867
else:
18551868
self.fail(messages.INVALID_EXCEPTION_TYPE, context)
18561869
return AnyType()

mypy/test/data/check-statements.test

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,20 @@ except (E1, E2) as e1:
573573
except (E2, E1) as e2:
574574
a = e2 # type: E1
575575
b = e2 # type: E2 # E: Incompatible types in assignment (expression has type "E1", variable has type "E2")
576+
except (E1, E2, int) as e3: # E: Exception type must be derived from BaseException
577+
pass
578+
[builtins fixtures/exception.py]
579+
580+
[case testExceptWithMultipleTypes3]
581+
import typing
582+
class E1(BaseException): pass
583+
class E2(E1): pass
584+
class E3(E1): pass
585+
try: pass
586+
except (E1, (E2, (E3,))) as e1:
587+
reveal_type(e1) # E: Revealed type is '__main__.E1'
588+
except (E2, (E3,)) as e2:
589+
reveal_type(e2) # E: Revealed type is '__main__.E1'
576590
[builtins fixtures/exception.py]
577591

578592
[case testReuseTryExceptionVariable]
@@ -618,6 +632,45 @@ except exc as e: pass # E: Exception type must be derived from BaseE
618632
except BaseException() as b: pass # E: Exception type must be derived from BaseException
619633
[builtins fixtures/exception.py]
620634

635+
[case testTupleValueAsExceptionType]
636+
import typing
637+
def exc() -> BaseException: pass
638+
class E1(BaseException): pass
639+
class E2(E1): pass
640+
class E3(E1): pass
641+
642+
exs1 = (E1, E2)
643+
try: pass
644+
except exs1 as e1:
645+
reveal_type(e1) # E: Revealed type is '__main__.E1'
646+
647+
exs2 = ((E1, (E2,)),)
648+
try: pass
649+
except exs2 as e2:
650+
reveal_type(e2) # E: Revealed type is '__main__.E1'
651+
652+
exs3 = (E2, E3)
653+
try: pass
654+
except exs3 as e3:
655+
reveal_type(e3) # E: Revealed type is '__main__.E1'
656+
[builtins fixtures/exception.py]
657+
658+
[case testInvalidTupleValueAsExceptionType]
659+
import typing
660+
def exc() -> BaseException: pass
661+
class E1(BaseException): pass
662+
class E2(E1): pass
663+
class E3(E1): pass
664+
665+
exs1 = (E1, E2, int)
666+
try: pass
667+
except exs1 as e: pass # E: Exception type must be derived from BaseException
668+
669+
exs2 = (E1, (E2, (int, (E3,))))
670+
try: pass
671+
except exs2 as e: pass # E: Exception type must be derived from BaseException
672+
[builtins fixtures/exception.py]
673+
621674
[case testOverloadedExceptionType]
622675
from typing import overload
623676
class E(BaseException):

0 commit comments

Comments
 (0)