1
0
forked from VimPlug/jedi

Use inspect.Parameter.kind for better differentiation between param types

Refs #292
This commit is contained in:
Dave Halter
2018-03-13 22:47:08 +01:00
parent f9ec989835
commit 5d36114be4
5 changed files with 48 additions and 15 deletions

View File

@@ -7,6 +7,7 @@ import os
import re
import pkgutil
import warnings
import inspect
try:
import importlib
except ImportError:
@@ -174,7 +175,6 @@ def _iter_modules(paths, prefix=''):
yielded = {}
import inspect
try:
filenames = os.listdir(importer.path)
except OSError:
@@ -457,3 +457,14 @@ def pickle_load(file):
def pickle_dump(data, file):
pickle.dump(data, file, protocol=_PICKLE_PROTOCOL)
try:
from inspect import Parameter
except ImportError:
class Parameter(object):
POSITIONAL_ONLY = object()
POSITIONAL_OR_KEYWORD = object()
VAR_POSITIONAL = object()
KEYWORD_ONLY = object()
VAR_KEYWORD = object()

View File

@@ -2,6 +2,7 @@ from parso.python import token
from parso.python import tree
from parso.tree import search_ancestor, Leaf
from jedi._compatibility import Parameter
from jedi import debug
from jedi import settings
from jedi.api import classes
@@ -18,16 +19,8 @@ def get_call_signature_param_names(call_signatures):
for call_sig in call_signatures:
for p in call_sig.params:
# Allow protected access, because it's a public API.
tree_name = p._name.tree_name
# Compiled modules typically don't allow keyword arguments.
if tree_name is not None:
# Allow access on _definition here, because it's a
# public API and we don't want to make the internal
# Name object public.
tree_param = tree.search_ancestor(tree_name, 'param')
if tree_param.star_count != 0: # no *args/**kwargs
continue
if p._name.get_kind() in (Parameter.POSITIONAL_OR_KEYWORD,
Parameter.KEYWORD_ONLY):
yield p._name

View File

@@ -99,7 +99,10 @@ def safe_getattr(obj, name, default=_sentinel):
return attr
SignatureParam = namedtuple('SignatureParam', 'name has_default default has_annotation annotation')
SignatureParam = namedtuple(
'SignatureParam',
'name has_default default has_annotation annotation kind_name'
)
def compiled_objects_cache(attribute_name):
@@ -413,6 +416,7 @@ class DirectObjectAccess(object):
default=self._create_access_path(p.default),
has_annotation=p.annotation is not p.empty,
annotation=self._create_access_path(p.annotation),
kind_name=str(p.kind)
) for p in signature.parameters.values()
]

View File

@@ -5,7 +5,7 @@ import re
from functools import partial
from jedi import debug
from jedi._compatibility import force_unicode
from jedi._compatibility import force_unicode, Parameter
from jedi.cache import underscore_memoization, memoize_method
from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition, \
ContextNameMixin
@@ -248,6 +248,12 @@ class SignatureParamName(AbstractNameDefinition):
def string_name(self):
return self._signature_param.name
def get_kind(self):
return getattr(Parameter, self._signature_param.kind_name)
def is_keyword_param(self):
return self._signature_param
def infer(self):
p = self._signature_param
evaluator = self.parent_context.evaluator
@@ -267,6 +273,9 @@ class UnresolvableParamName(AbstractNameDefinition):
self.parent_context = compiled_obj.parent_context
self.string_name = name
def get_kind(self):
return Parameter.POSITIONAL_ONLY
def infer(self):
return ContextSet()

View File

@@ -6,7 +6,7 @@ from abc import abstractmethod
from parso.tree import search_ancestor
from jedi._compatibility import use_metaclass
from jedi._compatibility import use_metaclass, Parameter
from jedi.cache import memoize_method
from jedi.evaluate import flow_analysis
from jedi.evaluate.base_context import ContextSet, Context
@@ -122,6 +122,22 @@ class ParamName(AbstractTreeName):
self.parent_context = parent_context
self.tree_name = tree_name
def get_kind(self):
tree_param = search_ancestor(self.tree_name, 'param')
if tree_param.star_count == 1: # *args
return Parameter.VAR_POSITIONAL
if tree_param.star_count == 2: # **kwargs
return Parameter.VAR_KEYWORD
parent = tree_param.parent
for p in parent.children:
if p.type == 'param':
if p.star_count:
return Parameter.KEYWORD_ONLY
if p == tree_param:
break
return Parameter.POSITIONAL_OR_KEYWORD
def infer(self):
return self.get_param().infer()