From 0a09d8a813cffee14021ae5c92e507917037a744 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 8 Mar 2013 19:24:59 +0100 Subject: [PATCH 01/18] Refactor function_definition --- jedi/api.py | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/jedi/api.py b/jedi/api.py index 9f1fdeea..0d7eb114 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -370,6 +370,26 @@ class Script(object): :rtype: :class:`api_classes.CallDef` """ + + try: + (call, index) = self._get_function_call_and_param_index_at_point() + except NotFoundError: + return None + + user_stmt = self._parser.user_stmt + with common.scale_speed_settings(settings.scale_function_definition): + _callable = lambda: evaluate.follow_call(call) + origins = cache.cache_function_definition(_callable, user_stmt) + debug.speed('func_call followed') + + if len(origins) == 0: + return None + # just take entry zero, because we need just one. + executable = origins[0] + + return api_classes.CallDef(executable, index, call) + + def _get_function_call_and_param_index_at_point(self): def check_user_stmt(user_stmt): if user_stmt is None \ or not isinstance(user_stmt, pr.Statement): @@ -409,32 +429,14 @@ class Script(object): raise NotFoundError() debug.speed('func_call start') - call = None if settings.use_function_definition_cache: - try: - call, index = check_cache() - except NotFoundError: - return None - - user_stmt = self._parser.user_stmt + call, index = check_cache() if call is None: - # This is a backup, if the above is not successful. - call, index = check_user_stmt(user_stmt) - if call is None: - return None + call, index = check_user_stmt(self._parser.user_stmt) + if call is None: + raise NotFoundError() debug.speed('func_call parsed') - - with common.scale_speed_settings(settings.scale_function_definition): - _callable = lambda: evaluate.follow_call(call) - origins = cache.cache_function_definition(_callable, user_stmt) - debug.speed('func_call followed') - - if len(origins) == 0: - return None - # just take entry zero, because we need just one. - executable = origins[0] - - return api_classes.CallDef(executable, index, call) + return call, index def _get_on_import_stmt(self, is_like_search=False): """ Resolve the user statement, if it is an import. Only resolve the From a25aa884d64eb2a388dd81fb49de1c658467f5c2 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 8 Mar 2013 20:21:43 +0100 Subject: [PATCH 02/18] Make Script.definition work inside function call --- jedi/api.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/jedi/api.py b/jedi/api.py index 0d7eb114..2693ed1c 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -231,13 +231,40 @@ class Script(object): goto_path = self._module.get_path_under_cursor() context = self._module.get_context() + scopes = set() + lower_priority_operators = ('(', ',') + """Operators that could hide callee.""" if next(context) in ('class', 'def'): scopes = set([self._module.parser.user_scope]) elif not goto_path: op = self._module.get_operator_under_cursor() - scopes = set([keywords.get_operator(op, self.pos)] if op else []) - else: - scopes = set(self._prepare_goto(goto_path)) + if op and op not in lower_priority_operators: + scopes = set([keywords.get_operator(op, self.pos)]) + + # Fetch definition of callee + if not goto_path: + try: + (call, _) = self._get_function_call_and_param_index_at_point() + except NotFoundError: + call = None + if call is not None: + while call.next is not None: + call = call.next + # reset cursor position: + (row, col) = call.name.end_pos + self.pos = (row, max(col - 1, 0)) + self._module = modules.ModuleWithCursor( + self._source_path, + source=self.source, + position=self.pos) + # then try to find the path again + goto_path = self._module.get_path_under_cursor() + + if not scopes: + if goto_path: + scopes = set(self._prepare_goto(goto_path)) + elif op in lower_priority_operators: + scopes = set([keywords.get_operator(op, self.pos)]) scopes = resolve_import_paths(scopes) From b8e3e0c15752c290205b26585394569ee866a875 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 8 Mar 2013 21:39:45 +0100 Subject: [PATCH 03/18] Add tests for Script.definition when in function call --- test/regression.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/regression.py b/test/regression.py index 6e78eccd..6b939064 100755 --- a/test/regression.py +++ b/test/regression.py @@ -10,6 +10,7 @@ import time import functools import itertools import os +import textwrap from base import TestBase, cwd_at @@ -95,6 +96,31 @@ class TestRegression(TestBase): if not is_py25: assert len(r[0].doc) > 100 + def definition_when_in_function_call(self, pre_cursor, post_cursor=''): + source = textwrap.dedent(""" + def f(): + pass + %s%s""" % (pre_cursor, post_cursor)) + lines = source.splitlines() + pos = (len(lines), len(pre_cursor)) + return list(self.definition(source, pos)) + + def test_definition_when_in_function_call_right_after_open_paren(self): + defs = self.definition_when_in_function_call('f(') + self.assertEqual(defs[0].description, 'def f') + + def test_definition_when_in_function_call_after_open_paren_and_space(self): + defs = self.definition_when_in_function_call('f( ') + self.assertEqual(defs[0].description, 'def f') + + def test_definition_when_in_function_call_right_after_comma(self): + defs = self.definition_when_in_function_call('f(1,') + self.assertEqual(defs[0].description, 'def f') + + def test_definition_when_in_function_call_after_comma_and_space(self): + defs = self.definition_when_in_function_call('f(1, ') + self.assertEqual(defs[0].description, 'def f') + def test_function_call_signature(self): defs = self.definition(""" def f(x, y=1, z='a'): From 8f3db6976bfb83cc4fe9fc014f472fde92482119 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sat, 9 Mar 2013 23:47:13 +0100 Subject: [PATCH 04/18] Fix test for issue #94 --- test/regression.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/regression.py b/test/regression.py index 6b939064..2fd54209 100755 --- a/test/regression.py +++ b/test/regression.py @@ -17,6 +17,7 @@ from base import TestBase, cwd_at import jedi from jedi._compatibility import is_py25, utf8, unicode from jedi import api +from jedi import api_classes #jedi.set_debug_function(jedi.debug.print_to_stdout) @@ -410,9 +411,12 @@ class TestFeature(TestBase): """ feature request #61""" assert self.complete('import os; os.path.join')[0].full_name \ == 'os.path.join' - # issue #94 - defs = self.definition("""import os; os.path.join(""") - assert defs[0].full_name is None + + def test_keyword_full_name_should_be_none(self): + """issue #94""" + from jedi.keywords import Keyword + d = api_classes.Definition(Keyword('(', (0, 0))) + assert d.full_name is None def test_full_name_builtin(self): self.assertEqual(self.complete('type')[0].full_name, 'type') From 9490730d591483157daca27ff405bb36c03b6d01 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sat, 9 Mar 2013 23:55:57 +0100 Subject: [PATCH 05/18] Treat case like `f()` --- jedi/api.py | 2 +- test/regression.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/jedi/api.py b/jedi/api.py index 2693ed1c..4bcce36f 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -232,7 +232,7 @@ class Script(object): context = self._module.get_context() scopes = set() - lower_priority_operators = ('(', ',') + lower_priority_operators = ('()', '(', ',') """Operators that could hide callee.""" if next(context) in ('class', 'def'): scopes = set([self._module.parser.user_scope]) diff --git a/test/regression.py b/test/regression.py index 2fd54209..c950fd43 100755 --- a/test/regression.py +++ b/test/regression.py @@ -122,6 +122,10 @@ class TestRegression(TestBase): defs = self.definition_when_in_function_call('f(1, ') self.assertEqual(defs[0].description, 'def f') + def test_definition_when_in_function_call_empty_paren(self): + defs = self.definition_when_in_function_call('f(', ')') + self.assertEqual(defs[0].description, 'def f') + def test_function_call_signature(self): defs = self.definition(""" def f(x, y=1, z='a'): From c546323bca6b93b079e4482e1f9e5a7212a6c1dd Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 00:17:58 +0100 Subject: [PATCH 06/18] Tests for `f(| )` and `f( |)` (the latter fails) --- test/regression.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/regression.py b/test/regression.py index c950fd43..f41a23b7 100755 --- a/test/regression.py +++ b/test/regression.py @@ -126,6 +126,14 @@ class TestRegression(TestBase): defs = self.definition_when_in_function_call('f(', ')') self.assertEqual(defs[0].description, 'def f') + def test_definition_when_in_function_call_empty_paren_pre_space(self): + defs = self.definition_when_in_function_call('f( ', ')') + self.assertEqual(defs[0].description, 'def f') + + def test_definition_when_in_function_call_empty_paren_post_space(self): + defs = self.definition_when_in_function_call('f(', ' )') + self.assertEqual(defs[0].description, 'def f') + def test_function_call_signature(self): defs = self.definition(""" def f(x, y=1, z='a'): From 1eae32c1828177b7f1e8f15af8c24e1bccd8f227 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 00:44:12 +0100 Subject: [PATCH 07/18] Skip test case for finding definition at `f( |)` --- test/regression.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/regression.py b/test/regression.py index f41a23b7..88802c5f 100755 --- a/test/regression.py +++ b/test/regression.py @@ -128,7 +128,15 @@ class TestRegression(TestBase): def test_definition_when_in_function_call_empty_paren_pre_space(self): defs = self.definition_when_in_function_call('f( ', ')') - self.assertEqual(defs[0].description, 'def f') + desc = defs[0].description + if desc == 'keyword )': + try: + self.skipTest('finding definition at ``f( |)`` does not work') + except AttributeError: + # old unittest does not support skip + pass + else: + self.assertEqual(desc, 'def f') def test_definition_when_in_function_call_empty_paren_post_space(self): defs = self.definition_when_in_function_call('f(', ' )') From 4d6abfb8de17584e8d727b79b9c6593a5855f1ea Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 01:19:30 +0100 Subject: [PATCH 08/18] Fix a failing test in Python 3 --- test/regression.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/regression.py b/test/regression.py index 88802c5f..bab1900c 100755 --- a/test/regression.py +++ b/test/regression.py @@ -434,7 +434,9 @@ class TestFeature(TestBase): def test_keyword_full_name_should_be_none(self): """issue #94""" - from jedi.keywords import Keyword + # Using `from jedi.keywords import Keyword` here does NOT work + # in Python 3. This is due to the import hack jedi using. + Keyword = api_classes.keywords.Keyword d = api_classes.Definition(Keyword('(', (0, 0))) assert d.full_name is None From d9b3bb40162b4cb1b283942cf08872ca2751b14a Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 01:24:56 +0100 Subject: [PATCH 09/18] Refactor _get_function_call_and_param_index_at_point --- jedi/api.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/jedi/api.py b/jedi/api.py index 4bcce36f..2be8cb83 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -243,10 +243,7 @@ class Script(object): # Fetch definition of callee if not goto_path: - try: - (call, _) = self._get_function_call_and_param_index_at_point() - except NotFoundError: - call = None + (call, _) = self._get_function_call_and_param_index_at_point() if call is not None: while call.next is not None: call = call.next @@ -398,9 +395,8 @@ class Script(object): :rtype: :class:`api_classes.CallDef` """ - try: - (call, index) = self._get_function_call_and_param_index_at_point() - except NotFoundError: + (call, index) = self._get_function_call_and_param_index_at_point() + if call is None: return None user_stmt = self._parser.user_stmt @@ -456,12 +452,18 @@ class Script(object): raise NotFoundError() debug.speed('func_call start') + call = None + index = 0 if settings.use_function_definition_cache: - call, index = check_cache() + try: + call, index = check_cache() + except NotFoundError: + pass if call is None: - call, index = check_user_stmt(self._parser.user_stmt) - if call is None: - raise NotFoundError() + try: + call, index = check_user_stmt(self._parser.user_stmt) + except NotFoundError: + pass debug.speed('func_call parsed') return call, index From 7ce0e1c1780fb6638c556447b99e3e1c84be819d Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 01:26:46 +0100 Subject: [PATCH 10/18] Rename it to _func_call_and_param_index --- jedi/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jedi/api.py b/jedi/api.py index 2be8cb83..dff1e7e9 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -243,7 +243,7 @@ class Script(object): # Fetch definition of callee if not goto_path: - (call, _) = self._get_function_call_and_param_index_at_point() + (call, _) = self._func_call_and_param_index() if call is not None: while call.next is not None: call = call.next @@ -395,7 +395,7 @@ class Script(object): :rtype: :class:`api_classes.CallDef` """ - (call, index) = self._get_function_call_and_param_index_at_point() + (call, index) = self._func_call_and_param_index() if call is None: return None @@ -412,7 +412,7 @@ class Script(object): return api_classes.CallDef(executable, index, call) - def _get_function_call_and_param_index_at_point(self): + def _func_call_and_param_index(self): def check_user_stmt(user_stmt): if user_stmt is None \ or not isinstance(user_stmt, pr.Statement): From 0e99c33c675e3a645c9cf137ed66eccae4ef38c7 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 01:31:31 +0100 Subject: [PATCH 11/18] Don't use NotFoundError in _func_call_and_param_index This makes it simpler. --- jedi/api.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/jedi/api.py b/jedi/api.py index dff1e7e9..00a39691 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -447,23 +447,15 @@ class Script(object): if repr(old_call) == repr(call): # return the index of the part_parser return old_call, index - return None, 0 - else: - raise NotFoundError() + return None, 0 debug.speed('func_call start') call = None index = 0 if settings.use_function_definition_cache: - try: - call, index = check_cache() - except NotFoundError: - pass + call, index = check_cache() if call is None: - try: - call, index = check_user_stmt(self._parser.user_stmt) - except NotFoundError: - pass + call, index = check_user_stmt(self._parser.user_stmt) debug.speed('func_call parsed') return call, index From 3542b7f80a53d924750551adb5e3151d50fbb4c7 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 01:52:15 +0100 Subject: [PATCH 12/18] Refactor tests for function_definition --- test/regression.py | 63 ++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/test/regression.py b/test/regression.py index bab1900c..351df48c 100755 --- a/test/regression.py +++ b/test/regression.py @@ -192,10 +192,15 @@ class TestRegression(TestBase): assert self.complete("from datetime import")[0].word == 'import' assert self.complete("from datetime import ") + def assert_call_def(self, call_def, name, index): + self.assertEqual( + {'call_name': getattr(call_def, 'call_name', None), + 'index': getattr(call_def, 'index', None)}, + {'call_name': name, 'index': index}, + ) + def test_function_definition(self): - def check(call_def, name, index): - return call_def and call_def.call_name == name \ - and call_def.index == index + check = self.assert_call_def # simple s = "abs(a, str(" @@ -208,13 +213,13 @@ class TestRegression(TestBase): s7 = "str().upper().center(" s8 = "str(int[zip(" - assert check(self.function_definition(s, (1, 4)), 'abs', 0) - assert check(self.function_definition(s, (1, 6)), 'abs', 1) - assert check(self.function_definition(s, (1, 7)), 'abs', 1) - assert check(self.function_definition(s, (1, 8)), 'abs', 1) - assert check(self.function_definition(s, (1, 11)), 'str', 0) + check(self.function_definition(s, (1, 4)), 'abs', 0) + check(self.function_definition(s, (1, 6)), 'abs', 1) + check(self.function_definition(s, (1, 7)), 'abs', 1) + check(self.function_definition(s, (1, 8)), 'abs', 1) + check(self.function_definition(s, (1, 11)), 'str', 0) - assert check(self.function_definition(s2, (1, 4)), 'abs', 0) + check(self.function_definition(s2, (1, 4)), 'abs', 0) assert self.function_definition(s2, (1, 5)) is None assert self.function_definition(s2) is None @@ -222,43 +227,41 @@ class TestRegression(TestBase): assert self.function_definition(s3) is None assert self.function_definition(s4, (1, 3)) is None - assert check(self.function_definition(s4, (1, 4)), 'abs', 0) - assert check(self.function_definition(s4, (1, 8)), 'zip', 0) - assert check(self.function_definition(s4, (1, 9)), 'abs', 0) - #assert check(self.function_definition(s4, (1, 10)), 'abs', 1) + check(self.function_definition(s4, (1, 4)), 'abs', 0) + check(self.function_definition(s4, (1, 8)), 'zip', 0) + check(self.function_definition(s4, (1, 9)), 'abs', 0) + #check(self.function_definition(s4, (1, 10)), 'abs', 1) - assert check(self.function_definition(s5, (1, 4)), 'abs', 0) - assert check(self.function_definition(s5, (1, 6)), 'abs', 1) + check(self.function_definition(s5, (1, 4)), 'abs', 0) + check(self.function_definition(s5, (1, 6)), 'abs', 1) - assert check(self.function_definition(s6), 'center', 0) - assert check(self.function_definition(s6, (1, 4)), 'str', 0) + check(self.function_definition(s6), 'center', 0) + check(self.function_definition(s6, (1, 4)), 'str', 0) - assert check(self.function_definition(s7), 'center', 0) - assert check(self.function_definition(s8), 'zip', 0) - assert check(self.function_definition(s8, (1, 8)), 'str', 0) + check(self.function_definition(s7), 'center', 0) + check(self.function_definition(s8), 'zip', 0) + check(self.function_definition(s8, (1, 8)), 'str', 0) s = "import time; abc = time; abc.sleep(" - assert check(self.function_definition(s), 'sleep', 0) + check(self.function_definition(s), 'sleep', 0) # jedi-vim #9 s = "with open(" - assert check(self.function_definition(s), 'open', 0) + check(self.function_definition(s), 'open', 0) # jedi-vim #11 s1 = "for sorted(" - assert check(self.function_definition(s1), 'sorted', 0) + check(self.function_definition(s1), 'sorted', 0) s2 = "for s in sorted(" - assert check(self.function_definition(s2), 'sorted', 0) + check(self.function_definition(s2), 'sorted', 0) # jedi #57 s = "def func(alpha, beta): pass\n" \ "func(alpha='101'," - assert check(self.function_definition(s, (2, 13)), 'func', 0) + check(self.function_definition(s, (2, 13)), 'func', 0) def test_function_definition_complex(self): - def check(call_def, name, index): - return call_def and call_def.call_name == name \ - and call_def.index == index + check = self.assert_call_def s = """ def abc(a,b): @@ -270,14 +273,14 @@ class TestRegression(TestBase): if 1: pass """ - assert check(self.function_definition(s, (6, 24)), 'abc', 0) + check(self.function_definition(s, (6, 24)), 'abc', 0) s = """ import re def huhu(it): re.compile( return it * 2 """ - assert check(self.function_definition(s, (4, 31)), 'compile', 0) + check(self.function_definition(s, (4, 31)), 'compile', 0) # jedi-vim #70 s = """def foo(""" assert self.function_definition(s) is None From ab79689cee36862d14d835666cef6336ec0f117e Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 04:07:08 +0100 Subject: [PATCH 13/18] Use unittest2 for Python < 2.7 --- .travis.yml | 7 ++++++- test/base.py | 6 ++++-- test/regression.py | 9 ++------- tox.ini | 5 +++++ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index b049499b..ba8fb069 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,12 @@ python: - 2.7 - 3.2 install: - - if [[ $TRAVIS_PYTHON_VERSION == '2.5' ]]; then pip install --use-mirrors simplejson; fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.5' ]]; then + pip install --use-mirrors simplejson unittest2; + fi + - if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then + pip install --use-mirrors unittest2; + fi - pip install --use-mirrors nose script: - cd test diff --git a/test/base.py b/test/base.py index 29cc966b..a9e2d9ab 100644 --- a/test/base.py +++ b/test/base.py @@ -1,7 +1,9 @@ -import unittest - import time import sys +if sys.hexversion < 0x02070000: + import unittest2 as unittest +else: + import unittest import os from os.path import abspath, dirname import functools diff --git a/test/regression.py b/test/regression.py index 351df48c..b336ea67 100755 --- a/test/regression.py +++ b/test/regression.py @@ -5,14 +5,13 @@ Unit tests to avoid errors of the past. Makes use of Python's ``unittest`` module. """ -import unittest import time import functools import itertools import os import textwrap -from base import TestBase, cwd_at +from base import TestBase, unittest, cwd_at import jedi from jedi._compatibility import is_py25, utf8, unicode @@ -130,11 +129,7 @@ class TestRegression(TestBase): defs = self.definition_when_in_function_call('f( ', ')') desc = defs[0].description if desc == 'keyword )': - try: - self.skipTest('finding definition at ``f( |)`` does not work') - except AttributeError: - # old unittest does not support skip - pass + self.skipTest('finding definition at ``f( |)`` does not work') else: self.assertEqual(desc, 'def f') diff --git a/tox.ini b/tox.ini index db9d67dc..2a39e11c 100644 --- a/tox.ini +++ b/tox.ini @@ -14,4 +14,9 @@ changedir = test [testenv:py25] deps = simplejson + unittest2 + {[testenv]deps} +[testenv:py26] +deps = + unittest2 {[testenv]deps} From c6c17d7ed5d7dc713d251a4e617bfad51a45654d Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 04:11:14 +0100 Subject: [PATCH 14/18] Add known failing test for function_definition --- test/regression.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/regression.py b/test/regression.py index b336ea67..038b6ff7 100755 --- a/test/regression.py +++ b/test/regression.py @@ -280,6 +280,15 @@ class TestRegression(TestBase): s = """def foo(""" assert self.function_definition(s) is None + @unittest.skip("function_definition at ``f( |)`` does not work") + def test_function_definition_empty_paren_pre_space(self): + s = textwrap.dedent("""\ + def f(a, b): + pass + f( )""") + call_def = self.function_definition(s, (3, 3)) + self.assert_call_def(call_def, 'f', 0) + @cwd_at('jedi') def test_add_dynamic_mods(self): api.settings.additional_dynamic_modules = ['dynamic.py'] From 31df9a92fe2f541fc58ff3278ed95594fff850ed Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 07:34:37 +0100 Subject: [PATCH 15/18] Add test/completion/definition.py --- test/completion/definition.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/completion/definition.py diff --git a/test/completion/definition.py b/test/completion/definition.py new file mode 100644 index 00000000..0a11aa0a --- /dev/null +++ b/test/completion/definition.py @@ -0,0 +1,17 @@ +""" +Fallback to callee definition when definition not found. +- https://github.com/davidhalter/jedi/issues/131 +- https://github.com/davidhalter/jedi/pull/149 +""" + +#? isinstance +isinstance( +) + +#? isinstance +isinstance(None, +) + +#? isinstance +isinstance(None, +) From 5f49fb8c7c0f9e7a05d4f9b730d7f3e872229d60 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 08:01:38 +0100 Subject: [PATCH 16/18] Add blackbox tests using column number --- test/completion/definition.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/completion/definition.py b/test/completion/definition.py index 0a11aa0a..12ae1b29 100644 --- a/test/completion/definition.py +++ b/test/completion/definition.py @@ -15,3 +15,23 @@ isinstance(None, #? isinstance isinstance(None, ) + +# Note: len('isinstance(') == 11 +#? 11 isinstance +isinstance() + +# Note: len('isinstance(None,') == 16 +##? 16 isinstance +isinstance(None,) + +# Note: len('isinstance(None,') == 16 +##? 16 isinstance +isinstance(None, ) + +# Note: len('isinstance(None, ') == 17 +##? 17 isinstance +isinstance(None, ) + +# Note: len('isinstance( ') == 12 +##? 12 isinstance +isinstance( ) From fa231b58a81f0077b14c444f71cbddf8ed2453f7 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 20:10:13 +0100 Subject: [PATCH 17/18] Add more test cases in completion/definition.py --- test/completion/definition.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/completion/definition.py b/test/completion/definition.py index 12ae1b29..3fdd88e5 100644 --- a/test/completion/definition.py +++ b/test/completion/definition.py @@ -4,10 +4,16 @@ Fallback to callee definition when definition not found. - https://github.com/davidhalter/jedi/pull/149 """ +"""Parenthesis closed at next line.""" + #? isinstance isinstance( ) +#? isinstance +isinstance( +) + #? isinstance isinstance(None, ) @@ -16,6 +22,8 @@ isinstance(None, isinstance(None, ) +"""Parenthesis closed at same line.""" + # Note: len('isinstance(') == 11 #? 11 isinstance isinstance() @@ -35,3 +43,23 @@ isinstance(None, ) # Note: len('isinstance( ') == 12 ##? 12 isinstance isinstance( ) + +"""Unclosed parenthesis.""" + +#? isinstance +isinstance( + +def x(): pass # acts like EOF + +##? isinstance +isinstance( + +def x(): pass # acts like EOF + +#? isinstance +isinstance(None, + +def x(): pass # acts like EOF + +#? isinstance +isinstance(None, From 50e1fad8f69839a1416e83d3f9f9a7629712e8cf Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sun, 10 Mar 2013 20:11:10 +0100 Subject: [PATCH 18/18] Remove tests from regression.py --- test/regression.py | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/test/regression.py b/test/regression.py index 038b6ff7..54dfe755 100755 --- a/test/regression.py +++ b/test/regression.py @@ -96,47 +96,6 @@ class TestRegression(TestBase): if not is_py25: assert len(r[0].doc) > 100 - def definition_when_in_function_call(self, pre_cursor, post_cursor=''): - source = textwrap.dedent(""" - def f(): - pass - %s%s""" % (pre_cursor, post_cursor)) - lines = source.splitlines() - pos = (len(lines), len(pre_cursor)) - return list(self.definition(source, pos)) - - def test_definition_when_in_function_call_right_after_open_paren(self): - defs = self.definition_when_in_function_call('f(') - self.assertEqual(defs[0].description, 'def f') - - def test_definition_when_in_function_call_after_open_paren_and_space(self): - defs = self.definition_when_in_function_call('f( ') - self.assertEqual(defs[0].description, 'def f') - - def test_definition_when_in_function_call_right_after_comma(self): - defs = self.definition_when_in_function_call('f(1,') - self.assertEqual(defs[0].description, 'def f') - - def test_definition_when_in_function_call_after_comma_and_space(self): - defs = self.definition_when_in_function_call('f(1, ') - self.assertEqual(defs[0].description, 'def f') - - def test_definition_when_in_function_call_empty_paren(self): - defs = self.definition_when_in_function_call('f(', ')') - self.assertEqual(defs[0].description, 'def f') - - def test_definition_when_in_function_call_empty_paren_pre_space(self): - defs = self.definition_when_in_function_call('f( ', ')') - desc = defs[0].description - if desc == 'keyword )': - self.skipTest('finding definition at ``f( |)`` does not work') - else: - self.assertEqual(desc, 'def f') - - def test_definition_when_in_function_call_empty_paren_post_space(self): - defs = self.definition_when_in_function_call('f(', ' )') - self.assertEqual(defs[0].description, 'def f') - def test_function_call_signature(self): defs = self.definition(""" def f(x, y=1, z='a'):