ilevkivskyi / typing_inspect

Runtime inspection utilities for Python typing module
MIT License
350 stars 35 forks source link

is_forward_ref() and eval_forward_ref(globs, locs) #15

Open smarie opened 6 years ago

smarie commented 6 years ago

Not sure these need to be in typing_inspect, but for I am currently relying on the private names so I guess there is maybe something to do in the api here?

def is_forward_ref(typ):
    """
    Returns true if typ is a typing ForwardRef
    :param typ:
    :return:
    """
    return isinstance(typ, _ForwardRef)

class InvalidForwardRefError(Exception):
    """ Raised whenever some forward reference can not be evaluated """

    def __init__(self, invalid: _ForwardRef):
        self.invalid_ref = invalid

    def __str__(self):
        return "Invalid PEP484 type hint: forward reference {} could not be resolved with the current stack's " \
               "variables".format(self.invalid_ref)

def eval_forward_ref(typ: _ForwardRef):
    """
    Climbs the current stack until the given Forward reference has been resolved, or raises an InvalidForwardRefError.
    :param typ: the forward reference to resolve
    :return:
    """
    for frame in stack():
        try:
            return typ._eval_type(frame[0].f_globals, frame[0].f_locals)
        except NameError:
            pass

    raise InvalidForwardRefError(typ)

As always if this is too high-level / specific, feel, free to suggest to move it to pytypes or equivalent libs. For example the eval_forward_ref above could be replaced with the low-level

def eval_forward_ref(typ, globs, locs):
    return typ._eval_type(globs, locs)
ilevkivskyi commented 6 years ago

I like the is_forward_ref. But for eval_forward_ref I think we should use more of typing logic used in get_type_hints, i.e. support custom locals and globals.

roo-oliv commented 4 years ago

@ilevkivskyi @smarie is there any news on this? I'll be hardcoding is_forward_ref function to my lib to work with this but it would be great to have them at typing_inspect :)

ilevkivskyi commented 4 years ago

@allrod5 I think adding is_forward_ref() totally makes sense (it needs to also account the renaming of _ForwardRef to ForwardRef in newer Python versions). I recently needed it myself actually. Would you like to make a PR?

roo-oliv commented 4 years ago

I surely can, will do it soon :)

roo-oliv commented 4 years ago

@ilevkivskyi submitted: https://github.com/ilevkivskyi/typing_inspect/pull/57

andreycizov commented 4 years ago

Could you release the latest version of the library with forward_ref support?

ilevkivskyi commented 4 years ago

OK, I will make a release soon.

ilevkivskyi commented 4 years ago

I just uploaded new version to PyPI: https://pypi.org/project/typing-inspect/0.6.0/

andreycizov commented 4 years ago

Thanks!