Python Forum
Type hinting - return type based on parameter - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Type hinting - return type based on parameter (/thread-23714.html)



Type hinting - return type based on parameter - micseydel - Jan-13-2020

I've had the pleasure of writing some Python at work recently, but I was stumped by something. I want something like this:
def get_from_dict(d: dict, key: str, value_type = int) -> type(value_type):
    value = d.get(key)
    if value is None:
        raise RuntimeError(f"Tried to fetch {key} from dictionary {d} but dictionary did not have the key.")

    return value_type(value)
My workaround was to hard-code it as int because that's my use case, but while I was writing the code, I wanted to make it more generic. I doubt this is possible, at least in the current state of Python's type hinting, but does anyone happen to have any ideas?


RE: Type hinting - return type based on parameter - scidam - Jan-14-2020

You always can define a custom decorator, e.g.

import inspect
from functools import wraps
from typing import Any

def set_rettype_as_var(variable_name):
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs_inner):
            return f(*args, **kwargs_inner)
        
        desired_type = Any
        signature = inspect.getfullargspec(f)
        if signature.kwonlydefaults and variable_name in signature.kwonlydefaults:
            desired_type = type(signature.kwonlydefaults.get(variable_name))
            # probably, you can take into account signature.annotations ... 
            
        if signature.args and variable_name in signature.args:
            if signature.defaults is not None:
                desired_type = type(signature.defaults[signature.args.index(variable_name)])
            else:
                desired_type = signature.annotations.get(variable_name, Any)
            
        # maybe you will need to define some other conditions .... 
        
        wrapper.__annotations__['return'] = desired_type
        return wrapper
    return decorator
@set_rettype_as_var('x')
def a(x:float):
    pass
a.__annotations__
Error:
{'x': float, 'return': float}



RE: Type hinting - return type based on parameter - micseydel - Jan-14-2020

That's not quite what I'm looking for. The return type is specified at function definition, when I want it to depend on the type of the value of the argument, not a fix parameter type.