1

I'm trying to specify types on some code that catches exceptions, but the exact type of exception is dynamic, i.e. specified at runtime.

Running mypy on the below

from typing import TypeVar

ExceptionType = TypeVar('ExceptionType', bound=BaseException)
def my_func(exception_type: ExceptionType) -> None:
    try:
        pass
    except exception_type:
        pass

results in the error:

error: Exception type must be derived from BaseException

How can I get it to pass type checking?

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165
  • You're passing a _type_, not an instance of it: https://mypy-play.net/?mypy=latest&python=3.10&gist=a66fa95c2b9504b77f2a0b885466c030. See e.g. https://stackoverflow.com/q/55751368/3001761. – jonrsharpe May 01 '22 at 10:50
  • @jonrsharpe That's right - but I think that's what I want? When catching an exception you use the type, not an instance, e.g. `except Exception:` and not `except Exception():`. Also, type checking https://mypy-play.net/?mypy=latest&python=3.10&gist=a66fa95c2b9504b77f2a0b885466c030 for me results in `"type" expects no type arguments, but 1 given` – Michal Charemza May 01 '22 at 10:53
  • Yes, that _is_ what you want, but it's _not what you've told the type system_. And that error suggests you're on an older version of Python. – jonrsharpe May 01 '22 at 10:55

2 Answers2

0

Based on @jonrsharpe's comments, this works:

from typing import Type, TypeVar

ExceptionType = TypeVar('ExceptionType', bound=BaseException)
def my_func(exception_type: Type[ExceptionType]) -> None:
    try:
        pass
    except exception_type:
        pass

(typing.Type is deprecated since Python 3.9, but you might want to support earlier versions of Python)

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165
-2

You can get it to pass using:

from typing import Any

def my_func(exception_type: Any) -> None:
    try:
        pass
    except exception_type:
        pass

but the downside of this is that Any isn't very specific - it does not enforce that that an Exception type is passed at type check time.

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165