Browse Source

[commands] Use typing.get_type_hints to resolve ForwardRefs

pull/6664/head
Nadir Chowdhury 4 years ago
committed by GitHub
parent
commit
7a34de1570
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 31
      discord/ext/commands/core.py

31
discord/ext/commands/core.py

@ -27,6 +27,7 @@ import functools
import inspect
import typing
import datetime
import sys
import discord
@ -299,17 +300,35 @@ class Command(_BaseCommand):
signature = inspect.signature(function)
self.params = signature.parameters.copy()
# PEP-563 allows postponing evaluation of annotations with a __future__
# import. When postponed, Parameter.annotation will be a string and must
# be replaced with the real value for the converters to work later on
for key, value in self.params.items():
if isinstance(value.annotation, str):
self.params[key] = value = value.replace(annotation=eval(value.annotation, function.__globals__))
# see: https://bugs.python.org/issue41341
resolve = self._recursive_resolve if sys.version_info < (3, 9) else self._return_resolved
try:
type_hints = {k: resolve(v) for k, v in typing.get_type_hints(function).items()}
except NameError as e:
raise NameError(f'unresolved forward reference: {e.args[0]}') from None
for key, value in self.params.items():
# coalesce the forward references
self.params[key] = value = value.replace(annotation=type_hints.get(key))
# fail early for when someone passes an unparameterized Greedy type
if value.annotation is converters.Greedy:
raise TypeError('Unparameterized Greedy[...] is disallowed in signature.')
def _return_resolved(self, type, **kwargs):
return type
def _recursive_resolve(self, type, *, globals=None):
if not isinstance(type, typing.ForwardRef):
return type
resolved = eval(type.__forward_arg__, globals)
args = typing.get_args(resolved)
for index, arg in enumerate(args):
inner_resolve_result = self._recursive_resolve(arg, globals=globals)
resolved[index] = inner_resolve_result
return resolved
def add_check(self, func):
"""Adds a check to the command.

Loading…
Cancel
Save