Python Forum
Type hinting - return type based on parameter
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Type hinting - return type based on parameter
#1
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?
Feel like you're not getting the answers you want? Checkout the help/rules for things like what to include/not include in a post, how to use code tags, how to ask smart questions, and more.

Pro-tip - there's an inverse correlation between the number of lines of code posted and my enthusiasm for helping with a question :)
Reply
#2
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}
Reply
#3
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.
Feel like you're not getting the answers you want? Checkout the help/rules for things like what to include/not include in a post, how to use code tags, how to ask smart questions, and more.

Pro-tip - there's an inverse correlation between the number of lines of code posted and my enthusiasm for helping with a question :)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  What type of *data* is the name of a list/tuple/dict, etc? alloydog 5 193 Jan-14-2021, 09:25 AM
Last Post: alloydog
Question dict value, how to change type from int to list? swissjoker 3 226 Dec-09-2020, 09:50 AM
Last Post: perfringo
  code to read files in folders and transfer the file name, type, date created to excel Divya577 0 124 Dec-06-2020, 04:14 PM
Last Post: Divya577
  Bug ? when dataclass field name == field type Cyril 0 205 Oct-22-2020, 03:26 AM
Last Post: Cyril
  TypeError: 'type' object is not subscriptable Stef 1 551 Aug-28-2020, 03:01 PM
Last Post: Gribouillis
  tmdbsimple content type? How to work with it? pythonnewbie138 1 318 Aug-01-2020, 08:18 PM
Last Post: bowlofred
  Type coercion with Numpy arrays Mark17 2 378 Jul-24-2020, 02:04 AM
Last Post: scidam
  isinstance() always return true for object type check Yoki91 2 419 Jul-22-2020, 06:52 PM
Last Post: Yoki91
  Type Error or Value Error? spalisetty06 3 388 Jul-21-2020, 04:56 AM
Last Post: deanhystad
  ctypes and custom data type (structures, pointer to structures) python_user_n 0 421 Jul-08-2020, 05:52 PM
Last Post: python_user_n

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020