mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 14:34:31 +08:00
Merge pull request #176 from tkf/basedefinition-type
More detailed BaseDefinition.type (fixes #169)
This commit is contained in:
12
jedi/api.py
12
jedi/api.py
@@ -271,7 +271,7 @@ class Script(object):
|
|||||||
|
|
||||||
d = set([api_classes.Definition(s) for s in scopes
|
d = set([api_classes.Definition(s) for s in scopes
|
||||||
if not isinstance(s, imports.ImportPath._GlobalNamespace)])
|
if not isinstance(s, imports.ImportPath._GlobalNamespace)])
|
||||||
return sorted(d, key=lambda x: (x.module_path, x.start_pos))
|
return self._sorted_defs(d)
|
||||||
|
|
||||||
@api_classes._clear_caches_after_call
|
@api_classes._clear_caches_after_call
|
||||||
def goto(self):
|
def goto(self):
|
||||||
@@ -284,7 +284,7 @@ class Script(object):
|
|||||||
:rtype: list of :class:`api_classes.Definition`
|
:rtype: list of :class:`api_classes.Definition`
|
||||||
"""
|
"""
|
||||||
d = [api_classes.Definition(d) for d in set(self._goto()[0])]
|
d = [api_classes.Definition(d) for d in set(self._goto()[0])]
|
||||||
return sorted(d, key=lambda x: (x.module_path, x.start_pos))
|
return self._sorted_defs(d)
|
||||||
|
|
||||||
def _goto(self, add_import_name=False):
|
def _goto(self, add_import_name=False):
|
||||||
"""
|
"""
|
||||||
@@ -370,7 +370,7 @@ class Script(object):
|
|||||||
else:
|
else:
|
||||||
names.append(api_classes.RelatedName(d.names[-1], d))
|
names.append(api_classes.RelatedName(d.names[-1], d))
|
||||||
|
|
||||||
return sorted(set(names), key=lambda x: (x.module_path, x.start_pos))
|
return self._sorted_defs(set(names))
|
||||||
|
|
||||||
def get_in_function_call(self):
|
def get_in_function_call(self):
|
||||||
"""
|
"""
|
||||||
@@ -491,6 +491,12 @@ class Script(object):
|
|||||||
match = re.match(r'^(.*?)(\.|)(\w?[\w\d]*)$', path, flags=re.S)
|
match = re.match(r'^(.*?)(\.|)(\w?[\w\d]*)$', path, flags=re.S)
|
||||||
return match.groups()
|
return match.groups()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _sorted_defs(d):
|
||||||
|
# Note: `or ''` below is required because `module_path` could be
|
||||||
|
# None and you can't compare None and str in Python 3.
|
||||||
|
return sorted(d, key=lambda x: (x.module_path or '', x.start_pos))
|
||||||
|
|
||||||
|
|
||||||
def defined_names(source, source_path=None, source_encoding='utf-8'):
|
def defined_names(source, source_path=None, source_encoding='utf-8'):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -120,20 +120,22 @@ class BaseDefinition(object):
|
|||||||
Finally, here is what you can get from :attr:`type`:
|
Finally, here is what you can get from :attr:`type`:
|
||||||
|
|
||||||
>>> defs[0].type
|
>>> defs[0].type
|
||||||
'Module'
|
'module'
|
||||||
>>> defs[1].type
|
>>> defs[1].type
|
||||||
'Class'
|
'class'
|
||||||
>>> defs[2].type
|
>>> defs[2].type
|
||||||
'Instance'
|
'instance'
|
||||||
>>> defs[3].type
|
>>> defs[3].type
|
||||||
'Function'
|
'function'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# generate the type
|
# generate the type
|
||||||
stripped = self.definition
|
stripped = self.definition
|
||||||
if isinstance(self.definition, er.InstanceElement):
|
if isinstance(self.definition, er.InstanceElement):
|
||||||
stripped = self.definition.var
|
stripped = self.definition.var
|
||||||
return type(stripped).__name__
|
if isinstance(stripped, pr.Name):
|
||||||
|
stripped = stripped.parent
|
||||||
|
return type(stripped).__name__.lower()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
|
|||||||
53
test/test_api_classes.py
Normal file
53
test/test_api_classes.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import textwrap
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from jedi import api
|
||||||
|
|
||||||
|
|
||||||
|
def make_definitions():
|
||||||
|
"""
|
||||||
|
Return a list of definitions for parametrized tests.
|
||||||
|
|
||||||
|
:rtype: [jedi.api_classes.BaseDefinition]
|
||||||
|
"""
|
||||||
|
source = textwrap.dedent("""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class C:
|
||||||
|
pass
|
||||||
|
|
||||||
|
x = C()
|
||||||
|
|
||||||
|
def f():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def g():
|
||||||
|
yield
|
||||||
|
|
||||||
|
h = lambda: None
|
||||||
|
""")
|
||||||
|
|
||||||
|
definitions = []
|
||||||
|
definitions += api.defined_names(source)
|
||||||
|
|
||||||
|
source += textwrap.dedent("""
|
||||||
|
variable = sys or C or x or f or g or h""")
|
||||||
|
lines = source.splitlines()
|
||||||
|
script = api.Script(source, len(lines), len('variable'), None)
|
||||||
|
definitions += script.definition()
|
||||||
|
|
||||||
|
script2 = api.Script(source, 4, len('class C'), None)
|
||||||
|
definitions += script2.related_names()
|
||||||
|
|
||||||
|
source_param = "def f(a): return a"
|
||||||
|
script_param = api.Script(source_param, 1, len(source_param), None)
|
||||||
|
definitions += script_param.goto()
|
||||||
|
|
||||||
|
return definitions
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('definition', make_definitions())
|
||||||
|
def test_basedefinition_type(definition):
|
||||||
|
assert definition.type in ('module', 'class', 'instance', 'function',
|
||||||
|
'statement', 'import', 'param')
|
||||||
@@ -319,7 +319,7 @@ class TestRegression(TestBase):
|
|||||||
# attributes
|
# attributes
|
||||||
objs = itertools.chain.from_iterable(r.follow_definition() for r in c)
|
objs = itertools.chain.from_iterable(r.follow_definition() for r in c)
|
||||||
types = [o.type for o in objs]
|
types = [o.type for o in objs]
|
||||||
assert 'Import' not in types and 'Class' in types
|
assert 'import' not in types and 'class' in types
|
||||||
|
|
||||||
def test_keyword_definition_doc(self):
|
def test_keyword_definition_doc(self):
|
||||||
""" github jedi-vim issue #44 """
|
""" github jedi-vim issue #44 """
|
||||||
|
|||||||
Reference in New Issue
Block a user