Fix argument clinic unpacking, remove dynamic bullshit

This commit is contained in:
Dave Halter
2020-05-10 13:27:20 +02:00
parent 1115cbd94d
commit 6dbc5e783e
3 changed files with 24 additions and 25 deletions

View File

@@ -35,7 +35,7 @@ class ParamIssue(Exception):
pass pass
def repack_with_argument_clinic(string, keep_arguments_param=False, keep_callback_param=False): def repack_with_argument_clinic(clinic_string):
""" """
Transforms a function or method with arguments to the signature that is Transforms a function or method with arguments to the signature that is
given as an argument clinic notation. given as an argument clinic notation.
@@ -46,35 +46,29 @@ def repack_with_argument_clinic(string, keep_arguments_param=False, keep_callbac
str.split.__text_signature__ str.split.__text_signature__
# Results in: '($self, /, sep=None, maxsplit=-1)' # Results in: '($self, /, sep=None, maxsplit=-1)'
""" """
clinic_args = list(_parse_argument_clinic(string))
def decorator(func): def decorator(func):
def wrapper(context, *args, **kwargs): def wrapper(value, arguments):
if keep_arguments_param:
arguments = kwargs['arguments']
else:
arguments = kwargs.pop('arguments')
if not keep_arguments_param:
kwargs.pop('callback', None)
try: try:
args += tuple(_iterate_argument_clinic( args = tuple(iterate_argument_clinic(
context.inference_state, value.inference_state,
arguments, arguments,
clinic_args clinic_string,
)) ))
except ParamIssue: except ParamIssue:
return NO_VALUES return NO_VALUES
else: else:
return func(context, *args, **kwargs) return func(value, *args)
return wrapper return wrapper
return decorator return decorator
def _iterate_argument_clinic(inference_state, arguments, parameters): def iterate_argument_clinic(inference_state, arguments, clinic_string):
"""Uses a list with argument clinic information (see PEP 436).""" """Uses a list with argument clinic information (see PEP 436)."""
clinic_args = list(_parse_argument_clinic(clinic_string))
iterator = PushBackIterator(arguments.unpack()) iterator = PushBackIterator(arguments.unpack())
for i, (name, optional, allow_kwargs, stars) in enumerate(parameters): for i, (name, optional, allow_kwargs, stars) in enumerate(clinic_args):
if stars == 1: if stars == 1:
lazy_values = [] lazy_values = []
for key, argument in iterator: for key, argument in iterator:
@@ -94,7 +88,7 @@ def _iterate_argument_clinic(inference_state, arguments, parameters):
raise ParamIssue raise ParamIssue
if argument is None and not optional: if argument is None and not optional:
debug.warning('TypeError: %s expected at least %s arguments, got %s', debug.warning('TypeError: %s expected at least %s arguments, got %s',
name, len(parameters), i) name, len(clinic_args), i)
raise ParamIssue raise ParamIssue
value_set = NO_VALUES if argument is None else argument.infer() value_set = NO_VALUES if argument is None else argument.infer()

View File

@@ -16,7 +16,7 @@ from jedi._compatibility import force_unicode, Parameter
from jedi import debug from jedi import debug
from jedi.inference.utils import safe_property from jedi.inference.utils import safe_property
from jedi.inference.helpers import get_str_or_none from jedi.inference.helpers import get_str_or_none
from jedi.inference.arguments import \ from jedi.inference.arguments import iterate_argument_clinic, ParamIssue, \
repack_with_argument_clinic, AbstractArguments, TreeArgumentsWrapper repack_with_argument_clinic, AbstractArguments, TreeArgumentsWrapper
from jedi.inference import analysis from jedi.inference import analysis
from jedi.inference import compiled from jedi.inference import compiled
@@ -143,7 +143,7 @@ def _follow_param(inference_state, arguments, index):
return lazy_value.infer() return lazy_value.infer()
def argument_clinic(string, want_value=False, want_context=False, def argument_clinic(clinic_string, want_value=False, want_context=False,
want_arguments=False, want_inference_state=False, want_arguments=False, want_inference_state=False,
want_callback=False): want_callback=False):
""" """
@@ -151,13 +151,15 @@ def argument_clinic(string, want_value=False, want_context=False,
""" """
def f(func): def f(func):
@repack_with_argument_clinic(string, keep_arguments_param=True, def wrapper(value, arguments, callback):
keep_callback_param=True) try:
def wrapper(value, *args, **kwargs): args = tuple(iterate_argument_clinic(
arguments = kwargs.pop('arguments') value.inference_state, arguments, clinic_string))
callback = kwargs.pop('callback') except ParamIssue:
assert not kwargs # Python 2... return NO_VALUES
debug.dbg('builtin start %s' % value, color='MAGENTA') debug.dbg('builtin start %s' % value, color='MAGENTA')
kwargs = {}
if want_context: if want_context:
kwargs['context'] = arguments.context kwargs['context'] = arguments.context
if want_value: if want_value:

View File

@@ -171,6 +171,9 @@ def example(a):
#? str() #? str()
example('') example('')
# From GH #1574
#? float()
functools.wraps(functools.partial(str, 1))(lambda: 1.0)()
# ----------------- # -----------------
# sqlite3 (#84) # sqlite3 (#84)