Use access handles everywhere

This commit is contained in:
Dave Halter
2017-12-06 14:46:27 +01:00
parent 7db6d11c49
commit f09ca9fc20
6 changed files with 51 additions and 50 deletions

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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:]

View File

@@ -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)')

View File

@@ -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