Search code examples
pythonpylance

Pylance reports unbound variable when exit path is wrapped in a function, how to prevent?


Toy example:

import logging
import sys

def log_exit(
    msg: str | Exception
) -> None:
    logging.error("error, msg {}".format(msg))
    sys.exit(1)
     
try:
    a = 1
except Exception as e:
    log_exit(e)

b = a + 1


try:
    c = 1
except Exception as e:
    logging.error("error, msg {}".format(e))
    sys.exit(1)
    
d = c + 1

Pylance will warn me that, in the statement b = a + 1, a is possibly unbound. This only occurs when the path leading to sys.exit() is wrapped in a function, i.e. not in the second example with c and d. In my real code, on exit I need to do a few things e.g. close a connection to a database, and I don't want to repeat myself every time, but I also don't want Pylance to be telling me all my variables might be unbound, when indeed they're not. How can I avoid this?

Thanks!


Solution

  • Your log_exit function return hint should be Never instead of None.

    https://docs.python.org/3.12/library/typing.html#typing.Never

    That way, Pylance will know the function never returns (!= returns None).

    It will also allow VSCode to dim any code unconditionally placed after a never returning function.

    from typing import Never
    
    def log_exit(
        msg: str | Exception
    ) -> Never:
        logging.error("error, msg {}".format(msg))
        sys.exit(1)