1
0
forked from VimPlug/jedi

@property now returns Name.type == 'property', fixes muffinmad/anakin-language-server#15

This commit is contained in:
Dave Halter
2020-07-20 01:20:24 +02:00
parent 7281302281
commit 784e965d3a
7 changed files with 57 additions and 3 deletions

View File

@@ -13,8 +13,12 @@ Unreleased
- ``Definition.module_path`` - ``Definition.module_path``
- ``Refactoring.get_renames`` - ``Refactoring.get_renames``
- ``Refactoring.get_changed_files`` - ``Refactoring.get_changed_files``
- Functions with ``@property`` now return ``property`` instead of ``function``
in ``Name().type``
- Started using annotations - Started using annotations
This is likely going to be the last minor release before 1.0.
0.17.2 (2020-07-17) 0.17.2 (2020-07-17)
+++++++++++++++++++ +++++++++++++++++++

View File

@@ -130,7 +130,11 @@ def goto_or_help(request, Script):
@pytest.fixture(scope='session', params=['goto', 'help', 'infer']) @pytest.fixture(scope='session', params=['goto', 'help', 'infer'])
def goto_or_help_or_infer(request, Script): def goto_or_help_or_infer(request, Script):
return lambda code, *args, **kwargs: getattr(Script(code), request.param)(*args, **kwargs) def do(code, *args, **kwargs):
return getattr(Script(code), request.param)(*args, **kwargs)
do.type = request.param
return do
@pytest.fixture(scope='session') @pytest.fixture(scope='session')

View File

@@ -174,7 +174,7 @@ class BaseName(object):
'function' 'function'
Valid values for type are ``module``, ``class``, ``instance``, ``function``, Valid values for type are ``module``, ``class``, ``instance``, ``function``,
``param``, ``path``, ``keyword`` and ``statement``. ``param``, ``path``, ``keyword``, ``property`` and ``statement``.
""" """
tree_name = self._name.tree_name tree_name = self._name.tree_name

View File

@@ -37,7 +37,8 @@ py__doc__() Returns the docstring for a value.
""" """
from jedi import debug from jedi import debug
from jedi.parser_utils import get_cached_parent_scope, expr_is_dotted from jedi.parser_utils import get_cached_parent_scope, expr_is_dotted, \
function_is_property
from jedi.inference.cache import inference_state_method_cache, CachedMetaClass, \ from jedi.inference.cache import inference_state_method_cache, CachedMetaClass, \
inference_state_method_generator_cache inference_state_method_generator_cache
from jedi.inference import compiled from jedi.inference import compiled
@@ -72,6 +73,20 @@ class ClassName(TreeNameDefinition):
else: else:
yield result_value yield result_value
@property
def api_type(self):
if self.tree_name is not None:
definition = self.tree_name.get_definition()
if definition.type == 'funcdef':
if function_is_property(definition):
# This essentially checks if there is an @property before
# the function. @property could be something different, but
# any programmer that redefines property as something that
# is not really a property anymore, should be shot. (i.e.
# this is a heuristic).
return 'property'
return super().api_type
class ClassFilter(ParserTreeFilter): class ClassFilter(ParserTreeFilter):
def __init__(self, class_value, node_context=None, until_position=None, def __init__(self, class_value, node_context=None, until_position=None,

View File

@@ -316,3 +316,4 @@ def _function_is_x_method(method_name):
function_is_staticmethod = _function_is_x_method('staticmethod') function_is_staticmethod = _function_is_x_method('staticmethod')
function_is_classmethod = _function_is_x_method('classmethod') function_is_classmethod = _function_is_x_method('classmethod')
function_is_property = _function_is_x_method('property')

View File

@@ -384,6 +384,8 @@ def builtins_classmethod(functions, value, arguments):
class PropertyObject(AttributeOverwrite, ValueWrapper): class PropertyObject(AttributeOverwrite, ValueWrapper):
api_type = 'property'
def __init__(self, property_obj, function): def __init__(self, property_obj, function):
super().__init__(property_obj) super().__init__(property_obj)
self._function = function self._function = function

View File

@@ -373,6 +373,34 @@ def test_type_II(Script):
assert c.type == 'keyword' assert c.type == 'keyword'
@pytest.mark.parametrize(
'added_code, expected_type, expected_infer_type', [
('Foo().x', 'property', 'instance'),
('Foo.x', 'property', 'property'),
('Foo().y', 'function', 'function'),
('Foo.y', 'function', 'function'),
('Foo().z', 'function', 'function'),
('Foo.z', 'function', 'function'),
]
)
def test_class_types(goto_or_help_or_infer, added_code, expected_type,
expected_infer_type):
code = dedent('''\
class Foo:
@property
def x(self): return 1
@staticmethod
def y(self): ...
@classmethod
def z(self): ...
''')
d, = goto_or_help_or_infer(code + added_code)
if goto_or_help_or_infer.type == 'infer':
assert d.type == expected_infer_type
else:
assert d.type == expected_type
""" """
This tests the BaseName.goto function, not the jedi This tests the BaseName.goto function, not the jedi
function. They are not really different in functionality, but really function. They are not really different in functionality, but really