mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-09 15:24:46 +08:00
Use access handles everywhere
This commit is contained in:
@@ -32,17 +32,17 @@ class CheckAttribute(object):
|
|||||||
# the __iter__ function as long as __getitem__ is defined (it will
|
# the __iter__ function as long as __getitem__ is defined (it will
|
||||||
# just start with __getitem__(0). This is especially true for
|
# just start with __getitem__(0). This is especially true for
|
||||||
# Python 2 strings, where `str.__iter__` is not even defined.
|
# Python 2 strings, where `str.__iter__` is not even defined.
|
||||||
if not instance.access.has_iter():
|
if not instance.access_handle.has_iter():
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
else:
|
else:
|
||||||
instance.access.getattr(self.check_name)
|
instance.access_handle.getattr(self.check_name)
|
||||||
return partial(self.func, instance)
|
return partial(self.func, instance)
|
||||||
|
|
||||||
|
|
||||||
class CompiledObject(Context):
|
class CompiledObject(Context):
|
||||||
def __init__(self, evaluator, access, parent_context=None, faked_class=None):
|
def __init__(self, evaluator, access_handle, parent_context=None, faked_class=None):
|
||||||
super(CompiledObject, self).__init__(evaluator, parent_context)
|
super(CompiledObject, self).__init__(evaluator, parent_context)
|
||||||
self.access = access
|
self.access_handle = access_handle
|
||||||
# This attribute will not be set for most classes, except for fakes.
|
# This attribute will not be set for most classes, except for fakes.
|
||||||
self.tree_node = faked_class
|
self.tree_node = faked_class
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ class CompiledObject(Context):
|
|||||||
parent_context=self.parent_context,
|
parent_context=self.parent_context,
|
||||||
funcdef=self.tree_node
|
funcdef=self.tree_node
|
||||||
).py__call__(params)
|
).py__call__(params)
|
||||||
if self.access.is_class():
|
if self.access_handle.is_class():
|
||||||
from jedi.evaluate.context import CompiledInstance
|
from jedi.evaluate.context import CompiledInstance
|
||||||
return ContextSet(CompiledInstance(self.evaluator, self.parent_context, self, params))
|
return ContextSet(CompiledInstance(self.evaluator, self.parent_context, self, params))
|
||||||
else:
|
else:
|
||||||
@@ -63,40 +63,41 @@ class CompiledObject(Context):
|
|||||||
|
|
||||||
@CheckAttribute
|
@CheckAttribute
|
||||||
def py__class__(self):
|
def py__class__(self):
|
||||||
return create_from_access_path(self.evaluator, self.access.py__class__())
|
return create_from_access_path(self.evaluator, self.access_handle.py__class__())
|
||||||
|
|
||||||
@CheckAttribute
|
@CheckAttribute
|
||||||
def py__mro__(self):
|
def py__mro__(self):
|
||||||
return (self,) + tuple(
|
return (self,) + tuple(
|
||||||
create_from_access_path(self.evaluator, access) for access in self.access.py__mro__accesses()
|
create_from_access_path(self.evaluator, access)
|
||||||
|
for access in self.access_handle.py__mro__accesses()
|
||||||
)
|
)
|
||||||
|
|
||||||
@CheckAttribute
|
@CheckAttribute
|
||||||
def py__bases__(self):
|
def py__bases__(self):
|
||||||
return tuple(
|
return tuple(
|
||||||
create_from_access_path(self.evaluator, access)
|
create_from_access_path(self.evaluator, access)
|
||||||
for access in self.access.py__bases__()
|
for access in self.access_handle.py__bases__()
|
||||||
)
|
)
|
||||||
|
|
||||||
def py__bool__(self):
|
def py__bool__(self):
|
||||||
return self.access.py__bool__()
|
return self.access_handle.py__bool__()
|
||||||
|
|
||||||
def py__file__(self):
|
def py__file__(self):
|
||||||
return self.access.py__file__()
|
return self.access_handle.py__file__()
|
||||||
|
|
||||||
def is_class(self):
|
def is_class(self):
|
||||||
return self.access.is_class()
|
return self.access_handle.is_class()
|
||||||
|
|
||||||
def py__doc__(self, include_call_signature=False):
|
def py__doc__(self, include_call_signature=False):
|
||||||
return self.access.py__doc__()
|
return self.access_handle.py__doc__()
|
||||||
|
|
||||||
def get_param_names(self):
|
def get_param_names(self):
|
||||||
try:
|
try:
|
||||||
signature_params = self.access.get_signature_params()
|
signature_params = self.access_handle.get_signature_params()
|
||||||
except ValueError: # Has no signature
|
except ValueError: # Has no signature
|
||||||
params_str, ret = self._parse_function_doc()
|
params_str, ret = self._parse_function_doc()
|
||||||
tokens = params_str.split(',')
|
tokens = params_str.split(',')
|
||||||
if self.access.ismethoddescriptor():
|
if self.access_handle.ismethoddescriptor():
|
||||||
tokens.insert(0, 'self')
|
tokens.insert(0, 'self')
|
||||||
for p in tokens:
|
for p in tokens:
|
||||||
parts = p.strip().split('=')
|
parts = p.strip().split('=')
|
||||||
@@ -106,7 +107,7 @@ class CompiledObject(Context):
|
|||||||
yield SignatureParamName(self, signature_param)
|
yield SignatureParamName(self, signature_param)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s: %s>' % (self.__class__.__name__, self.access.get_repr())
|
return '<%s: %s>' % (self.__class__.__name__, self.access_handle.get_repr())
|
||||||
|
|
||||||
@underscore_memoization
|
@underscore_memoization
|
||||||
def _parse_function_doc(self):
|
def _parse_function_doc(self):
|
||||||
@@ -118,7 +119,7 @@ class CompiledObject(Context):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def api_type(self):
|
def api_type(self):
|
||||||
return self.access.get_api_type()
|
return self.access_handle.get_api_type()
|
||||||
|
|
||||||
@underscore_memoization
|
@underscore_memoization
|
||||||
def _cls(self):
|
def _cls(self):
|
||||||
@@ -143,7 +144,7 @@ class CompiledObject(Context):
|
|||||||
|
|
||||||
@CheckAttribute
|
@CheckAttribute
|
||||||
def py__getitem__(self, index):
|
def py__getitem__(self, index):
|
||||||
access = self.access.py__getitem__(index)
|
access = self.access_handle.py__getitem__(index)
|
||||||
if access is None:
|
if access is None:
|
||||||
return ContextSet()
|
return ContextSet()
|
||||||
|
|
||||||
@@ -151,17 +152,17 @@ class CompiledObject(Context):
|
|||||||
|
|
||||||
@CheckAttribute
|
@CheckAttribute
|
||||||
def py__iter__(self):
|
def py__iter__(self):
|
||||||
for access in self.access.py__iter__list():
|
for access in self.access_handle.py__iter__list():
|
||||||
yield LazyKnownContext(create_from_access_path(self.evaluator, access))
|
yield LazyKnownContext(create_from_access_path(self.evaluator, access))
|
||||||
|
|
||||||
def py__name__(self):
|
def py__name__(self):
|
||||||
return self.access.py__name__()
|
return self.access_handle.py__name__()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
name = self.py__name__()
|
name = self.py__name__()
|
||||||
if name is None:
|
if name is None:
|
||||||
name = self.access.get_repr()
|
name = self.access_handle.get_repr()
|
||||||
return CompiledContextName(self, name)
|
return CompiledContextName(self, name)
|
||||||
|
|
||||||
def _execute_function(self, params):
|
def _execute_function(self, params):
|
||||||
@@ -171,7 +172,7 @@ class CompiledObject(Context):
|
|||||||
return
|
return
|
||||||
for name in self._parse_function_doc()[1].split():
|
for name in self._parse_function_doc()[1].split():
|
||||||
try:
|
try:
|
||||||
self.evaluator.BUILTINS.access.getattr(name)
|
self.evaluator.BUILTINS.access_handle.getattr(name)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -183,12 +184,13 @@ class CompiledObject(Context):
|
|||||||
|
|
||||||
def dict_values(self):
|
def dict_values(self):
|
||||||
return ContextSet.from_iterable(
|
return ContextSet.from_iterable(
|
||||||
create_from_access_path(self.evaluator, access) for access in self.access.dict_values()
|
create_from_access_path(self.evaluator, access)
|
||||||
|
for access in self.access_handle.dict_values()
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_safe_value(self, default=_sentinel):
|
def get_safe_value(self, default=_sentinel):
|
||||||
try:
|
try:
|
||||||
return self.access.get_safe_value()
|
return self.access_handle.get_safe_value()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if default == _sentinel:
|
if default == _sentinel:
|
||||||
raise
|
raise
|
||||||
@@ -197,14 +199,14 @@ class CompiledObject(Context):
|
|||||||
def execute_operation(self, other, operator):
|
def execute_operation(self, other, operator):
|
||||||
return create_from_access_path(
|
return create_from_access_path(
|
||||||
self.evaluator,
|
self.evaluator,
|
||||||
self.access.execute_operation(other.access, operator)
|
self.access_handle.execute_operation(other.access_handle, operator)
|
||||||
)
|
)
|
||||||
|
|
||||||
def negate(self):
|
def negate(self):
|
||||||
return create_from_access_path(self.evaluator, self.access.negate())
|
return create_from_access_path(self.evaluator, self.access_handle.negate())
|
||||||
|
|
||||||
def is_super_class(self, exception):
|
def is_super_class(self, exception):
|
||||||
return self.access.is_super_class(exception)
|
return self.access_handle.is_super_class(exception)
|
||||||
|
|
||||||
|
|
||||||
class CompiledName(AbstractNameDefinition):
|
class CompiledName(AbstractNameDefinition):
|
||||||
@@ -298,23 +300,23 @@ class CompiledObjectFilter(AbstractFilter):
|
|||||||
def get(self, name):
|
def get(self, name):
|
||||||
name = str(name)
|
name = str(name)
|
||||||
try:
|
try:
|
||||||
if not self._compiled_object.access.is_allowed_getattr(name):
|
if not self._compiled_object.access_handle.is_allowed_getattr(name):
|
||||||
return [EmptyCompiledName(self._evaluator, name)]
|
return [EmptyCompiledName(self._evaluator, name)]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if self._is_instance and name not in self._compiled_object.access.dir():
|
if self._is_instance and name not in self._compiled_object.access_handle.dir():
|
||||||
return []
|
return []
|
||||||
return [self._create_name(name)]
|
return [self._create_name(name)]
|
||||||
|
|
||||||
def values(self):
|
def values(self):
|
||||||
from jedi.evaluate.compiled import builtin_from_name
|
from jedi.evaluate.compiled import builtin_from_name
|
||||||
names = []
|
names = []
|
||||||
for name in self._compiled_object.access.dir():
|
for name in self._compiled_object.access_handle.dir():
|
||||||
names += self.get(name)
|
names += self.get(name)
|
||||||
|
|
||||||
# ``dir`` doesn't include the type names.
|
# ``dir`` doesn't include the type names.
|
||||||
if not self._is_instance and self._compiled_object.access.needs_type_completions():
|
if not self._is_instance and self._compiled_object.access_handle.needs_type_completions():
|
||||||
for filter in builtin_from_name(self._evaluator, 'type').get_filters():
|
for filter in builtin_from_name(self._evaluator, 'type').get_filters():
|
||||||
names += filter.values()
|
names += filter.values()
|
||||||
return names
|
return names
|
||||||
@@ -399,7 +401,7 @@ def _create_from_name(evaluator, compiled_object, name):
|
|||||||
except fake.FakeDoesNotExist:
|
except fake.FakeDoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
access = compiled_object.access.getattr(name, default=None)
|
access = compiled_object.access_handle.getattr(name, default=None)
|
||||||
return create_cached_compiled_object(
|
return create_cached_compiled_object(
|
||||||
evaluator, access, parent_context=compiled_object, faked=faked
|
evaluator, access, parent_context=compiled_object, faked=faked
|
||||||
)
|
)
|
||||||
@@ -429,5 +431,5 @@ def create_from_access_path(evaluator, access_path):
|
|||||||
|
|
||||||
@_normalize_create_args
|
@_normalize_create_args
|
||||||
@evaluator_function_cache()
|
@evaluator_function_cache()
|
||||||
def create_cached_compiled_object(evaluator, access, parent_context, faked):
|
def create_cached_compiled_object(evaluator, access_handle, parent_context, faked):
|
||||||
return CompiledObject(evaluator, access, parent_context, faked)
|
return CompiledObject(evaluator, access_handle, parent_context, faked)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class MixedObject(object):
|
|||||||
self.parent_context = parent_context
|
self.parent_context = parent_context
|
||||||
self.compiled_object = compiled_object
|
self.compiled_object = compiled_object
|
||||||
self._context = tree_context
|
self._context = tree_context
|
||||||
self.access = compiled_object.access
|
self.access_handle = compiled_object.access_handle
|
||||||
|
|
||||||
# We have to overwrite everything that has to do with trailers, name
|
# We have to overwrite everything that has to do with trailers, name
|
||||||
# lookups and filters to make it possible to route name lookups towards
|
# lookups and filters to make it possible to route name lookups towards
|
||||||
@@ -51,7 +51,7 @@ class MixedObject(object):
|
|||||||
yield MixedObjectFilter(self.evaluator, self)
|
yield MixedObjectFilter(self.evaluator, self)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s: %s>' % (type(self).__name__, repr(self.access))
|
return '<%s: %s>' % (type(self).__name__, self.access_handle.get_repr())
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return getattr(self._context, name)
|
return getattr(self._context, name)
|
||||||
@@ -76,11 +76,11 @@ class MixedName(compiled.CompiledName):
|
|||||||
|
|
||||||
@underscore_memoization
|
@underscore_memoization
|
||||||
def infer(self):
|
def infer(self):
|
||||||
access = self.parent_context.access
|
access_handle = self.parent_context.access_handle
|
||||||
# TODO use logic from compiled.CompiledObjectFilter
|
# TODO use logic from compiled.CompiledObjectFilter
|
||||||
access = access.getattr(self.string_name, default=None)
|
access_handle = access_handle.getattr(self.string_name, default=None)
|
||||||
return ContextSet(
|
return ContextSet(
|
||||||
_create(self._evaluator, access, parent_context=self.parent_context)
|
_create(self._evaluator, access_handle, parent_context=self.parent_context)
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -132,10 +132,10 @@ def _get_object_to_check(python_object):
|
|||||||
raise TypeError # Prevents computation of `repr` within inspect.
|
raise TypeError # Prevents computation of `repr` within inspect.
|
||||||
|
|
||||||
|
|
||||||
def _find_syntax_node_name(evaluator, access):
|
def _find_syntax_node_name(evaluator, access_handle):
|
||||||
# TODO accessing this is bad, but it probably doesn't matter that much,
|
# TODO accessing this is bad, but it probably doesn't matter that much,
|
||||||
# because we're working with interpreteters only here.
|
# because we're working with interpreteters only here.
|
||||||
python_object = access._obj
|
python_object = access_handle.access._obj
|
||||||
try:
|
try:
|
||||||
python_object = _get_object_to_check(python_object)
|
python_object = _get_object_to_check(python_object)
|
||||||
path = inspect.getsourcefile(python_object)
|
path = inspect.getsourcefile(python_object)
|
||||||
@@ -195,11 +195,11 @@ def _find_syntax_node_name(evaluator, access):
|
|||||||
|
|
||||||
|
|
||||||
@compiled_objects_cache('mixed_cache')
|
@compiled_objects_cache('mixed_cache')
|
||||||
def _create(evaluator, access, parent_context=None, *args):
|
def _create(evaluator, access_handle, parent_context=None, *args):
|
||||||
tree_node, path = _find_syntax_node_name(evaluator, access)
|
tree_node, path = _find_syntax_node_name(evaluator, access_handle)
|
||||||
|
|
||||||
compiled_object = create_cached_compiled_object(
|
compiled_object = create_cached_compiled_object(
|
||||||
evaluator, access, parent_context=parent_context.compiled_object)
|
evaluator, access_handle, parent_context=parent_context.compiled_object)
|
||||||
if tree_node is None:
|
if tree_node is None:
|
||||||
return compiled_object
|
return compiled_object
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ def _create(evaluator, access, parent_context=None, *args):
|
|||||||
node_is_object=True
|
node_is_object=True
|
||||||
)
|
)
|
||||||
if tree_node.type == 'classdef':
|
if tree_node.type == 'classdef':
|
||||||
if not access.is_class():
|
if not access_handle.is_class():
|
||||||
# Is an instance, not a class.
|
# Is an instance, not a class.
|
||||||
tree_context, = tree_context.execute_evaluated()
|
tree_context, = tree_context.execute_evaluated()
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ class Listener():
|
|||||||
|
|
||||||
print(result, payload, file=sys.stderr)
|
print(result, payload, file=sys.stderr)
|
||||||
|
|
||||||
ModifiedPickler(stdout, protocol=_PICKLE_PROTOCOL).dump(result)
|
ModifiedPickler(file=stdout, protocol=_PICKLE_PROTOCOL).dump(result)
|
||||||
stdout.flush()
|
stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
@@ -214,9 +214,8 @@ class ModifiedUnpickler(pickle._Unpickler):
|
|||||||
|
|
||||||
|
|
||||||
class ModifiedPickler(pickle._Pickler):
|
class ModifiedPickler(pickle._Pickler):
|
||||||
def __init__(self, subprocess, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(ModifiedPickler, self).__init__(*args, **kwargs)
|
super(ModifiedPickler, self).__init__(*args, **kwargs)
|
||||||
self._subprocess = subprocess
|
|
||||||
|
|
||||||
def save(self, obj, *args, **kwargs):
|
def save(self, obj, *args, **kwargs):
|
||||||
print('s', obj, args, kwargs, file=sys.stderr)
|
print('s', obj, args, kwargs, file=sys.stderr)
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ class BoundMethod(FunctionContext):
|
|||||||
class CompiledBoundMethod(compiled.CompiledObject):
|
class CompiledBoundMethod(compiled.CompiledObject):
|
||||||
def __init__(self, func):
|
def __init__(self, func):
|
||||||
super(CompiledBoundMethod, self).__init__(
|
super(CompiledBoundMethod, self).__init__(
|
||||||
func.evaluator, func.access, func.parent_context, func.tree_node)
|
func.evaluator, func.access_handle, func.parent_context, func.tree_node)
|
||||||
|
|
||||||
def get_param_names(self):
|
def get_param_names(self):
|
||||||
return list(super(CompiledBoundMethod, self).get_param_names())[1:]
|
return list(super(CompiledBoundMethod, self).get_param_names())[1:]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from jedi._compatibility import py_version, unicode
|
|||||||
|
|
||||||
def _eval_literal(code):
|
def _eval_literal(code):
|
||||||
def_, = jedi.Script(code).goto_definitions()
|
def_, = jedi.Script(code).goto_definitions()
|
||||||
return def_._name._context.access._obj
|
return def_._name._context.access_handle.access._obj
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif('sys.version_info[:2] < (3, 6)')
|
@pytest.mark.skipif('sys.version_info[:2] < (3, 6)')
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ def test_equals(source):
|
|||||||
script = Script(source)
|
script = Script(source)
|
||||||
node = script._get_module_node().children[0]
|
node = script._get_module_node().children[0]
|
||||||
first, = script._get_module().eval_node(node)
|
first, = script._get_module().eval_node(node)
|
||||||
assert isinstance(first, CompiledObject) and first.access._obj is True
|
assert isinstance(first, CompiledObject) and first.access_handle.access._obj is True
|
||||||
|
|||||||
Reference in New Issue
Block a user