[commands] Refactor evaluation functions to allow passing in localns
This commit is contained in:
parent
aac0374baf
commit
7fb746e6e5
@ -28,6 +28,7 @@ from typing import (
|
|||||||
ForwardRef,
|
ForwardRef,
|
||||||
Iterable,
|
Iterable,
|
||||||
Literal,
|
Literal,
|
||||||
|
Optional,
|
||||||
Tuple,
|
Tuple,
|
||||||
Union,
|
Union,
|
||||||
)
|
)
|
||||||
@ -89,7 +90,14 @@ def normalise_optional_params(parameters: Iterable[Any]) -> Tuple[Any, ...]:
|
|||||||
none_cls = type(None)
|
none_cls = type(None)
|
||||||
return tuple(p for p in parameters if p is not none_cls) + (none_cls,)
|
return tuple(p for p in parameters if p is not none_cls) + (none_cls,)
|
||||||
|
|
||||||
def _evaluate_annotation(tp: Any, globals: Dict[str, Any], cache: Dict[str, Any] = {}, *, implicit_str=True):
|
def _evaluate_annotation(
|
||||||
|
tp: Any,
|
||||||
|
globals: Dict[str, Any],
|
||||||
|
locals: Dict[str, Any],
|
||||||
|
cache: Dict[str, Any],
|
||||||
|
*,
|
||||||
|
implicit_str: bool = True,
|
||||||
|
):
|
||||||
if isinstance(tp, ForwardRef):
|
if isinstance(tp, ForwardRef):
|
||||||
tp = tp.__forward_arg__
|
tp = tp.__forward_arg__
|
||||||
# ForwardRefs always evaluate their internals
|
# ForwardRefs always evaluate their internals
|
||||||
@ -98,9 +106,9 @@ def _evaluate_annotation(tp: Any, globals: Dict[str, Any], cache: Dict[str, Any]
|
|||||||
if implicit_str and isinstance(tp, str):
|
if implicit_str and isinstance(tp, str):
|
||||||
if tp in cache:
|
if tp in cache:
|
||||||
return cache[tp]
|
return cache[tp]
|
||||||
evaluated = eval(tp, globals)
|
evaluated = eval(tp, globals, locals)
|
||||||
cache[tp] = evaluated
|
cache[tp] = evaluated
|
||||||
return _evaluate_annotation(evaluated, globals, cache)
|
return _evaluate_annotation(evaluated, globals, locals, cache)
|
||||||
|
|
||||||
if hasattr(tp, '__args__'):
|
if hasattr(tp, '__args__'):
|
||||||
implicit_str = True
|
implicit_str = True
|
||||||
@ -108,7 +116,7 @@ def _evaluate_annotation(tp: Any, globals: Dict[str, Any], cache: Dict[str, Any]
|
|||||||
if not hasattr(tp, '__origin__'):
|
if not hasattr(tp, '__origin__'):
|
||||||
if PY_310 and tp.__class__ is types.Union:
|
if PY_310 and tp.__class__ is types.Union:
|
||||||
converted = Union[args] # type: ignore
|
converted = Union[args] # type: ignore
|
||||||
return _evaluate_annotation(converted, globals, cache)
|
return _evaluate_annotation(converted, globals, locals, cache)
|
||||||
|
|
||||||
return tp
|
return tp
|
||||||
if tp.__origin__ is Union:
|
if tp.__origin__ is Union:
|
||||||
@ -123,7 +131,7 @@ def _evaluate_annotation(tp: Any, globals: Dict[str, Any], cache: Dict[str, Any]
|
|||||||
implicit_str = False
|
implicit_str = False
|
||||||
|
|
||||||
evaluated_args = tuple(
|
evaluated_args = tuple(
|
||||||
_evaluate_annotation(arg, globals, cache, implicit_str=implicit_str) for arg in args
|
_evaluate_annotation(arg, globals, locals, cache, implicit_str=implicit_str) for arg in args
|
||||||
)
|
)
|
||||||
|
|
||||||
if evaluated_args == args:
|
if evaluated_args == args:
|
||||||
@ -136,12 +144,21 @@ def _evaluate_annotation(tp: Any, globals: Dict[str, Any], cache: Dict[str, Any]
|
|||||||
|
|
||||||
return tp
|
return tp
|
||||||
|
|
||||||
def resolve_annotation(annotation: Any, globalns: Dict[str, Any], cache: Dict[str, Any] = {}) -> Any:
|
def resolve_annotation(
|
||||||
|
annotation: Any,
|
||||||
|
globalns: Dict[str, Any],
|
||||||
|
localns: Optional[Dict[str, Any]],
|
||||||
|
cache: Optional[Dict[str, Any]],
|
||||||
|
) -> Any:
|
||||||
if annotation is None:
|
if annotation is None:
|
||||||
return type(None)
|
return type(None)
|
||||||
if isinstance(annotation, str):
|
if isinstance(annotation, str):
|
||||||
annotation = ForwardRef(annotation)
|
annotation = ForwardRef(annotation)
|
||||||
return _evaluate_annotation(annotation, globalns, cache)
|
|
||||||
|
locals = globalns if localns is None else localns
|
||||||
|
if cache is None:
|
||||||
|
cache = {}
|
||||||
|
return _evaluate_annotation(annotation, globalns, locals, cache)
|
||||||
|
|
||||||
def get_signature_parameters(function: types.FunctionType) -> Dict[str, inspect.Parameter]:
|
def get_signature_parameters(function: types.FunctionType) -> Dict[str, inspect.Parameter]:
|
||||||
globalns = function.__globals__
|
globalns = function.__globals__
|
||||||
@ -157,7 +174,7 @@ def get_signature_parameters(function: types.FunctionType) -> Dict[str, inspect.
|
|||||||
params[name] = parameter.replace(annotation=type(None))
|
params[name] = parameter.replace(annotation=type(None))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
annotation = _evaluate_annotation(annotation, globalns, cache)
|
annotation = _evaluate_annotation(annotation, globalns, globalns, cache)
|
||||||
if annotation is converters.Greedy:
|
if annotation is converters.Greedy:
|
||||||
raise TypeError('Unparameterized Greedy[...] is disallowed in signature.')
|
raise TypeError('Unparameterized Greedy[...] is disallowed in signature.')
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user