mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-09 23:34:45 +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
|
||||
# just start with __getitem__(0). This is especially true for
|
||||
# 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
|
||||
else:
|
||||
instance.access.getattr(self.check_name)
|
||||
instance.access_handle.getattr(self.check_name)
|
||||
return partial(self.func, instance)
|
||||
|
||||
|
||||
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)
|
||||
self.access = access
|
||||
self.access_handle = access_handle
|
||||
# This attribute will not be set for most classes, except for fakes.
|
||||
self.tree_node = faked_class
|
||||
|
||||
@@ -55,7 +55,7 @@ class CompiledObject(Context):
|
||||
parent_context=self.parent_context,
|
||||
funcdef=self.tree_node
|
||||
).py__call__(params)
|
||||
if self.access.is_class():
|
||||
if self.access_handle.is_class():
|
||||
from jedi.evaluate.context import CompiledInstance
|
||||
return ContextSet(CompiledInstance(self.evaluator, self.parent_context, self, params))
|
||||
else:
|
||||
@@ -63,40 +63,41 @@ class CompiledObject(Context):
|
||||
|
||||
@CheckAttribute
|
||||
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
|
||||
def py__mro__(self):
|
||||
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
|
||||
def py__bases__(self):
|
||||
return tuple(
|
||||
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):
|
||||
return self.access.py__bool__()
|
||||
return self.access_handle.py__bool__()
|
||||
|
||||
def py__file__(self):
|
||||
return self.access.py__file__()
|
||||
return self.access_handle.py__file__()
|
||||
|
||||
def is_class(self):
|
||||
return self.access.is_class()
|
||||
return self.access_handle.is_class()
|
||||
|
||||
def py__doc__(self, include_call_signature=False):
|
||||
return self.access.py__doc__()
|
||||
return self.access_handle.py__doc__()
|
||||
|
||||
def get_param_names(self):
|
||||
try:
|
||||
signature_params = self.access.get_signature_params()
|
||||
signature_params = self.access_handle.get_signature_params()
|
||||
except ValueError: # Has no signature
|
||||
params_str, ret = self._parse_function_doc()
|
||||
tokens = params_str.split(',')
|
||||
if self.access.ismethoddescriptor():
|
||||
if self.access_handle.ismethoddescriptor():
|
||||
tokens.insert(0, 'self')
|
||||
for p in tokens:
|
||||
parts = p.strip().split('=')
|
||||
@@ -106,7 +107,7 @@ class CompiledObject(Context):
|
||||
yield SignatureParamName(self, signature_param)
|
||||
|
||||
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
|
||||
def _parse_function_doc(self):
|
||||
@@ -118,7 +119,7 @@ class CompiledObject(Context):
|
||||
|
||||
@property
|
||||
def api_type(self):
|
||||
return self.access.get_api_type()
|
||||
return self.access_handle.get_api_type()
|
||||
|
||||
@underscore_memoization
|
||||
def _cls(self):
|
||||
@@ -143,7 +144,7 @@ class CompiledObject(Context):
|
||||
|
||||
@CheckAttribute
|
||||
def py__getitem__(self, index):
|
||||
access = self.access.py__getitem__(index)
|
||||
access = self.access_handle.py__getitem__(index)
|
||||
if access is None:
|
||||
return ContextSet()
|
||||
|
||||
@@ -151,17 +152,17 @@ class CompiledObject(Context):
|
||||
|
||||
@CheckAttribute
|
||||
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))
|
||||
|
||||
def py__name__(self):
|
||||
return self.access.py__name__()
|
||||
return self.access_handle.py__name__()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
name = self.py__name__()
|
||||
if name is None:
|
||||
name = self.access.get_repr()
|
||||
name = self.access_handle.get_repr()
|
||||
return CompiledContextName(self, name)
|
||||
|
||||
def _execute_function(self, params):
|
||||
@@ -171,7 +172,7 @@ class CompiledObject(Context):
|
||||
return
|
||||
for name in self._parse_function_doc()[1].split():
|
||||
try:
|
||||
self.evaluator.BUILTINS.access.getattr(name)
|
||||
self.evaluator.BUILTINS.access_handle.getattr(name)
|
||||
except AttributeError:
|
||||
continue
|
||||
else:
|
||||
@@ -183,12 +184,13 @@ class CompiledObject(Context):
|
||||
|
||||
def dict_values(self):
|
||||
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):
|
||||
try:
|
||||
return self.access.get_safe_value()
|
||||
return self.access_handle.get_safe_value()
|
||||
except ValueError:
|
||||
if default == _sentinel:
|
||||
raise
|
||||
@@ -197,14 +199,14 @@ class CompiledObject(Context):
|
||||
def execute_operation(self, other, operator):
|
||||
return create_from_access_path(
|
||||
self.evaluator,
|
||||
self.access.execute_operation(other.access, operator)
|
||||
self.access_handle.execute_operation(other.access_handle, operator)
|
||||
)
|
||||
|
||||
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):
|
||||
return self.access.is_super_class(exception)
|
||||
return self.access_handle.is_super_class(exception)
|
||||
|
||||
|
||||
class CompiledName(AbstractNameDefinition):
|
||||
@@ -298,23 +300,23 @@ class CompiledObjectFilter(AbstractFilter):
|
||||
def get(self, name):
|
||||
name = str(name)
|
||||
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)]
|
||||
except AttributeError:
|
||||
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 [self._create_name(name)]
|
||||
|
||||
def values(self):
|
||||
from jedi.evaluate.compiled import builtin_from_name
|
||||
names = []
|
||||
for name in self._compiled_object.access.dir():
|
||||
for name in self._compiled_object.access_handle.dir():
|
||||
names += self.get(name)
|
||||
|
||||
# ``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():
|
||||
names += filter.values()
|
||||
return names
|
||||
@@ -399,7 +401,7 @@ def _create_from_name(evaluator, compiled_object, name):
|
||||
except fake.FakeDoesNotExist:
|
||||
pass
|
||||
|
||||
access = compiled_object.access.getattr(name, default=None)
|
||||
access = compiled_object.access_handle.getattr(name, default=None)
|
||||
return create_cached_compiled_object(
|
||||
evaluator, access, parent_context=compiled_object, faked=faked
|
||||
)
|
||||
@@ -429,5 +431,5 @@ def create_from_access_path(evaluator, access_path):
|
||||
|
||||
@_normalize_create_args
|
||||
@evaluator_function_cache()
|
||||
def create_cached_compiled_object(evaluator, access, parent_context, faked):
|
||||
return CompiledObject(evaluator, access, parent_context, faked)
|
||||
def create_cached_compiled_object(evaluator, access_handle, parent_context, faked):
|
||||
return CompiledObject(evaluator, access_handle, parent_context, faked)
|
||||
|
||||
@@ -39,7 +39,7 @@ class MixedObject(object):
|
||||
self.parent_context = parent_context
|
||||
self.compiled_object = compiled_object
|
||||
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
|
||||
# lookups and filters to make it possible to route name lookups towards
|
||||
@@ -51,7 +51,7 @@ class MixedObject(object):
|
||||
yield MixedObjectFilter(self.evaluator, 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):
|
||||
return getattr(self._context, name)
|
||||
@@ -76,11 +76,11 @@ class MixedName(compiled.CompiledName):
|
||||
|
||||
@underscore_memoization
|
||||
def infer(self):
|
||||
access = self.parent_context.access
|
||||
access_handle = self.parent_context.access_handle
|
||||
# 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(
|
||||
_create(self._evaluator, access, parent_context=self.parent_context)
|
||||
_create(self._evaluator, access_handle, parent_context=self.parent_context)
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -132,10 +132,10 @@ def _get_object_to_check(python_object):
|
||||
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,
|
||||
# because we're working with interpreteters only here.
|
||||
python_object = access._obj
|
||||
python_object = access_handle.access._obj
|
||||
try:
|
||||
python_object = _get_object_to_check(python_object)
|
||||
path = inspect.getsourcefile(python_object)
|
||||
@@ -195,11 +195,11 @@ def _find_syntax_node_name(evaluator, access):
|
||||
|
||||
|
||||
@compiled_objects_cache('mixed_cache')
|
||||
def _create(evaluator, access, parent_context=None, *args):
|
||||
tree_node, path = _find_syntax_node_name(evaluator, access)
|
||||
def _create(evaluator, access_handle, parent_context=None, *args):
|
||||
tree_node, path = _find_syntax_node_name(evaluator, access_handle)
|
||||
|
||||
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:
|
||||
return compiled_object
|
||||
|
||||
@@ -218,7 +218,7 @@ def _create(evaluator, access, parent_context=None, *args):
|
||||
node_is_object=True
|
||||
)
|
||||
if tree_node.type == 'classdef':
|
||||
if not access.is_class():
|
||||
if not access_handle.is_class():
|
||||
# Is an instance, not a class.
|
||||
tree_context, = tree_context.execute_evaluated()
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ class Listener():
|
||||
|
||||
print(result, payload, file=sys.stderr)
|
||||
|
||||
ModifiedPickler(stdout, protocol=_PICKLE_PROTOCOL).dump(result)
|
||||
ModifiedPickler(file=stdout, protocol=_PICKLE_PROTOCOL).dump(result)
|
||||
stdout.flush()
|
||||
|
||||
|
||||
@@ -214,9 +214,8 @@ class ModifiedUnpickler(pickle._Unpickler):
|
||||
|
||||
|
||||
class ModifiedPickler(pickle._Pickler):
|
||||
def __init__(self, subprocess, *args, **kwargs):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ModifiedPickler, self).__init__(*args, **kwargs)
|
||||
self._subprocess = subprocess
|
||||
|
||||
def save(self, obj, *args, **kwargs):
|
||||
print('s', obj, args, kwargs, file=sys.stderr)
|
||||
|
||||
@@ -305,7 +305,7 @@ class BoundMethod(FunctionContext):
|
||||
class CompiledBoundMethod(compiled.CompiledObject):
|
||||
def __init__(self, func):
|
||||
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):
|
||||
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_, = 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)')
|
||||
|
||||
@@ -14,4 +14,4 @@ def test_equals(source):
|
||||
script = Script(source)
|
||||
node = script._get_module_node().children[0]
|
||||
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