'How to typehint the return value of a function that takes other functions

I have a function that accepts other functions, and would like to type-hint the return value of this "wrapper" function. The function is similar to this below, but with a lot more logic specific to the use case. That said, this function is also pretty handy:

def guard(func, default: WhatGoesHere = None) -> Optional[WhatGoesHere]:
    try:
        return func()
    except:
        return default

The function is used like this, with existing typehinted functions as well as the occasional lambda:

def difficult_math() -> int:
    return e^(pi * i) / 0

if res := guard(difficult_math):
   ...

if res := guard(lambda: x/3):
   ...



Solution 1:[1]

Something like this

from typing import Callable, Optional, TypeVar

R = TypeVar('R')

def guard(func: Callable[[], R], default: R = None) -> Optional[R]:
    try:
        return func()
    except:
        return default

If your function would be taking *args, **kwargs you can extend this with ParamSpec. And additional positional parameters you'd want to include Concatenate.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1