From f70e425c4a0355ce6114f2f27944ecc2f59f8b72 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Mar 2013 13:08:55 +0100 Subject: [PATCH 1/8] Lowercase the str returned by BaseDefinition.type --- jedi/api_classes.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jedi/api_classes.py b/jedi/api_classes.py index 2be10641..88300d9e 100644 --- a/jedi/api_classes.py +++ b/jedi/api_classes.py @@ -120,20 +120,20 @@ class BaseDefinition(object): Finally, here is what you can get from :attr:`type`: >>> defs[0].type - 'Module' + 'module' >>> defs[1].type - 'Class' + 'class' >>> defs[2].type - 'Instance' + 'instance' >>> defs[3].type - 'Function' + 'function' """ # generate the type stripped = self.definition if isinstance(self.definition, er.InstanceElement): stripped = self.definition.var - return type(stripped).__name__ + return type(stripped).__name__.lower() @property def path(self): From 3caebcb5aa3ff6986262df69b1564d348d29aa80 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Mar 2013 13:39:48 +0100 Subject: [PATCH 2/8] Add test_basedefinition_type --- test/test_api_classes.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/test_api_classes.py diff --git a/test/test_api_classes.py b/test/test_api_classes.py new file mode 100644 index 00000000..3856d6be --- /dev/null +++ b/test/test_api_classes.py @@ -0,0 +1,23 @@ +import pytest + +from jedi import api + + +def make_definitions(): + return api.defined_names(""" + import sys + + class C: + pass + + x = C() + + def f(): + pass + """) + + +@pytest.mark.parametrize('definition', make_definitions()) +def test_basedefinition_type(definition): + assert definition.type in ('module', 'class', 'instance', 'function', + 'statement', 'import') From f791e96d9da075ca7b69fd7218c0200a0e0f1827 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Mar 2013 13:47:31 +0100 Subject: [PATCH 3/8] Fix failing test_basedefinition_type --- jedi/api_classes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jedi/api_classes.py b/jedi/api_classes.py index 88300d9e..2baff8c3 100644 --- a/jedi/api_classes.py +++ b/jedi/api_classes.py @@ -133,6 +133,8 @@ class BaseDefinition(object): stripped = self.definition if isinstance(self.definition, er.InstanceElement): stripped = self.definition.var + if isinstance(stripped, pr.Name): + stripped = stripped.parent return type(stripped).__name__.lower() @property From 956ad502766eddbaf3c81672a30e58c814ba8437 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Mar 2013 14:10:24 +0100 Subject: [PATCH 4/8] Make more examples in make_definitions --- test/test_api_classes.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/test_api_classes.py b/test/test_api_classes.py index 3856d6be..8e4f76cf 100644 --- a/test/test_api_classes.py +++ b/test/test_api_classes.py @@ -1,10 +1,17 @@ +import textwrap + import pytest from jedi import api def make_definitions(): - return api.defined_names(""" + """ + Return a list of definitions for parametrized tests. + + :rtype: [jedi.api_classes.BaseDefinition] + """ + source = textwrap.dedent(""" import sys class C: @@ -16,6 +23,20 @@ def make_definitions(): pass """) + definitions = [] + definitions += api.defined_names(source) + + source += textwrap.dedent(""" + variable = sys or C or x or f""") + 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() + + return definitions + @pytest.mark.parametrize('definition', make_definitions()) def test_basedefinition_type(definition): From a0c796087aff5055e0e4cef7e5b3ea46ce1550e2 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Mar 2013 14:24:42 +0100 Subject: [PATCH 5/8] Generate "param" definition in make_definitions --- test/test_api_classes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/test_api_classes.py b/test/test_api_classes.py index 8e4f76cf..69bbf2b3 100644 --- a/test/test_api_classes.py +++ b/test/test_api_classes.py @@ -35,10 +35,14 @@ def make_definitions(): 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') + 'statement', 'import', 'param') From c8c1113c55659c72603247452ec6be6767a5b319 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Mar 2013 14:26:58 +0100 Subject: [PATCH 6/8] Test generator and lambda --- test/test_api_classes.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/test_api_classes.py b/test/test_api_classes.py index 69bbf2b3..bcb7a722 100644 --- a/test/test_api_classes.py +++ b/test/test_api_classes.py @@ -21,13 +21,18 @@ def make_definitions(): 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""") + 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() From be33f0ad98fdf18153653917328ee006b5b4d9e8 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Mar 2013 14:39:51 +0100 Subject: [PATCH 7/8] Fix previously failing test_follow_definition --- test/test_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_regression.py b/test/test_regression.py index 2e0da3cf..a6e210d0 100755 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -319,7 +319,7 @@ class TestRegression(TestBase): # attributes objs = itertools.chain.from_iterable(r.follow_definition() for r in c) 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): """ github jedi-vim issue #44 """ From df08122639f85d3e0e3067c61753172b37f24bd4 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Mar 2013 14:51:59 +0100 Subject: [PATCH 8/8] Fix a failure when run with Python 3 --- jedi/api.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/jedi/api.py b/jedi/api.py index 86b9a369..87e62c56 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -272,7 +272,7 @@ class Script(object): d = set([api_classes.Definition(s) for s in scopes 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 def goto(self): @@ -285,7 +285,7 @@ class Script(object): :rtype: list of :class:`api_classes.Definition` """ 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): """ @@ -371,7 +371,7 @@ class Script(object): else: 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): """ @@ -492,6 +492,12 @@ class Script(object): match = re.match(r'^(.*?)(\.|)(\w?[\w\d]*)$', path, flags=re.S) 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'): """