mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 06:44:46 +08:00
A temporary argument clinic implementation for the stdlib.
This commit is contained in:
@@ -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()]
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user