A temporary argument clinic implementation for the stdlib.

This commit is contained in:
Dave Halter
2014-10-28 14:56:22 +01:00
parent f8bb369467
commit d27df89681
2 changed files with 43 additions and 6 deletions

View File

@@ -94,6 +94,26 @@ class Arguments(pr.Base):
new_args.append(stmt)
return new_args
def eval_argument_clinic(self, arguments):
"""Uses a list with argument clinic information (see PEP 436)."""
iterator = self.unpack()
for i, (name, optional, allow_kwargs) in enumerate(arguments):
key, va_values = next(iterator, (None, []))
if key is not None:
raise NotImplementedError
if not va_values and not optional:
debug.warning('TypeError: %s expected at least %s arguments, got %s',
name, len(arguments), i)
raise ValueError
values = list(chain.from_iterable(self._evaluator.eval_element(el)
for el in va_values))
if not values and not optional:
# For the stdlib we always want values. If we don't get them,
# that's ok, maybe something is too hard to resolve, however,
# we will not proceed with the evaluation of that function.
raise ValueError
yield values
def eval_args(self):
return [self._evaluator.eval_element(el) for stars, el in self._split()]

View File

@@ -7,6 +7,8 @@ To add a new implementation, create a function and add it to the
"""
import collections
import re
from jedi._compatibility import unicode
from jedi.evaluate import compiled
from jedi.evaluate import representation as er
@@ -58,15 +60,30 @@ def argument_clinic(string, want_obj=False):
"""
Works like Argument Clinic (PEP 436), to validate function params.
"""
args = []
# TODO Do the splitting and checking if the input is correct.
#re.
# = string.split(', ')
clinic_args = []
allow_kwargs = False
while string:
# Optional arguments have to begin with a bracket. And should always be
# at the end of the arguments. This is therefore not a proper argument
# clinic implementation. `range()` for exmple allows an optional start
# value at the beginning.
match = re.match('(?:(?:(\[), ?|, ?|)(\w+)|, ?/)\]*', string)
string = string[len(match.group(0)):]
if not match.group(2): # A slash -> allow named arguments
allow_kwargs = True
continue
optional = match.group(1)
word = match.group(2)
clinic_args.append((word, bool(optional), allow_kwargs))
def f(func):
def wrapper(evaluator, obj, arguments):
args = arguments.eval_args()
return func(evaluator, *args)
try:
lst = list(arguments.eval_argument_clinic(clinic_args))
except ValueError:
return []
else:
return func(evaluator, *lst)
return wrapper
return f