mirror of
https://github.com/davidhalter/jedi.git
synced 2026-05-19 23:09:43 +08:00
Fix classmethod issues
This commit is contained in:
@@ -128,11 +128,7 @@ def _parse_argument_clinic(string):
|
|||||||
allow_kwargs = True
|
allow_kwargs = True
|
||||||
|
|
||||||
|
|
||||||
class AbstractArguments(object):
|
class _AbstractArgumentsMixin(object):
|
||||||
context = None
|
|
||||||
argument_node = None
|
|
||||||
trailer = None
|
|
||||||
|
|
||||||
def eval_all(self, funcdef=None):
|
def eval_all(self, funcdef=None):
|
||||||
"""
|
"""
|
||||||
Evaluates all arguments as a support for static analysis
|
Evaluates all arguments as a support for static analysis
|
||||||
@@ -142,15 +138,21 @@ class AbstractArguments(object):
|
|||||||
types = lazy_context.infer()
|
types = lazy_context.infer()
|
||||||
try_iter_content(types)
|
try_iter_content(types)
|
||||||
|
|
||||||
def get_calling_nodes(self):
|
|
||||||
return []
|
|
||||||
|
|
||||||
def unpack(self, funcdef=None):
|
def unpack(self, funcdef=None):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_executed_params_and_issues(self, execution_context):
|
def get_executed_params_and_issues(self, execution_context):
|
||||||
return get_executed_params_and_issues(execution_context, self)
|
return get_executed_params_and_issues(execution_context, self)
|
||||||
|
|
||||||
|
def get_calling_nodes(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractArguments(_AbstractArgumentsMixin):
|
||||||
|
context = None
|
||||||
|
argument_node = None
|
||||||
|
trailer = None
|
||||||
|
|
||||||
|
|
||||||
class AnonymousArguments(AbstractArguments):
|
class AnonymousArguments(AbstractArguments):
|
||||||
def get_executed_params_and_issues(self, execution_context):
|
def get_executed_params_and_issues(self, execution_context):
|
||||||
@@ -302,6 +304,28 @@ class ValuesArguments(AbstractArguments):
|
|||||||
return '<%s: %s>' % (self.__class__.__name__, self._values_list)
|
return '<%s: %s>' % (self.__class__.__name__, self._values_list)
|
||||||
|
|
||||||
|
|
||||||
|
class TreeArgumentsWrapper(_AbstractArgumentsMixin):
|
||||||
|
def __init__(self, arguments):
|
||||||
|
self._wrapped_arguments = arguments
|
||||||
|
|
||||||
|
@property
|
||||||
|
def argument_node(self):
|
||||||
|
return self._wrapped_arguments.argument_node
|
||||||
|
|
||||||
|
@property
|
||||||
|
def trailer(self):
|
||||||
|
return self._wrapped_arguments.trailer
|
||||||
|
|
||||||
|
def unpack(self, func=None):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_calling_nodes(self):
|
||||||
|
return self._wrapped_arguments.get_calling_nodes()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<%s: %s>' % (self.__class__.__name__, self._wrapped_arguments)
|
||||||
|
|
||||||
|
|
||||||
def _iterate_star_args(context, array, input_node, funcdef=None):
|
def _iterate_star_args(context, array, input_node, funcdef=None):
|
||||||
try:
|
try:
|
||||||
iter_ = array.py__iter__
|
iter_ = array.py__iter__
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from jedi.evaluate.base_context import Context, NO_CONTEXTS, ContextSet, \
|
|||||||
from jedi.evaluate.lazy_context import LazyKnownContext, LazyKnownContexts
|
from jedi.evaluate.lazy_context import LazyKnownContext, LazyKnownContexts
|
||||||
from jedi.evaluate.cache import evaluator_method_cache
|
from jedi.evaluate.cache import evaluator_method_cache
|
||||||
from jedi.evaluate.arguments import AbstractArguments, AnonymousArguments, \
|
from jedi.evaluate.arguments import AbstractArguments, AnonymousArguments, \
|
||||||
ValuesArguments
|
ValuesArguments, TreeArgumentsWrapper
|
||||||
from jedi.evaluate.context.function import FunctionExecutionContext, \
|
from jedi.evaluate.context.function import FunctionExecutionContext, \
|
||||||
FunctionContext, AbstractFunction, OverloadedFunctionContext
|
FunctionContext, AbstractFunction, OverloadedFunctionContext
|
||||||
from jedi.evaluate.context.klass import ClassContext, apply_py__get__, \
|
from jedi.evaluate.context.klass import ClassContext, apply_py__get__, \
|
||||||
@@ -522,32 +522,18 @@ class SelfAttributeFilter(ClassFilter):
|
|||||||
return names
|
return names
|
||||||
|
|
||||||
|
|
||||||
class InstanceArguments(AbstractArguments):
|
class InstanceArguments(TreeArgumentsWrapper):
|
||||||
def __init__(self, instance, arguments):
|
def __init__(self, instance, arguments):
|
||||||
|
super(InstanceArguments, self).__init__(arguments)
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self._arguments = arguments
|
|
||||||
|
|
||||||
@property
|
|
||||||
def argument_node(self):
|
|
||||||
return self._arguments.argument_node
|
|
||||||
|
|
||||||
@property
|
|
||||||
def trailer(self):
|
|
||||||
return self._arguments.trailer
|
|
||||||
|
|
||||||
def unpack(self, func=None):
|
def unpack(self, func=None):
|
||||||
yield None, LazyKnownContext(self.instance)
|
yield None, LazyKnownContext(self.instance)
|
||||||
for values in self._arguments.unpack(func):
|
for values in self._wrapped_arguments.unpack(func):
|
||||||
yield values
|
yield values
|
||||||
|
|
||||||
def get_calling_nodes(self):
|
|
||||||
return self._arguments.get_calling_nodes()
|
|
||||||
|
|
||||||
def get_executed_params_and_issues(self, execution_context):
|
def get_executed_params_and_issues(self, execution_context):
|
||||||
if isinstance(self._arguments, AnonymousInstanceArguments):
|
if isinstance(self._wrapped_arguments, AnonymousInstanceArguments):
|
||||||
return self._arguments.get_executed_params_and_issues(execution_context)
|
return self._wrapped_arguments.get_executed_params_and_issues(execution_context)
|
||||||
|
|
||||||
return super(InstanceArguments, self).get_executed_params_and_issues(execution_context)
|
return super(InstanceArguments, self).get_executed_params_and_issues(execution_context)
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return '<%s: %s>' % (self.__class__.__name__, self._arguments)
|
|
||||||
|
|||||||
+68
-4
@@ -15,19 +15,18 @@ from jedi._compatibility import force_unicode
|
|||||||
from jedi.plugins.base import BasePlugin
|
from jedi.plugins.base import BasePlugin
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.evaluate.arguments import ValuesArguments, \
|
from jedi.evaluate.arguments import ValuesArguments, \
|
||||||
repack_with_argument_clinic, AbstractArguments
|
repack_with_argument_clinic, AbstractArguments, TreeArgumentsWrapper
|
||||||
from jedi.evaluate import analysis
|
from jedi.evaluate import analysis
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate.context.instance import TreeInstance, \
|
from jedi.evaluate.context.instance import TreeInstance, \
|
||||||
AbstractInstanceContext, CompiledInstance, BoundMethod, InstanceArguments
|
AbstractInstanceContext, BoundMethod, InstanceArguments
|
||||||
from jedi.evaluate.base_context import ContextualizedNode, \
|
from jedi.evaluate.base_context import ContextualizedNode, \
|
||||||
NO_CONTEXTS, ContextSet, ContextWrapper
|
NO_CONTEXTS, ContextSet, ContextWrapper
|
||||||
from jedi.evaluate.context import ClassContext, ModuleContext, \
|
from jedi.evaluate.context import ClassContext, ModuleContext, \
|
||||||
FunctionExecutionContext
|
FunctionExecutionContext
|
||||||
from jedi.plugins import typeshed
|
|
||||||
from jedi.evaluate.context.klass import py__mro__
|
from jedi.evaluate.context.klass import py__mro__
|
||||||
from jedi.evaluate.context import iterable
|
from jedi.evaluate.context import iterable
|
||||||
from jedi.evaluate.lazy_context import LazyTreeContext
|
from jedi.evaluate.lazy_context import LazyTreeContext, LazyKnownContext
|
||||||
from jedi.evaluate.syntax_tree import is_string
|
from jedi.evaluate.syntax_tree import is_string
|
||||||
|
|
||||||
# Now this is all part of fake tuples in Jedi. However super doesn't work on
|
# Now this is all part of fake tuples in Jedi. However super doesn't work on
|
||||||
@@ -280,6 +279,69 @@ def builtins_isinstance(objects, types, arguments, evaluator):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StaticMethodObject(AbstractObjectOverwrite, ContextWrapper):
|
||||||
|
def get_object(self):
|
||||||
|
return self._wrapped_context
|
||||||
|
|
||||||
|
@publish_method('__get__')
|
||||||
|
def _py__get__(self):
|
||||||
|
return ContextSet([self._wrapped_context])
|
||||||
|
|
||||||
|
|
||||||
|
@argument_clinic('sequence, /')
|
||||||
|
def builtins_staticmethod(functions):
|
||||||
|
return ContextSet(StaticMethodObject(f) for f in functions)
|
||||||
|
|
||||||
|
|
||||||
|
class ClassMethodObject(AbstractObjectOverwrite, ContextWrapper):
|
||||||
|
def __init__(self, class_method_obj, function):
|
||||||
|
super(ClassMethodObject, self).__init__(class_method_obj)
|
||||||
|
self._function = function
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return self._wrapped_context
|
||||||
|
|
||||||
|
def py__get__(self, obj):
|
||||||
|
actual, = self._wrapped_context.py__getattribute__('__get__')
|
||||||
|
klass = obj
|
||||||
|
if not obj.is_class():
|
||||||
|
klass = obj.py__class__()
|
||||||
|
return ContextSet([ClassMethodGet(actual, klass, self._function)])
|
||||||
|
|
||||||
|
|
||||||
|
class ClassMethodGet(AbstractObjectOverwrite, ContextWrapper):
|
||||||
|
def __init__(self, get_method, klass, function):
|
||||||
|
super(ClassMethodGet, self).__init__(get_method)
|
||||||
|
self._class = klass
|
||||||
|
self._function = function
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return self._wrapped_context
|
||||||
|
|
||||||
|
def py__call__(self, arguments):
|
||||||
|
return self._function.execute(ClassMethodArguments(self._class, arguments))
|
||||||
|
|
||||||
|
|
||||||
|
class ClassMethodArguments(TreeArgumentsWrapper):
|
||||||
|
def __init__(self, klass, arguments):
|
||||||
|
super(ClassMethodArguments, self).__init__(arguments)
|
||||||
|
self._class = klass
|
||||||
|
|
||||||
|
def unpack(self, func=None):
|
||||||
|
yield None, LazyKnownContext(self._class)
|
||||||
|
for values in self._wrapped_arguments.unpack(func):
|
||||||
|
yield values
|
||||||
|
|
||||||
|
|
||||||
|
@argument_clinic('sequence, /', want_obj=True, want_arguments=True)
|
||||||
|
def builtins_classmethod(functions, obj, arguments):
|
||||||
|
return ContextSet(
|
||||||
|
ClassMethodObject(class_method_object, function)
|
||||||
|
for class_method_object in obj.py__call__(arguments=arguments)
|
||||||
|
for function in functions
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def collections_namedtuple(obj, arguments):
|
def collections_namedtuple(obj, arguments):
|
||||||
"""
|
"""
|
||||||
Implementation of the namedtuple function.
|
Implementation of the namedtuple function.
|
||||||
@@ -434,6 +496,8 @@ _implemented = {
|
|||||||
'isinstance': builtins_isinstance,
|
'isinstance': builtins_isinstance,
|
||||||
'next': builtins_next,
|
'next': builtins_next,
|
||||||
'iter': builtins_iter,
|
'iter': builtins_iter,
|
||||||
|
'staticmethod': builtins_staticmethod,
|
||||||
|
'classmethod': builtins_classmethod,
|
||||||
},
|
},
|
||||||
'copy': {
|
'copy': {
|
||||||
'copy': _return_first_param,
|
'copy': _return_first_param,
|
||||||
|
|||||||
Reference in New Issue
Block a user