forked from VimPlug/jedi
Make it possible to access properties again
This time we catch all exceptions and try to avoid issues for the user. This is only happening when working with an Interpreter. I don't feel this is necessary otherwise. See #1299
This commit is contained in:
@@ -11,6 +11,8 @@ Changelog
|
||||
- ``*args``/``**kwargs`` resolving. If possible Jedi replaces the parameters
|
||||
with the actual alternatives.
|
||||
- Better support for enums/dataclasses
|
||||
- When using Interpreter, properties are now executed, since a lot of people
|
||||
have complained about this. Discussion in #1299.
|
||||
|
||||
New APIs:
|
||||
|
||||
|
||||
@@ -436,6 +436,7 @@ class Interpreter(Script):
|
||||
>>> print(script.completions()[0].name)
|
||||
upper
|
||||
"""
|
||||
_allow_descriptor_getattr_default = True
|
||||
|
||||
def __init__(self, source, namespaces, **kwds):
|
||||
"""
|
||||
@@ -466,6 +467,7 @@ class Interpreter(Script):
|
||||
super(Interpreter, self).__init__(source, environment=environment,
|
||||
_project=Project(os.getcwd()), **kwds)
|
||||
self.namespaces = namespaces
|
||||
self._evaluator.allow_descriptor_getattr = self._allow_descriptor_getattr_default
|
||||
|
||||
def _get_module(self):
|
||||
return interpreter.MixedModuleContext(
|
||||
|
||||
@@ -106,6 +106,7 @@ class Evaluator(object):
|
||||
self.is_analysis = False
|
||||
self.project = project
|
||||
self.access_cache = {}
|
||||
self.allow_descriptor_getattr = False
|
||||
|
||||
self.reset_recursion_limitations()
|
||||
self.allow_different_encoding = True
|
||||
|
||||
@@ -340,12 +340,16 @@ class DirectObjectAccess(object):
|
||||
def getattr_paths(self, name, default=_sentinel):
|
||||
try:
|
||||
return_obj = getattr(self._obj, name)
|
||||
except AttributeError:
|
||||
# Happens e.g. in properties of
|
||||
# PyQt4.QtGui.QStyleOptionComboBox.currentText
|
||||
# -> just set it to None
|
||||
except Exception as e:
|
||||
if default is _sentinel:
|
||||
raise
|
||||
if isinstance(e, AttributeError):
|
||||
# Happens e.g. in properties of
|
||||
# PyQt4.QtGui.QStyleOptionComboBox.currentText
|
||||
# -> just set it to None
|
||||
raise
|
||||
# Just in case anything happens, return an AttributeError. It
|
||||
# should not crash.
|
||||
raise AttributeError
|
||||
return_obj = default
|
||||
access = self._create_access(return_obj)
|
||||
if inspect.ismodule(return_obj):
|
||||
|
||||
@@ -399,7 +399,7 @@ class CompiledObjectFilter(AbstractFilter):
|
||||
# Always use unicode objects in Python 2 from here.
|
||||
name = force_unicode(name)
|
||||
|
||||
if is_descriptor or not has_attribute:
|
||||
if (is_descriptor and not self._evaluator.allow_descriptor_getattr) or not has_attribute:
|
||||
return [self._get_cached_name(name, is_empty=True)]
|
||||
|
||||
if self.is_instance and name not in dir_callback():
|
||||
|
||||
@@ -7,7 +7,7 @@ import pytest
|
||||
|
||||
import jedi
|
||||
from jedi._compatibility import is_py3, py_version
|
||||
from jedi.evaluate.compiled import mixed
|
||||
from jedi.evaluate.compiled import mixed, context
|
||||
from importlib import import_module
|
||||
|
||||
if py_version > 30:
|
||||
@@ -197,7 +197,13 @@ def test_getitem_side_effects():
|
||||
_assert_interpreter_complete('foo["asdf"].upper', locals(), ['upper'])
|
||||
|
||||
|
||||
def test_property_error_oldstyle():
|
||||
@pytest.fixture(params=[False, True])
|
||||
def allow_descriptor_access_or_not(request, monkeypatch):
|
||||
monkeypatch.setattr(jedi.Interpreter, '_allow_descriptor_getattr_default', request.param)
|
||||
return request.param
|
||||
|
||||
|
||||
def test_property_error_oldstyle(allow_descriptor_access_or_not):
|
||||
lst = []
|
||||
class Foo3:
|
||||
@property
|
||||
@@ -209,11 +215,14 @@ def test_property_error_oldstyle():
|
||||
_assert_interpreter_complete('foo.bar', locals(), ['bar'])
|
||||
_assert_interpreter_complete('foo.bar.baz', locals(), [])
|
||||
|
||||
# There should not be side effects
|
||||
assert lst == []
|
||||
if allow_descriptor_access_or_not:
|
||||
assert lst == [1, 1]
|
||||
else:
|
||||
# There should not be side effects
|
||||
assert lst == []
|
||||
|
||||
|
||||
def test_property_error_newstyle():
|
||||
def test_property_error_newstyle(allow_descriptor_access_or_not):
|
||||
lst = []
|
||||
class Foo3(object):
|
||||
@property
|
||||
@@ -225,8 +234,22 @@ def test_property_error_newstyle():
|
||||
_assert_interpreter_complete('foo.bar', locals(), ['bar'])
|
||||
_assert_interpreter_complete('foo.bar.baz', locals(), [])
|
||||
|
||||
# There should not be side effects
|
||||
assert lst == []
|
||||
if allow_descriptor_access_or_not:
|
||||
assert lst == [1, 1]
|
||||
else:
|
||||
# There should not be side effects
|
||||
assert lst == []
|
||||
|
||||
|
||||
def test_property_content():
|
||||
class Foo3(object):
|
||||
@property
|
||||
def bar(self):
|
||||
return 1
|
||||
|
||||
foo = Foo3()
|
||||
def_, = jedi.Interpreter('foo.bar', [locals()]).goto_definitions()
|
||||
assert def_.name == 'int'
|
||||
|
||||
|
||||
@pytest.mark.skipif(sys.version_info[0] == 2, reason="Ignore Python 2, because EOL")
|
||||
|
||||
Reference in New Issue
Block a user