diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3fe8cacd..ef1129be 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,10 +3,15 @@ Changelog --------- +0.16.0 (2020--) ++++++++++++++++++++ + +- ``BaseDefinition.goto_assignments`` renamed to ``BaseDefinition.goto`` + 0.15.2 (2019-12-20) +++++++++++++++++++ -- Call signatures are now detected a lot better +- Signatures are now detected a lot better - Add fuzzy completions with ``Script(...).completions(fuzzy=True)`` - Files bigger than one MB (about 20kLOC) get cropped to avoid getting stuck completely. @@ -33,7 +38,7 @@ New APIs: - ``Definition.get_signatures() -> List[Signature]``. Signatures are similar to ``CallSignature``. ``Definition.params`` is therefore deprecated. -- ``Signature.to_string()`` to format call signatures. +- ``Signature.to_string()`` to format signatures. - ``Signature.params -> List[ParamDefinition]``, ParamDefinition has the following additional attributes ``infer_default()``, ``infer_annotation()``, ``to_string()``, and ``kind``. diff --git a/README.rst b/README.rst index 7c90f8b7..ef0d804e 100644 --- a/README.rst +++ b/README.rst @@ -32,7 +32,7 @@ Jedi has a focus on autocompletion and goto functionality. Jedi is fast and is very well tested. It understands Python and stubs on a deep level. Jedi has support for different goto functions. It's possible to search for -usages and list names in a Python file to get information about them. +references and list names in a Python file to get information about them. Jedi uses a very simple API to connect with IDE's. There's a reference implementation as a `VIM-Plugin `_, @@ -128,9 +128,9 @@ Autocompletion / Goto / Pydoc Please check the API for a good explanation. There are the following commands: -- ``jedi.Script.goto_assignments`` -- ``jedi.Script.completions`` -- ``jedi.Script.usages`` +- ``jedi.Script.goto`` +- ``jedi.Script.complete`` +- ``jedi.Script.find_references`` The returned objects are very powerful and really all you might need. @@ -149,8 +149,9 @@ This means that in Python you can enable tab completion in a `REPL Static Analysis ------------------------ -To do all forms of static analysis, please try to use ``jedi.names``. It will -return a list of names that you can use to infer types and so on. +To do all forms of static analysis, please try to use +``jedi.Script(...).names``. It will return a list of names that you can use to +infer types and so on. Refactoring diff --git a/conftest.py b/conftest.py index 35aa6073..1eec4221 100644 --- a/conftest.py +++ b/conftest.py @@ -106,8 +106,8 @@ def Script(environment): @pytest.fixture(scope='session') -def names(environment): - return partial(jedi.names, environment=environment) +def names(Script): + return lambda code, **kwargs: Script(code).names(**kwargs) @pytest.fixture(scope='session') @@ -118,7 +118,7 @@ def has_typing(environment): return True script = jedi.Script('import typing', environment=environment) - return bool(script.goto_definitions()) + return bool(script.infer()) @pytest.fixture(scope='session') diff --git a/docs/docs/api.rst b/docs/docs/api.rst index 58c88ef1..d0073587 100644 --- a/docs/docs/api.rst +++ b/docs/docs/api.rst @@ -29,9 +29,8 @@ API Documentation The API consists of a few different parts: -- The main starting points for completions/goto: :class:`.Script` and :class:`.Interpreter` -- Helpful functions: :func:`.names`, :func:`.preload_module` and - :func:`.set_debug_function` +- The main starting points for complete/goto: :class:`.Script` and :class:`.Interpreter` +- Helpful functions: :func:`.preload_module` and :func:`.set_debug_function` - :ref:`API Result Classes ` - :ref:`Python Versions/Virtualenv Support ` with functions like :func:`.find_system_environments` and :func:`.find_virtualenvs` @@ -47,7 +46,6 @@ Static Analysis Interface :members: .. autoclass:: jedi.Interpreter :members: -.. autofunction:: jedi.names .. autofunction:: jedi.preload_module .. autofunction:: jedi.set_debug_function @@ -76,10 +74,10 @@ Completions: >>> import jedi >>> source = '''import json; json.l''' - >>> script = jedi.Script(source, 1, 19, '') + >>> script = jedi.Script(source, path='') >>> script - >>> completions = script.completions() + >>> completions = script.complete(1, 19) >>> completions [, ] >>> completions[1] @@ -102,15 +100,15 @@ Definitions / Goto: ... inception = my_list[2] ... ... inception()''' - >>> script = jedi.Script(source, 8, 1, '') + >>> script = jedi.Script(source, path='') >>> - >>> script.goto_assignments() + >>> script.goto(8, 1) [] >>> - >>> script.goto_definitions() + >>> script.infer(8, 1) [] -Related names: +References: .. sourcecode:: python @@ -120,13 +118,12 @@ Related names: ... x = 4 ... else: ... del x''' - >>> script = jedi.Script(source, 5, 8, '') - >>> rns = script.related_names() + >>> script = jedi.Script(source, '') + >>> rns = script.find_references(5, 8) >>> rns - [, ] - >>> rns[0].start_pos - (3, 4) - >>> rns[0].is_keyword - False - >>> rns[0].text - 'x' + [, + ] + >>> rns[1].line + 5 + >>> rns[0].column + 8 diff --git a/docs/docs/features.rst b/docs/docs/features.rst index 54e1435a..693e3cdd 100644 --- a/docs/docs/features.rst +++ b/docs/docs/features.rst @@ -6,7 +6,7 @@ Features and Caveats Jedi obviously supports autocompletion. It's also possible to get it working in (:ref:`your REPL (IPython, etc.) `). -Static analysis is also possible by using the command ``jedi.names``. +Static analysis is also possible by using ``jedi.Script(...).names``. Jedi would in theory support refactoring, but we have never publicized it, because it's not production ready. If you're interested in helping out here, diff --git a/jedi/__init__.py b/jedi/__init__.py index f8303477..efec776d 100644 --- a/jedi/__init__.py +++ b/jedi/__init__.py @@ -4,7 +4,7 @@ Jedi has a focus on autocompletion and goto functionality. Jedi is fast and is very well tested. It understands Python and stubs on a deep level. Jedi has support for different goto functions. It's possible to search for -usages and list names in a Python file to get information about them. +references and list names in a Python file to get information about them. Jedi uses a very simple API to connect with IDE's. There's a reference implementation as a `VIM-Plugin `_, @@ -18,10 +18,10 @@ Here's a simple example of the autocompletion feature: >>> source = ''' ... import json ... json.lo''' ->>> script = jedi.Script(source, 3, len('json.lo'), 'example.py') +>>> script = jedi.Script(source, path='example.py') >>> script ->>> completions = script.completions() +>>> completions = script.complete(3, len('json.lo')) >>> completions [, ] >>> print(completions[0].complete) @@ -33,7 +33,7 @@ As you see Jedi is pretty simple and allows you to concentrate on writing a good text editor, while still having very good IDE features for Python. """ -__version__ = '0.15.2' +__version__ = '0.16.0' from jedi.api import Script, Interpreter, set_debug_function, \ preload_module, names diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index ec841065..ea0ffe7b 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -25,12 +25,13 @@ from jedi.file_io import KnownContentFileIO from jedi.api import classes from jedi.api import interpreter from jedi.api import helpers +from jedi.api.helpers import validate_line_column from jedi.api.completion import Completion from jedi.api.environment import InterpreterEnvironment from jedi.api.project import get_default_project, Project from jedi.inference import InferenceState from jedi.inference import imports -from jedi.inference import usages +from jedi.inference.references import find_references from jedi.inference.arguments import try_iter_content from jedi.inference.helpers import get_module_names, infer_call_of_leaf from jedi.inference.sys_path import transform_path_to_dotted @@ -68,9 +69,9 @@ class Script(object): :param source: The source code of the current file, separated by newlines. :type source: str - :param line: The line to perform actions on (starting with 1). + :param line: Deprecated, please use it directly on e.g. `.complete` :type line: int - :param column: The column of the cursor (starting with 0). + :param column: Deprecated, please use it directly on e.g. `.complete` :type column: int :param path: The path of the file in the file system, or ``''`` if it hasn't been saved yet. @@ -126,22 +127,6 @@ class Script(object): debug.speed('parsed') self._code_lines = parso.split_lines(source, keepends=True) self._code = source - line = max(len(self._code_lines), 1) if line is None else line - if not (0 < line <= len(self._code_lines)): - raise ValueError('`line` parameter is not in a valid range.') - - line_string = self._code_lines[line - 1] - line_len = len(line_string) - if line_string.endswith('\r\n'): - line_len -= 1 - if line_string.endswith('\n'): - line_len -= 1 - - column = line_len if column is None else column - if not (0 <= column <= line_len): - raise ValueError('`column` parameter (%d) is not in a valid range ' - '(0-%d) for line %d (%r).' % ( - column, line_len, line, line_string)) self._pos = line, column cache.clear_time_caches() @@ -201,27 +186,38 @@ class Script(object): self._inference_state.environment, ) - def completions(self, fuzzy=False): + @validate_line_column + def complete(self, line=None, column=None, **kwargs): """ Return :class:`classes.Completion` objects. Those objects contain information about the completions, more than just names. - :return: Completion objects, sorted by name and __ comes last. + :param fuzzy: Default False. Will return fuzzy completions, which means + that e.g. ``ooa`` will match ``foobar``. + :return: Completion objects, sorted by name and ``__`` comes last. :rtype: list of :class:`classes.Completion` """ - with debug.increase_indent_cm('completions'): + return self._complete(line, column, **kwargs) + + def _complete(self, line, column, fuzzy=False): # Python 2... + with debug.increase_indent_cm('complete'): completion = Completion( self._inference_state, self._get_module_context(), self._code_lines, - self._pos, self.call_signatures + (line, column), self.find_signatures ) - return completion.completions(fuzzy) + return completion.complete(fuzzy) - def goto_definitions(self, **kwargs): + def completions(self, fuzzy=False): + # Deprecated, will be removed. + return self.complete(*self._pos, fuzzy=fuzzy) + + @validate_line_column + def infer(self, line=None, column=None, **kwargs): """ Return the definitions of a the path under the cursor. goto function! This follows complicated paths and returns the end, not the first - definition. The big difference between :meth:`goto_assignments` and - :meth:`goto_definitions` is that :meth:`goto_assignments` doesn't + definition. The big difference between :meth:`goto` and + :meth:`infer` is that :meth:`goto` doesn't follow imports and statements. Multiple objects may be returned, because Python itself is a dynamic language, which means depending on an option you can have two different versions of a function. @@ -231,19 +227,24 @@ class Script(object): inference call. :rtype: list of :class:`classes.Definition` """ - with debug.increase_indent_cm('goto_definitions'): - return self._goto_definitions(**kwargs) + with debug.increase_indent_cm('infer'): + return self._infer(line, column, **kwargs) - def _goto_definitions(self, only_stubs=False, prefer_stubs=False): - leaf = self._module_node.get_name_of_position(self._pos) + def goto_definitions(self, **kwargs): + # Deprecated, will be removed. + return self.infer(*self._pos, **kwargs) + + def _infer(self, line, column, only_stubs=False, prefer_stubs=False): + pos = line, column + leaf = self._module_node.get_name_of_position(pos) if leaf is None: - leaf = self._module_node.get_leaf_for_position(self._pos) + leaf = self._module_node.get_leaf_for_position(pos) if leaf is None or leaf.type == 'string': return [] context = self._get_module_context().create_context(leaf) - values = helpers.infer_goto_definition(self._inference_state, context, leaf) + values = helpers.infer(self._inference_state, context, leaf) values = convert_values( values, only_stubs=only_stubs, @@ -257,6 +258,14 @@ class Script(object): return helpers.sorted_definitions(set(defs)) def goto_assignments(self, follow_imports=False, follow_builtin_imports=False, **kwargs): + # Deprecated, will be removed. + return self.goto(*self._pos, + follow_imports=follow_imports, + follow_builtin_imports=follow_builtin_imports, + **kwargs) + + @validate_line_column + def goto(self, line=None, column=None, **kwargs): """ Return the first definition found, while optionally following imports. Multiple objects may be returned, because Python itself is a @@ -273,11 +282,11 @@ class Script(object): :param prefer_stubs: Prefer stubs to Python objects for this goto call. :rtype: list of :class:`classes.Definition` """ - with debug.increase_indent_cm('goto_assignments'): - return self._goto_assignments(follow_imports, follow_builtin_imports, **kwargs) + with debug.increase_indent_cm('goto'): + return self._goto(line, column, **kwargs) - def _goto_assignments(self, follow_imports, follow_builtin_imports, - only_stubs=False, prefer_stubs=False): + def _goto(self, line, column, follow_imports=False, follow_builtin_imports=False, + only_stubs=False, prefer_stubs=False): def filter_follow_imports(names): for name in names: if name.is_import(): @@ -296,11 +305,11 @@ class Script(object): else: yield name - tree_name = self._module_node.get_name_of_position(self._pos) + tree_name = self._module_node.get_name_of_position((line, column)) if tree_name is None: # Without a name we really just want to jump to the result e.g. # executed by `foo()`, if we the cursor is after `)`. - return self.goto_definitions(only_stubs=only_stubs, prefer_stubs=prefer_stubs) + return self.infer(line, column, only_stubs=only_stubs, prefer_stubs=prefer_stubs) name = self._get_module_context().create_name(tree_name) names = list(name.goto()) @@ -315,42 +324,43 @@ class Script(object): defs = [classes.Definition(self._inference_state, d) for d in set(names)] return helpers.sorted_definitions(defs) - def usages(self, additional_module_paths=(), **kwargs): + def usages(self, **kwargs): + # Deprecated, will be removed. + return self.find_references(*self._pos, **kwargs) + + @validate_line_column + def find_references(self, line=None, column=None, **kwargs): """ Return :class:`classes.Definition` objects, which contain all names that point to the definition of the name under the cursor. This - is very useful for refactoring (renaming), or to show all usages of a - variable. + is very useful for refactoring (renaming), or to show all references of + a variable. - .. todo:: Implement additional_module_paths - - :param additional_module_paths: Deprecated, never ever worked. - :param include_builtins: Default True, checks if a usage is a builtin - (e.g. ``sys``) and in that case does not return it. + :param include_builtins: Default True, checks if a reference is a + builtin (e.g. ``sys``) and in that case does not return it. :rtype: list of :class:`classes.Definition` """ - if additional_module_paths: - warnings.warn( - "Deprecated since version 0.12.0. This never even worked, just ignore it.", - DeprecationWarning, - stacklevel=2 - ) - def _usages(include_builtins=True): - tree_name = self._module_node.get_name_of_position(self._pos) + def _references(include_builtins=True): + tree_name = self._module_node.get_name_of_position((line, column)) if tree_name is None: # Must be syntax return [] - names = usages.usages(self._get_module_context(), tree_name) + names = find_references(self._get_module_context(), tree_name) definitions = [classes.Definition(self._inference_state, n) for n in names] if not include_builtins: definitions = [d for d in definitions if not d.in_builtin_module()] return helpers.sorted_definitions(definitions) - return _usages(**kwargs) + return _references(**kwargs) def call_signatures(self): + # Deprecated, will be removed. + return self.find_signatures(*self._pos) + + @validate_line_column + def find_signatures(self, line=None, column=None): """ Return the function object of the call you're currently in. @@ -364,25 +374,26 @@ class Script(object): This would return an empty list.. - :rtype: list of :class:`classes.CallSignature` + :rtype: list of :class:`classes.Signature` """ - call_details = helpers.get_call_signature_details(self._module_node, self._pos) + pos = line, column + call_details = helpers.get_signature_details(self._module_node, pos) if call_details is None: return [] context = self._get_module_context().create_context(call_details.bracket_leaf) - definitions = helpers.cache_call_signatures( + definitions = helpers.cache_signatures( self._inference_state, context, call_details.bracket_leaf, self._code_lines, - self._pos + pos ) debug.speed('func_call followed') # TODO here we use stubs instead of the actual values. We should use # the signatures from stubs, but the actual values, probably?! - return [classes.CallSignature(self._inference_state, signature, call_details) + return [classes.Signature(self._inference_state, signature, call_details) for signature in definitions.get_signatures()] def _analysis(self): @@ -408,7 +419,7 @@ class Script(object): unpack_tuple_to_dict(context, types, testlist) else: if node.type == 'name': - defs = self._inference_state.goto_definitions(context, node) + defs = self._inference_state.infer(context, node) else: defs = infer_call_of_leaf(context, node) try_iter_content(defs) @@ -419,6 +430,36 @@ class Script(object): finally: self._inference_state.is_analysis = False + def names(self, **kwargs): + """ + Returns a list of `Definition` objects, containing name parts. + This means you can call ``Definition.goto()`` and get the + reference of a name. + + :param all_scopes: If True lists the names of all scopes instead of only + the module namespace. + :param definitions: If True lists the names that have been defined by a + class, function or a statement (``a = b`` returns ``a``). + :param references: If True lists all the names that are not listed by + ``definitions=True``. E.g. ``a = b`` returns ``b``. + """ + return self._names(**kwargs) # Python 2... + + def _names(self, all_scopes=False, definitions=True, references=False): + def def_ref_filter(_def): + is_def = _def._name.tree_name.is_definition() + return definitions and is_def or references and not is_def + + # Set line/column to a random position, because they don't matter. + module_context = self._get_module_context() + defs = [ + classes.Definition( + self._inference_state, + module_context.create_name(name) + ) for name in get_module_names(self._module_node, all_scopes) + ] + return sorted(filter(def_ref_filter, defs), key=lambda x: (x.line, x.column)) + class Interpreter(Script): """ @@ -432,7 +473,7 @@ class Interpreter(Script): >>> from os.path import join >>> namespace = locals() >>> script = Interpreter('join("").up', [namespace]) - >>> print(script.completions()[0].name) + >>> print(script.complete()[0].name) upper """ _allow_descriptor_getattr_default = True @@ -484,34 +525,17 @@ class Interpreter(Script): def names(source=None, path=None, encoding='utf-8', all_scopes=False, definitions=True, references=False, environment=None): - """ - Returns a list of `Definition` objects, containing name parts. - This means you can call ``Definition.goto_assignments()`` and get the - reference of a name. - The parameters are the same as in :py:class:`Script`, except or the - following ones: + warnings.warn( + "Deprecated since version 0.16.0. Use Script(...).names instead.", + DeprecationWarning, + stacklevel=2 + ) - :param all_scopes: If True lists the names of all scopes instead of only - the module namespace. - :param definitions: If True lists the names that have been defined by a - class, function or a statement (``a = b`` returns ``a``). - :param references: If True lists all the names that are not listed by - ``definitions=True``. E.g. ``a = b`` returns ``b``. - """ - def def_ref_filter(_def): - is_def = _def._name.tree_name.is_definition() - return definitions and is_def or references and not is_def - - # Set line/column to a random position, because they don't matter. - script = Script(source, line=1, column=0, path=path, encoding=encoding, environment=environment) - module_context = script._get_module_context() - defs = [ - classes.Definition( - script._inference_state, - module_context.create_name(name) - ) for name in get_module_names(script._module_node, all_scopes) - ] - return sorted(filter(def_ref_filter, defs), key=lambda x: (x.line, x.column)) + return Script(source, path=path, encoding=encoding).names( + all_scopes=all_scopes, + definitions=definitions, + references=references, + ) def preload_module(*modules): @@ -523,7 +547,7 @@ def preload_module(*modules): """ for m in modules: s = "import %s as x; x." % m - Script(s, 1, len(s), None).completions() + Script(s, path=None).complete(1, len(s)) def set_debug_function(func_cb=debug.print_to_stdout, warnings=True, diff --git a/jedi/api/classes.py b/jedi/api/classes.py index 12c5b5bd..6786589b 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -104,7 +104,7 @@ class BaseDefinition(object): Here is an example of the value of this attribute. Let's consider the following source. As what is in ``variable`` is unambiguous - to Jedi, :meth:`jedi.Script.goto_definitions` should return a list of + to Jedi, :meth:`jedi.Script.infer` should return a list of definition for ``sys``, ``f``, ``C`` and ``x``. >>> from jedi._compatibility import no_unicode_pprint @@ -127,7 +127,7 @@ class BaseDefinition(object): ... variable''' >>> script = Script(source) - >>> defs = script.goto_definitions() + >>> defs = script.infer() Before showing what is in ``defs``, let's sort it by :attr:`line` so that it is easy to relate the result to the source code. @@ -177,7 +177,7 @@ class BaseDefinition(object): >>> from jedi import Script >>> source = 'import json' >>> script = Script(source, path='example.py') - >>> d = script.goto_definitions()[0] + >>> d = script.infer()[0] >>> print(d.module_name) # doctest: +ELLIPSIS json """ @@ -217,18 +217,18 @@ class BaseDefinition(object): ... def f(a, b=1): ... "Document for function f." ... ''' - >>> script = Script(source, 1, len('def f'), 'example.py') - >>> doc = script.goto_definitions()[0].docstring() + >>> script = Script(source, path='example.py') + >>> doc = script.infer(1, len('def f'))[0].docstring() >>> print(doc) f(a, b=1) Document for function f. Notice that useful extra information is added to the actual - docstring. For function, it is call signature. If you need + docstring. For function, it is signature. If you need actual docstring, use ``raw=True`` instead. - >>> print(script.goto_definitions()[0].docstring(raw=True)) + >>> print(script.infer(1, len('def f'))[0].docstring(raw=True)) Document for function f. :param fast: Don't follow imports that are only one level deep like @@ -259,8 +259,8 @@ class BaseDefinition(object): >>> source = ''' ... import os ... os.path.join''' - >>> script = Script(source, 3, len('os.path.join'), 'example.py') - >>> print(script.goto_definitions()[0].full_name) + >>> script = Script(source, path='example.py') + >>> print(script.infer(3, len('os.path.join'))[0].full_name) os.path.join Notice that it returns ``'os.path.join'`` instead of (for example) @@ -289,11 +289,19 @@ class BaseDefinition(object): return self._name.get_root_context().is_stub() - def goto_assignments(self, **kwargs): # Python 2... + def goto(self, **kwargs): with debug.increase_indent_cm('goto for %s' % self._name): - return self._goto_assignments(**kwargs) + return self._goto(**kwargs) - def _goto_assignments(self, only_stubs=False, prefer_stubs=False): + def goto_assignments(self, **kwargs): # Python 2... + warnings.warn( + "Deprecated since version 0.16.0. Use .goto.", + DeprecationWarning, + stacklevel=2 + ) + return self.goto(**kwargs) + + def _goto(self, only_stubs=False, prefer_stubs=False): assert not (only_stubs and prefer_stubs) if not self._name.is_value_name: @@ -397,7 +405,10 @@ class BaseDefinition(object): return ''.join(lines[start_index:index + after + 1]) def get_signatures(self): - return [Signature(self._inference_state, s) for s in self._name.infer().get_signatures()] + return [ + BaseSignature(self._inference_state, s) + for s in self._name.infer().get_signatures() + ] def execute(self): return _values_to_definitions(self._name.infer().execute_with_values()) @@ -405,7 +416,7 @@ class BaseDefinition(object): class Completion(BaseDefinition): """ - `Completion` objects are returned from :meth:`api.Script.completions`. They + `Completion` objects are returned from :meth:`api.Script.complete`. They provide additional information about a completion. """ def __init__(self, inference_state, name, stack, like_name_length, is_fuzzy): @@ -514,8 +525,8 @@ class Completion(BaseDefinition): class Definition(BaseDefinition): """ - *Definition* objects are returned from :meth:`api.Script.goto_assignments` - or :meth:`api.Script.goto_definitions`. + *Definition* objects are returned from :meth:`api.Script.goto` + or :meth:`api.Script.infer`. """ def __init__(self, inference_state, definition): super(Definition, self).__init__(inference_state, definition) @@ -538,8 +549,8 @@ class Definition(BaseDefinition): ... pass ... ... variable = f if random.choice([0,1]) else C''' - >>> script = Script(source, column=3) # line is maximum by default - >>> defs = script.goto_definitions() + >>> script = Script(source) # line is maximum by default + >>> defs = script.infer(column=3) >>> defs = sorted(defs, key=lambda d: d.line) >>> no_unicode_pprint(defs) # doctest: +NORMALIZE_WHITESPACE [, @@ -620,14 +631,14 @@ class Definition(BaseDefinition): return hash((self._name.start_pos, self.module_path, self.name, self._inference_state)) -class Signature(Definition): +class BaseSignature(Definition): """ - `Signature` objects is the return value of `Script.function_definition`. + `BaseSignature` objects is the return value of `Script.function_definition`. It knows what functions you are currently in. e.g. `isinstance(` would return the `isinstance` function. without `(` it would return nothing. """ def __init__(self, inference_state, signature): - super(Signature, self).__init__(inference_state, signature.name) + super(BaseSignature, self).__init__(inference_state, signature.name) self._signature = signature @property @@ -642,15 +653,15 @@ class Signature(Definition): return self._signature.to_string() -class CallSignature(Signature): +class Signature(BaseSignature): """ - `CallSignature` objects is the return value of `Script.call_signatures`. + `Signature` objects is the return value of `Script.find_signatures`. It knows what functions you are currently in. e.g. `isinstance(` would return the `isinstance` function with its params. Without `(` it would return nothing. """ def __init__(self, inference_state, signature, call_details): - super(CallSignature, self).__init__(inference_state, signature) + super(Signature, self).__init__(inference_state, signature) self._call_details = call_details self._signature = signature diff --git a/jedi/api/completion.py b/jedi/api/completion.py index 62e52ff1..e8966173 100644 --- a/jedi/api/completion.py +++ b/jedi/api/completion.py @@ -10,7 +10,7 @@ from jedi import settings from jedi.api import classes from jedi.api import helpers from jedi.api import keywords -from jedi.api.file_name import file_name_completions +from jedi.api.file_name import complete_file_name from jedi.inference import imports from jedi.inference.helpers import infer_call_of_leaf, parse_dotted_names from jedi.inference.context import get_global_filters @@ -18,9 +18,9 @@ from jedi.inference.gradual.conversion import convert_values from jedi.parser_utils import cut_value_at_position -def get_call_signature_param_names(call_signatures): +def get_signature_param_names(signatures): # add named params - for call_sig in call_signatures: + for call_sig in signatures: for p in call_sig.params: # Allow protected access, because it's a public API. if p._name.get_kind() in (Parameter.POSITIONAL_OR_KEYWORD, @@ -74,7 +74,7 @@ def get_flow_scope_node(module_node, position): class Completion: def __init__(self, inference_state, module_context, code_lines, position, - call_signatures_callback, fuzzy=False): + signatures_callback, fuzzy=False): self._inference_state = inference_state self._module_context = module_context self._module_node = module_context.tree_node @@ -86,27 +86,24 @@ class Completion: # everything. We want the start of the name we're on. self._original_position = position self._position = position[0], position[1] - len(self._like_name) - self._call_signatures_callback = call_signatures_callback + self._signatures_callback = signatures_callback self._fuzzy = fuzzy - def completions(self, fuzzy=False, **kwargs): - return self._completions(fuzzy, **kwargs) - - def _completions(self, fuzzy): + def complete(self, fuzzy): leaf = self._module_node.get_leaf_for_position(self._position, include_prefixes=True) string, start_leaf = _extract_string_while_in_string(leaf, self._position) if string is not None: - completions = list(file_name_completions( + completions = list(complete_file_name( self._inference_state, self._module_context, start_leaf, string, - self._like_name, self._call_signatures_callback, + self._like_name, self._signatures_callback, self._code_lines, self._original_position, fuzzy )) if completions: return completions - completion_names = self._get_value_completions(leaf) + completion_names = self._complete_python(leaf) completions = filter_names(self._inference_state, completion_names, self.stack, self._like_name, fuzzy) @@ -115,7 +112,7 @@ class Completion: x.name.startswith('_'), x.name.lower())) - def _get_value_completions(self, leaf): + def _complete_python(self, leaf): """ Analyzes the value that a completion is made in and decides what to return. @@ -145,7 +142,7 @@ class Completion: return [] # If we don't have a value, just use global completion. - return self._global_completions() + return self._complete_global_scope() allowed_transitions = \ list(stack._allowed_transition_names_and_token_types()) @@ -185,7 +182,7 @@ class Completion: completion_names = [] current_line = self._code_lines[self._position[0] - 1][:self._position[1]] if not current_line or current_line[-1] in ' \t.;': - completion_names += self._get_keyword_completion_names(allowed_transitions) + completion_names += self._complete_keywords(allowed_transitions) if any(t in allowed_transitions for t in (PythonTokenTypes.NAME, PythonTokenTypes.INDENT)): @@ -203,7 +200,7 @@ class Completion: if nodes and nodes[-1] in ('as', 'def', 'class'): # No completions for ``with x as foo`` and ``import x as foo``. # Also true for defining names as a class or function. - return list(self._get_class_value_completions(is_function=True)) + return list(self._complete_inherited(is_function=True)) elif "import_stmt" in nonterminals: level, names = parse_dotted_names(nodes, "import_from" in nonterminals) @@ -215,10 +212,10 @@ class Completion: ) elif nonterminals[-1] in ('trailer', 'dotted_name') and nodes[-1] == '.': dot = self._module_node.get_leaf_for_position(self._position) - completion_names += self._trailer_completions(dot.get_previous_leaf()) + completion_names += self._complete_trailer(dot.get_previous_leaf()) else: - completion_names += self._global_completions() - completion_names += self._get_class_value_completions(is_function=False) + completion_names += self._complete_global_scope() + completion_names += self._complete_inherited(is_function=False) # Apparently this looks like it's good enough to filter most cases # so that signature completions don't randomly appear. @@ -229,17 +226,17 @@ class Completion: # 3. Decorators are very primitive and have an optional `(` with # optional arglist in them. if nodes[-1] in ['(', ','] and nonterminals[-1] in ('trailer', 'arglist', 'decorator'): - call_signatures = self._call_signatures_callback() - completion_names += get_call_signature_param_names(call_signatures) + signatures = self._signatures_callback(*self._position) + completion_names += get_signature_param_names(signatures) return completion_names - def _get_keyword_completion_names(self, allowed_transitions): + def _complete_keywords(self, allowed_transitions): for k in allowed_transitions: if isinstance(k, str) and k.isalpha(): yield keywords.KeywordName(self._inference_state, k) - def _global_completions(self): + def _complete_global_scope(self): context = get_user_context(self._module_context, self._position) debug.dbg('global completion scope: %s', context) flow_scope_node = get_flow_scope_node(self._module_node, self._position) @@ -253,7 +250,7 @@ class Completion: completion_names += filter.values() return completion_names - def _trailer_completions(self, previous_leaf): + def _complete_trailer(self, previous_leaf): user_value = get_user_context(self._module_context, self._position) inferred_context = self._module_context.create_context(previous_leaf) values = infer_call_of_leaf(inferred_context, previous_leaf) @@ -275,7 +272,7 @@ class Completion: i = imports.Importer(self._inference_state, names, self._module_context, level) return i.completion_names(self._inference_state, only_modules=only_modules) - def _get_class_value_completions(self, is_function=True): + def _complete_inherited(self, is_function=True): """ Autocomplete inherited methods when overriding in child class. """ diff --git a/jedi/api/file_name.py b/jedi/api/file_name.py index 1747c803..9a536c43 100644 --- a/jedi/api/file_name.py +++ b/jedi/api/file_name.py @@ -8,8 +8,8 @@ from jedi.inference.helpers import get_str_or_none from jedi.parser_utils import get_string_quote -def file_name_completions(inference_state, module_context, start_leaf, string, - like_name, call_signatures_callback, code_lines, position, fuzzy): +def complete_file_name(inference_state, module_context, start_leaf, string, + like_name, signatures_callback, code_lines, position, fuzzy): # First we want to find out what can actually be changed as a name. like_name_length = len(os.path.basename(string) + like_name) @@ -23,7 +23,7 @@ def file_name_completions(inference_state, module_context, start_leaf, string, must_start_with = os.path.basename(string) + like_name string = os.path.dirname(string) - sigs = call_signatures_callback() + sigs = signatures_callback(*position) is_in_os_path_join = sigs and all(s.full_name == 'os.path.join' for s in sigs) if is_in_os_path_join: to_be_added = _add_os_path_join(module_context, start_leaf, sigs[0].bracket_start) diff --git a/jedi/api/helpers.py b/jedi/api/helpers.py index ea797560..598bd3ca 100644 --- a/jedi/api/helpers.py +++ b/jedi/api/helpers.py @@ -4,6 +4,7 @@ Helpers for the API import re from collections import namedtuple from textwrap import dedent +from functools import wraps from parso.python.parser import Parser from parso.python import tree @@ -13,7 +14,7 @@ from jedi.inference.base_value import NO_VALUES from jedi.inference.syntax_tree import infer_atom from jedi.inference.helpers import infer_call_of_leaf from jedi.inference.compiled import get_string_value_set -from jedi.cache import call_signature_time_cache +from jedi.cache import signature_time_cache CompletionParts = namedtuple('CompletionParts', ['path', 'has_dot', 'name']) @@ -149,11 +150,9 @@ def get_stack_at_position(grammar, code_lines, leaf, pos): ) -def infer_goto_definition(inference_state, context, leaf): +def infer(inference_state, context, leaf): if leaf.type == 'name': - # In case of a name we can just use goto_definition which does all the - # magic itself. - return inference_state.goto_definitions(context, leaf) + return inference_state.infer(context, leaf) parent = leaf.parent definitions = NO_VALUES @@ -327,7 +326,7 @@ def _get_index_and_key(nodes, position): return nodes_before.count(','), key_str -def _get_call_signature_details_from_error_node(node, additional_children, position): +def _get_signature_details_from_error_node(node, additional_children, position): for index, element in reversed(list(enumerate(node.children))): # `index > 0` means that it's a trailer and not an atom. if element == '(' and element.end_pos <= position and index > 0: @@ -341,7 +340,7 @@ def _get_call_signature_details_from_error_node(node, additional_children, posit return CallDetails(element, children + additional_children, position) -def get_call_signature_details(module, position): +def get_signature_details(module, position): leaf = module.get_leaf_for_position(position, include_prefixes=True) # It's easier to deal with the previous token than the next one in this # case. @@ -356,15 +355,15 @@ def get_call_signature_details(module, position): node = leaf.parent while node is not None: if node.type in ('funcdef', 'classdef'): - # Don't show call signatures if there's stuff before it that just - # makes it feel strange to have a call signature. + # Don't show signatures if there's stuff before it that just + # makes it feel strange to have a signature. return None additional_children = [] for n in reversed(node.children): if n.start_pos < position: if n.type == 'error_node': - result = _get_call_signature_details_from_error_node( + result = _get_signature_details_from_error_node( n, additional_children, position ) if result is not None: @@ -391,8 +390,8 @@ def get_call_signature_details(module, position): return None -@call_signature_time_cache("call_signatures_validity") -def cache_call_signatures(inference_state, context, bracket_leaf, code_lines, user_pos): +@signature_time_cache("call_signatures_validity") +def cache_signatures(inference_state, context, bracket_leaf, code_lines, user_pos): """This function calculates the cache key.""" line_index = user_pos[0] - 1 @@ -406,8 +405,31 @@ def cache_call_signatures(inference_state, context, bracket_leaf, code_lines, us yield None # Don't cache! else: yield (module_path, before_bracket, bracket_leaf.start_pos) - yield infer_goto_definition( + yield infer( inference_state, context, bracket_leaf.get_previous_leaf(), ) + + +def validate_line_column(func): + @wraps(func) + def wrapper(self, line=None, column=None, *args, **kwargs): + line = max(len(self._code_lines), 1) if line is None else line + if not (0 < line <= len(self._code_lines)): + raise ValueError('`line` parameter is not in a valid range.') + + line_string = self._code_lines[line - 1] + line_len = len(line_string) + if line_string.endswith('\r\n'): + line_len -= 1 + if line_string.endswith('\n'): + line_len -= 1 + + column = line_len if column is None else column + if not (0 <= column <= line_len): + raise ValueError('`column` parameter (%d) is not in a valid range ' + '(0-%d) for line %d (%r).' % ( + column, line_len, line, line_string)) + return func(self, line, column, *args, **kwargs) + return wrapper diff --git a/jedi/cache.py b/jedi/cache.py index 93e2bd7f..e2ba9374 100644 --- a/jedi/cache.py +++ b/jedi/cache.py @@ -75,7 +75,7 @@ def clear_time_caches(delete_all=False): del tc[key] -def call_signature_time_cache(time_add_setting): +def signature_time_cache(time_add_setting): """ This decorator works as follows: Call it with a setting and after that use the function with a callable that returns the key. diff --git a/jedi/inference/__init__.py b/jedi/inference/__init__.py index bd1b66c3..e3c2db7a 100644 --- a/jedi/inference/__init__.py +++ b/jedi/inference/__init__.py @@ -143,7 +143,7 @@ class InferenceState(object): """Convenience function""" return self.project._get_sys_path(self, environment=self.environment, **kwargs) - def goto_definitions(self, context, name): + def infer(self, context, name): def_ = name.get_definition(import_name_always=True) if def_ is not None: type_ = def_.type diff --git a/jedi/inference/dynamic_params.py b/jedi/inference/dynamic_params.py index 7b17046c..e37c442e 100644 --- a/jedi/inference/dynamic_params.py +++ b/jedi/inference/dynamic_params.py @@ -74,7 +74,7 @@ def dynamic_param_lookup(function_value, param_index): path = function_value.get_root_context().py__file__() if path is not None and is_stdlib_path(path): - # We don't want to search for usages in the stdlib. Usually people + # We don't want to search for references in the stdlib. Usually people # don't work with it (except if you are a core maintainer, sorry). # This makes everything slower. Just disable it and run the tests, # you will see the slowdown, especially in 3.6. @@ -186,7 +186,7 @@ def _check_name_for_execution(inference_state, context, compare_node, name, trai args = InstanceArguments(value.instance, args) return args - for value in inference_state.goto_definitions(context, name): + for value in inference_state.infer(context, name): value_node = value.tree_node if compare_node == value_node: yield create_args(value) diff --git a/jedi/inference/usages.py b/jedi/inference/references.py similarity index 81% rename from jedi/inference/usages.py rename to jedi/inference/references.py index 95888ed2..22fe4e92 100644 --- a/jedi/inference/usages.py +++ b/jedi/inference/references.py @@ -32,13 +32,13 @@ def _find_names(module_context, tree_name): return _dictionarize(_resolve_names(found_names)) -def usages(module_context, tree_name): +def find_references(module_context, tree_name): search_name = tree_name.value found_names = _find_names(module_context, tree_name) module_contexts = set(d.get_root_context() for d in found_names.values()) module_contexts = set(m for m in module_contexts if not m.is_compiled()) - non_matching_usage_maps = {} + non_matching_reference_maps = {} inf = module_context.inference_state potential_modules = imports.get_module_contexts_containing_name( inf, module_contexts, search_name @@ -49,15 +49,15 @@ def usages(module_context, tree_name): if any(tree_name in found_names for tree_name in new): found_names.update(new) for tree_name in new: - for dct in non_matching_usage_maps.get(tree_name, []): - # A usage that was previously searched for matches with - # a now found name. Merge. + for dct in non_matching_reference_maps.get(tree_name, []): + # A reference that was previously searched for matches + # with a now found name. Merge. found_names.update(dct) try: - del non_matching_usage_maps[tree_name] + del non_matching_reference_maps[tree_name] except KeyError: pass else: for name in new: - non_matching_usage_maps.setdefault(name, []).append(new) + non_matching_reference_maps.setdefault(name, []).append(new) return found_names.values() diff --git a/jedi/inference/signature.py b/jedi/inference/signature.py index 7837fb88..9f90a1cc 100644 --- a/jedi/inference/signature.py +++ b/jedi/inference/signature.py @@ -107,7 +107,7 @@ class TreeSignature(AbstractSignature): for executed_param_name in executed_param_names) if debug.enable_notice: tree_node = self._function_value.tree_node - signature = parser_utils.get_call_signature(tree_node) + signature = parser_utils.get_signature(tree_node) if matches: debug.dbg("Overloading match: %s@%s (%s)", signature, tree_node.start_pos[0], arguments, color='BLUE') diff --git a/jedi/inference/syntax_tree.py b/jedi/inference/syntax_tree.py index bf0f67e5..5e73878f 100644 --- a/jedi/inference/syntax_tree.py +++ b/jedi/inference/syntax_tree.py @@ -108,7 +108,7 @@ def infer_node(context, element): str_element_names = [e.value for e in element_names] if any(i.value in str_element_names for i in if_names): for if_name in if_names: - definitions = context.inference_state.goto_definitions(context, if_name) + definitions = context.inference_state.infer(context, if_name) # Every name that has multiple different definitions # causes the complexity to rise. The complexity should # never fall below 1. diff --git a/jedi/parser_utils.py b/jedi/parser_utils.py index 4be8416c..5667853f 100644 --- a/jedi/parser_utils.py +++ b/jedi/parser_utils.py @@ -127,10 +127,10 @@ def safe_literal_eval(value): return '' -def get_call_signature(funcdef, width=72, call_string=None, - omit_first_param=False, omit_return_annotation=False): +def get_signature(funcdef, width=72, call_string=None, + omit_first_param=False, omit_return_annotation=False): """ - Generate call signature of this function. + Generate a string signature of a function. :param width: Fold lines if a line is longer than this value. :type width: int diff --git a/jedi/refactoring.py b/jedi/refactoring.py index 996c67ba..4a25ed66 100644 --- a/jedi/refactoring.py +++ b/jedi/refactoring.py @@ -57,7 +57,7 @@ def rename(script, new_name): :param script: The source Script object. :return: list of changed lines/changed files """ - return Refactoring(_rename(script.usages(), new_name)) + return Refactoring(_rename(script.find_references(), new_name)) def _rename(names, replace_str): @@ -166,11 +166,11 @@ def inline(script): dct = {} - definitions = script.goto_assignments() + definitions = script.goto() assert len(definitions) == 1 stmt = definitions[0]._definition - usages = script.usages() - inlines = [r for r in usages + references = script.find_references() + inlines = [r for r in references if not stmt.start_pos <= (r.line, r.column) <= stmt.end_pos] inlines = sorted(inlines, key=lambda x: (x.module_path, x.line, x.column), reverse=True) diff --git a/jedi/utils.py b/jedi/utils.py index 56b21d0c..85fe4314 100644 --- a/jedi/utils.py +++ b/jedi/utils.py @@ -83,7 +83,7 @@ def setup_readline(namespace_module=__main__, fuzzy=False): logging.debug("Start REPL completion: " + repr(text)) interpreter = Interpreter(text, [namespace_module.__dict__]) - completions = interpreter.completions(fuzzy=fuzzy) + completions = interpreter.complete(fuzzy=fuzzy) logging.debug("REPL completions: %s", completions) self.matches = [ diff --git a/scripts/profile_output.py b/scripts/profile_output.py index 27b9e9f5..3497ce6b 100755 --- a/scripts/profile_output.py +++ b/scripts/profile_output.py @@ -45,9 +45,9 @@ def run(code, index, infer=False): start = time.time() script = jedi.Script(code) if infer: - result = script.goto_definitions() + result = script.infer() else: - result = script.completions() + result = script.complete() print('Used %ss for the %sth run.' % (time.time() - start, index + 1)) return result diff --git a/scripts/wx_check.py b/scripts/wx_check.py index 2692f43a..6d49aa77 100755 --- a/scripts/wx_check.py +++ b/scripts/wx_check.py @@ -45,7 +45,7 @@ def run(): print('Process Memory before: %skB' % process_memory()) # After this the module should be cached. # Need to invent a path so that it's really cached. - jedi.Script(wx_core, path='foobar.py').completions() + jedi.Script(wx_core, path='foobar.py').complete() gc.collect() # make sure that it's all fair and the gc did its job. print('Process Memory after: %skB' % process_memory()) diff --git a/sith.py b/sith.py index 17c6546c..64d8a308 100755 --- a/sith.py +++ b/sith.py @@ -95,9 +95,7 @@ class TestCase(object): args = json.load(f) return cls(*args) - operations = [ - 'completions', 'goto_assignments', 'goto_definitions', 'usages', - 'call_signatures'] + operations = ['complete', 'goto', 'infer', 'find_references', 'find_signatures'] @classmethod def generate(cls, file_path): @@ -123,12 +121,12 @@ class TestCase(object): def run(self, debugger, record=None, print_result=False): try: with open(self.path) as f: - self.script = jedi.Script(f.read(), self.line, self.column, self.path) + self.script = jedi.Script(f.read(), path=self.path) kwargs = {} if self.operation == 'goto_assignments': kwargs['follow_imports'] = random.choice([False, True]) - self.objects = getattr(self.script, self.operation)(**kwargs) + self.objects = getattr(self.script, self.operation)(self.line, self.column, **kwargs) if print_result: print("{path}: Line {line} column {column}".format(**self.__dict__)) self.show_location(self.line, self.column) diff --git a/test/blabla_test_documentation.py b/test/blabla_test_documentation.py index 7f6c478e..c0625339 100644 --- a/test/blabla_test_documentation.py +++ b/test/blabla_test_documentation.py @@ -1,29 +1,29 @@ def test_keyword_doc(Script): - r = list(Script("or", 1, 1).goto_definitions()) + r = list(Script("or").infer(1, 1)) assert len(r) == 1 assert len(r[0].doc) > 100 - r = list(Script("asfdasfd", 1, 1).goto_definitions()) + r = list(Script("asfdasfd").infer(1, 1)) assert len(r) == 0 - k = Script("fro").completions()[0] + k = Script("fro").complete()[0] imp_start = '\nThe ``import' assert k.raw_doc.startswith(imp_start) assert k.doc.startswith(imp_start) def test_blablabla(Script): - defs = Script("import").goto_definitions() + defs = Script("import").infer() assert len(defs) == 1 and [1 for d in defs if d.doc] # unrelated to #44 def test_operator_doc(Script): - r = list(Script("a == b", 1, 3).goto_definitions()) + r = list(Script("a == b").infer(1, 3)) assert len(r) == 1 assert len(r[0].doc) > 100 def test_lambda(Script): - defs = Script('lambda x: x', column=0).goto_definitions() + defs = Script('lambda x: x').infer(column=0) assert [d.type for d in defs] == ['keyword'] diff --git a/test/completion/goto.py b/test/completion/goto.py index 029c59cb..3deabf33 100644 --- a/test/completion/goto.py +++ b/test/completion/goto.py @@ -1,4 +1,4 @@ -# goto_assignments command tests are different in syntax +# goto command tests are different in syntax definition = 3 #! 0 ['a = definition'] diff --git a/test/completion/thirdparty/jedi_.py b/test/completion/thirdparty/jedi_.py index 59f21f75..f588f740 100644 --- a/test/completion/thirdparty/jedi_.py +++ b/test/completion/thirdparty/jedi_.py @@ -1,7 +1,7 @@ from jedi import functions, inference, parsing -el = functions.completions()[0] +el = functions.complete()[0] #? ['description'] el.description diff --git a/test/completion/usages.py b/test/completion/usages.py index 0976798c..2f8d1802 100644 --- a/test/completion/usages.py +++ b/test/completion/usages.py @@ -1,5 +1,5 @@ """ -Renaming tests. This means search for usages. +Renaming tests. This means search for references. I always leave a little bit of space to add room for additions, because the results always contain position informations. """ diff --git a/test/refactor/rename.py b/test/refactor/rename.py index e98c5897..8faab24f 100644 --- a/test/refactor/rename.py +++ b/test/refactor/rename.py @@ -1,6 +1,6 @@ """ Test coverage for renaming is mostly being done by testing -`Script.usages`. +`Script.find_references`. """ # --- simple diff --git a/test/run.py b/test/run.py index 6223298a..59c42ea8 100755 --- a/test/run.py +++ b/test/run.py @@ -10,9 +10,9 @@ tests. There are different kind of tests: -- completions / goto_definitions ``#?`` -- goto_assignments: ``#!`` -- usages: ``#<`` +- completions / inference ``#?`` +- goto: ``#!`` +- references: ``#<`` How to run tests? +++++++++++++++++ @@ -26,7 +26,7 @@ multiple Python versions. Integration test cases are located in ``test/completion`` directory and each test case is indicated by either the comment ``#?`` (completions / -definitions), ``#!`` (assignments), or ``#<`` (usages). +inference), ``#!`` (goto), or ``#<`` (references). There is also support for third party libraries. In a normal test run they are not being executed, you have to provide a ``--thirdparty`` option. @@ -76,17 +76,17 @@ For example:: Because it follows ``a.rea`` and a is an ``int``, which has a ``real`` property. -Goto Definitions -++++++++++++++++ +Inference ++++++++++ -Definition tests use the same symbols like completion tests. This is +Inference tests use the same symbols like completion tests. This is possible because the completion tests are defined with a list:: #? int() ab = 3; ab -Goto Assignments -++++++++++++++++ +Goto +++++ Tests look like this:: @@ -100,8 +100,8 @@ describes the position of the test (otherwise it's just the end of line):: #! 2 ['abc=1'] abc -Usages -++++++ +References +++++++++++ Tests look like this:: @@ -131,9 +131,9 @@ from jedi.inference.analysis import Warning TEST_COMPLETIONS = 0 -TEST_DEFINITIONS = 1 -TEST_ASSIGNMENTS = 2 -TEST_USAGES = 3 +TEST_INFERENCE = 1 +TEST_GOTO = 2 +TEST_REFERENCES = 3 grammar36 = parso.load_grammar(version='3.6') @@ -195,28 +195,25 @@ class IntegrationTestCase(BaseTestCase): self.line_nr_test, self.line.rstrip()) def script(self, environment): - return jedi.Script( - self.source, self.line_nr, self.column, self.path, - environment=environment - ) + return jedi.Script(self.source, path=self.path, environment=environment) def run(self, compare_cb, environment=None): testers = { TEST_COMPLETIONS: self.run_completion, - TEST_DEFINITIONS: self.run_goto_definitions, - TEST_ASSIGNMENTS: self.run_goto_assignments, - TEST_USAGES: self.run_usages, + TEST_INFERENCE: self.run_inference, + TEST_GOTO: self.run_goto, + TEST_REFERENCES: self.run_find_references, } return testers[self.test_type](compare_cb, environment) def run_completion(self, compare_cb, environment): - completions = self.script(environment).completions() - #import cProfile; cProfile.run('script.completions()') + completions = self.script(environment).complete(self.line_nr, self.column) + # import cProfile; cProfile.run('...') comp_str = {c.name for c in completions} return compare_cb(self, comp_str, set(literal_eval(self.correct))) - def run_goto_definitions(self, compare_cb, environment): + def run_inference(self, compare_cb, environment): script = self.script(environment) inference_state = script._inference_state @@ -233,9 +230,6 @@ class IntegrationTestCase(BaseTestCase): node = parser.get_root_node() module_context = script._get_module_context() user_context = get_user_context(module_context, (self.line_nr, 0)) - # TODO needed? - #if user_context._value.api_type == 'function': - # user_context = user_context.get_function_execution() node.parent = user_context.tree_node results = convert_values(user_context.infer_node(node)) if not results: @@ -250,17 +244,17 @@ class IntegrationTestCase(BaseTestCase): return should should = definition(self.correct, self.start, script.path) - result = script.goto_definitions() + result = script.infer(self.line_nr, self.column) is_str = set(comparison(r) for r in result) return compare_cb(self, is_str, should) - def run_goto_assignments(self, compare_cb, environment): - result = self.script(environment).goto_assignments() + def run_goto(self, compare_cb, environment): + result = self.script(environment).goto(self.line_nr, self.column) comp_str = str(sorted(str(r.description) for r in result)) return compare_cb(self, comp_str, self.correct) - def run_usages(self, compare_cb, environment): - result = self.script(environment).usages() + def run_find_references(self, compare_cb, environment): + result = self.script(environment).find_references(self.line_nr, self.column) self.correct = self.correct.strip() compare = sorted( (re.sub(r'^test\.completion\.', '', r.module_name), r.line, r.column) @@ -287,7 +281,7 @@ class IntegrationTestCase(BaseTestCase): class StaticAnalysisCase(BaseTestCase): """ Static Analysis cases lie in the static_analysis folder. - The tests also start with `#!`, like the goto_definition tests. + The tests also start with `#!`, like the inference tests. """ def __init__(self, path): self._path = path @@ -311,12 +305,14 @@ class StaticAnalysisCase(BaseTestCase): return cases def run(self, compare_cb, environment): + def typ_str(inst): + return 'warning ' if isinstance(inst, Warning) else '' + analysis = jedi.Script( self._source, path=self._path, environment=environment, )._analysis() - typ_str = lambda inst: 'warning ' if isinstance(inst, Warning) else '' analysis = [(r.line, r.column, typ_str(r) + r.name) for r in analysis] compare_cb(self, analysis, self.collect_comparison()) @@ -354,19 +350,19 @@ def collect_file_tests(path, lines, lines_to_execute): else: column = len(line) - 1 # -1 for the \n if test_type == '!': - yield makecase(TEST_ASSIGNMENTS) + yield makecase(TEST_GOTO) elif test_type == '<': - yield makecase(TEST_USAGES) + yield makecase(TEST_REFERENCES) elif correct.startswith('['): yield makecase(TEST_COMPLETIONS) else: - yield makecase(TEST_DEFINITIONS) + yield makecase(TEST_INFERENCE) correct = None else: skip_version_info = skip_python_version(line) or skip_version_info try: r = re.search(r'(?:^|(?<=\s))#([?!<])\s*([^\n]*)', line) - # test_type is ? for completion and ! for goto_assignments + # test_type is ? for completion and ! for goto test_type = r.group(1) correct = r.group(2) # Quick hack to make everything work (not quite a bloody unicorn hack though). diff --git a/test/test_api/import_tree_for_usages/__init__.py b/test/test_api/import_tree_for_usages/__init__.py index d2ae403e..70352869 100644 --- a/test/test_api/import_tree_for_usages/__init__.py +++ b/test/test_api/import_tree_for_usages/__init__.py @@ -1,4 +1,4 @@ """ -An import tree, for testing usages. +An import tree, for testing references. """ diff --git a/test/test_api/test_api.py b/test/test_api/test_api.py index 506d03be..7982f197 100644 --- a/test/test_api/test_api.py +++ b/test/test_api/test_api.py @@ -56,29 +56,29 @@ def test_line_number_errors(Script): s = 'hello' # lines with raises(ValueError): - Script(s, 2, 0) + Script(s).complete(2, 0) with raises(ValueError): - Script(s, 0, 0) + Script(s).complete(0, 0) # columns with raises(ValueError): - Script(s, 1, len(s) + 1) + Script(s).infer(1, len(s) + 1) with raises(ValueError): - Script(s, 1, -1) + Script(s).goto(1, -1) # ok - Script(s, 1, 0) - Script(s, 1, len(s)) + Script(s).find_signatures(1, 0) + Script(s).find_references(1, len(s)) def _check_number(Script, source, result='float'): - completions = Script(source).completions() + completions = Script(source).complete() assert completions[0].parent().name == result def test_completion_on_number_literals(Script): # No completions on an int literal (is a float). - assert [c.name for c in Script('1. ').completions()] \ + assert [c.name for c in Script('1. ').complete()] \ == ['and', 'if', 'in', 'is', 'not', 'or'] # Multiple points after an int literal basically mean that there's a float @@ -90,27 +90,27 @@ def test_completion_on_number_literals(Script): _check_number(Script, '1.e14.') _check_number(Script, '1.e-3.') _check_number(Script, '9e3.') - assert Script('1.e3..').completions() == [] - assert Script('1.e-13..').completions() == [] + assert Script('1.e3..').complete() == [] + assert Script('1.e-13..').complete() == [] def test_completion_on_hex_literals(Script): - assert Script('0x1..').completions() == [] + assert Script('0x1..').complete() == [] _check_number(Script, '0x1.', 'int') # hexdecimal # Completing binary literals doesn't work if they are not actually binary # (invalid statements). - assert Script('0b2.b').completions() == [] + assert Script('0b2.b').complete() == [] _check_number(Script, '0b1.', 'int') # binary _check_number(Script, '0x2e.', 'int') _check_number(Script, '0xE7.', 'int') _check_number(Script, '0xEa.', 'int') # theoretically, but people can just check for syntax errors: - assert Script('0x.').completions() == [] + assert Script('0x.').complete() == [] def test_completion_on_complex_literals(Script): - assert Script('1j..').completions() == [] + assert Script('1j..').complete() == [] _check_number(Script, '1j.', 'complex') _check_number(Script, '44.j.', 'complex') _check_number(Script, '4.0j.', 'complex') @@ -118,24 +118,24 @@ def test_completion_on_complex_literals(Script): # which a keyword like or is allowed. Good times, haha! # However this has been disabled again, because it apparently annoyed # users. So no completion after j without a space :) - assert not Script('4j').completions() - assert ({c.name for c in Script('4j ').completions()} == + assert not Script('4j').complete() + assert ({c.name for c in Script('4j ').complete()} == {'if', 'and', 'in', 'is', 'not', 'or'}) -def test_goto_assignments_on_non_name(Script, environment): - assert Script('for').goto_assignments() == [] +def test_goto_non_name(Script, environment): + assert Script('for').goto() == [] - assert Script('assert').goto_assignments() == [] - assert Script('True').goto_assignments() == [] + assert Script('assert').goto() == [] + assert Script('True').goto() == [] -def test_goto_definitions_on_non_name(Script): - assert Script('import x', column=0).goto_definitions() == [] +def test_infer_on_non_name(Script): + assert Script('import x').infer(column=0) == [] -def test_goto_definitions_on_generator(Script): - def_, = Script('def x(): yield 1\ny=x()\ny').goto_definitions() +def test_infer_on_generator(Script): + def_, = Script('def x(): yield 1\ny=x()\ny').infer() assert def_.name == 'Generator' @@ -159,17 +159,17 @@ def test_goto_definition_not_multiple(Script): else: a = A(1) a''') - assert len(Script(s).goto_definitions()) == 1 + assert len(Script(s).infer()) == 1 -def test_usage_description(Script): - descs = [u.description for u in Script("foo = ''; foo").usages()] +def test_reference_description(Script): + descs = [u.description for u in Script("foo = ''; foo").find_references()] assert set(descs) == {"foo = ''", 'foo'} def test_get_line_code(Script): def get_line_code(source, line=None, **kwargs): - return Script(source, line=line).completions()[0].get_line_code(**kwargs) + return Script(source).complete(line=line)[0].get_line_code(**kwargs) # On builtin assert get_line_code('abs') == 'def abs(__n: SupportsAbs[_T]) -> _T: ...\n' @@ -191,49 +191,49 @@ def test_get_line_code(Script): def test_get_line_code_on_builtin(Script, disable_typeshed): - abs_ = Script('abs').completions()[0] + abs_ = Script('abs').complete()[0] assert abs_.name == 'abs' assert abs_.get_line_code() == '' assert abs_.line is None -def test_goto_assignments_follow_imports(Script): +def test_goto_follow_imports(Script): code = dedent(""" import inspect inspect.isfunction""") - definition, = Script(code, column=0).goto_assignments(follow_imports=True) + definition, = Script(code).goto(column=0, follow_imports=True) assert 'inspect.py' in definition.module_path assert (definition.line, definition.column) == (1, 0) - definition, = Script(code).goto_assignments(follow_imports=True) + definition, = Script(code).goto(follow_imports=True) assert 'inspect.py' in definition.module_path assert (definition.line, definition.column) > (1, 0) code = '''def param(p): pass\nparam(1)''' start_pos = 1, len('def param(') - script = Script(code, *start_pos) - definition, = script.goto_assignments(follow_imports=True) + script = Script(code) + definition, = script.goto(*start_pos, follow_imports=True) assert (definition.line, definition.column) == start_pos assert definition.name == 'p' - result, = definition.goto_assignments() + result, = definition.goto() assert result.name == 'p' result, = definition.infer() assert result.name == 'int' result, = result.infer() assert result.name == 'int' - definition, = script.goto_assignments() + definition, = script.goto(*start_pos) assert (definition.line, definition.column) == start_pos - d, = Script('a = 1\na').goto_assignments(follow_imports=True) + d, = Script('a = 1\na').goto(follow_imports=True) assert d.name == 'a' def test_goto_module(Script): def check(line, expected, follow_imports=False): - script = Script(path=path, line=line) - module, = script.goto_assignments(follow_imports=follow_imports) + script = Script(path=path) + module, = script.goto(line=line, follow_imports=follow_imports) assert module.module_path == expected base_path = os.path.join(os.path.dirname(__file__), 'simple_import') @@ -264,7 +264,7 @@ def test_goto_definition_cursor(Script): should2 = 8, 10 def get_def(pos): - return [d.description for d in Script(s, *pos).goto_definitions()] + return [d.description for d in Script(s).infer(*pos)] in_name = get_def(in_name) under_score = get_def(under_score) @@ -290,7 +290,7 @@ def test_no_statement_parent(Script): pass variable = f if random.choice([0, 1]) else C""") - defs = Script(source, column=3).goto_definitions() + defs = Script(source).infer(column=3) defs = sorted(defs, key=lambda d: d.line) assert [d.description for d in defs] == ['def f', 'class C'] @@ -303,27 +303,27 @@ def test_backslash_continuation_and_bracket(Script): lines = code.splitlines() column = lines[-1].index('(') - def_, = Script(code, line=len(lines), column=column).goto_definitions() + def_, = Script(code).infer(line=len(lines), column=column) assert def_.name == 'int' def test_goto_follow_builtin_imports(Script): s = Script('import sys; sys') - d, = s.goto_assignments(follow_imports=True) + d, = s.goto(follow_imports=True) assert d.in_builtin_module() is True - d, = s.goto_assignments(follow_imports=True, follow_builtin_imports=True) + d, = s.goto(follow_imports=True, follow_builtin_imports=True) assert d.in_builtin_module() is True def test_docstrings_for_completions(Script): - for c in Script('').completions(): + for c in Script('').complete(): assert isinstance(c.docstring(), (str, unicode)) def test_fuzzy_completion(Script): script = Script('string = "hello"\nstring.upper') assert ['isupper', - 'upper'] == [comp.name for comp in script.completions(fuzzy=True)] + 'upper'] == [comp.name for comp in script.complete(fuzzy=True)] def test_math_fuzzy_completion(Script, environment): @@ -331,7 +331,7 @@ def test_math_fuzzy_completion(Script, environment): expected = ['copysign', 'log', 'log10', 'log1p'] if environment.version_info.major >= 3: expected.append('log2') - completions = script.completions(fuzzy=True) + completions = script.complete(fuzzy=True) assert expected == [comp.name for comp in completions] for c in completions: assert c.complete is None @@ -341,7 +341,7 @@ def test_file_fuzzy_completion(Script): path = os.path.join(test_dir, 'completion') script = Script('"{}/ep08_i'.format(path)) assert ['pep0484_basic.py"', 'pep0484_typing.py"'] \ - == [comp.name for comp in script.completions(fuzzy=True)] + == [comp.name for comp in script.complete(fuzzy=True)] @pytest.mark.parametrize( @@ -355,6 +355,14 @@ def test_file_fuzzy_completion(Script): ] ) def test_goto_on_string(Script, code, column): - script = Script(code, column=column) - assert not script.goto_definitions() - assert not script.goto_assignments() + script = Script(code) + assert not script.infer(column=column) + assert not script.goto(column=column) + + +def test_multi_goto(Script): + script = Script('x = 1\ny = 1.0\nx\ny') + x, = script.goto(line=3) + y, = script.goto(line=4) + assert x.line == 1 + assert y.line == 2 diff --git a/test/test_api/test_api_classes_follow_definition.py b/test/test_api/test_api_classes_follow_definition.py index d05f4528..83ed1c95 100644 --- a/test/test_api/test_api_classes_follow_definition.py +++ b/test/test_api/test_api_classes_follow_definition.py @@ -6,14 +6,14 @@ from ..helpers import cwd_at def test_import_empty(Script): """ github #340, return the full word. """ - completion = Script("import ").completions()[0] + completion = Script("import ").complete()[0] definition = completion.infer()[0] assert definition def check_follow_definition_types(Script, source): # nested import - completions = Script(source, path='some_path.py').completions() + completions = Script(source, path='some_path.py').complete() defs = chain.from_iterable(c.infer() for c in completions) return [d.type for d in defs] @@ -27,7 +27,7 @@ def test_follow_import_incomplete(Script, environment): assert datetime == ['module'] # empty `from * import` parts - itert = jedi.Script("from itertools import ").completions() + itert = jedi.Script("from itertools import ").complete() definitions = [d for d in itert if d.name == 'chain'] assert len(definitions) == 1 assert [d.type for d in definitions[0].infer()] == ['class'] diff --git a/test/test_api/test_call_signatures.py b/test/test_api/test_call_signatures.py index ff797452..3e773883 100644 --- a/test/test_api/test_call_signatures.py +++ b/test/test_api/test_call_signatures.py @@ -6,12 +6,12 @@ import pytest from ..helpers import TestCase from jedi import cache -from jedi.parser_utils import get_call_signature +from jedi.parser_utils import get_signature from jedi import Interpreter def assert_signature(Script, source, expected_name, expected_index=0, line=None, column=None): - signatures = Script(source, line, column).call_signatures() + signatures = Script(source).find_signatures(line, column) assert len(signatures) <= 1 @@ -28,7 +28,7 @@ def test_valid_call(Script): assert_signature(Script, 'bool()', 'bool', column=5) -class TestCallSignatures(TestCase): +class TestSignatures(TestCase): @pytest.fixture(autouse=True) def init(self, Script): self.Script = Script @@ -96,12 +96,12 @@ class TestCallSignatures(TestCase): def test_with(Script): # jedi-vim #9 - sigs = Script("with open(").call_signatures() + sigs = Script("with open(").find_signatures() assert sigs assert all(sig.name == 'open' for sig in sigs) -def test_call_signatures_empty_parentheses_pre_space(Script): +def test_find_signatures_empty_parentheses_pre_space(Script): s = dedent("""\ def f(a, b): pass @@ -118,10 +118,10 @@ def test_multiple_signatures(Script): def f(a, b): pass f(""") - assert len(Script(s).call_signatures()) == 2 + assert len(Script(s).find_signatures()) == 2 -def test_call_signatures_whitespace(Script): +def test_find_signatures_whitespace(Script): s = dedent("""\ abs( def x(): @@ -148,7 +148,7 @@ def test_decorator_in_class(Script): C().test(""") - signatures = Script(s).call_signatures() + signatures = Script(s).find_signatures() assert len(signatures) == 1 x = [p.description for p in signatures[0].params] assert x == ['param *args'] @@ -176,14 +176,14 @@ def test_brackets_in_string_literals(Script): def test_function_definitions_should_break(Script): """ Function definitions (and other tokens that cannot exist within call - signatures) should break and not be able to return a call signature. + signatures) should break and not be able to return a signature. """ assert_signature(Script, 'abs(\ndef x', 'abs', 0) - assert not Script('abs(\ndef x(): pass').call_signatures() + assert not Script('abs(\ndef x(): pass').find_signatures() def test_flow_call(Script): - assert not Script('if (1').call_signatures() + assert not Script('if (1').find_signatures() def test_chained_calls(Script): @@ -209,11 +209,11 @@ def test_return(Script): assert_signature(Script, source, 'join', 0, column=len(" return '.'.join(")) -def test_call_signature_on_module(Script): +def test_find_signature_on_module(Script): """github issue #240""" s = 'import datetime; datetime(' # just don't throw an exception (if numpy doesn't exist, just ignore it) - assert Script(s).call_signatures() == [] + assert Script(s).find_signatures() == [] def test_complex(Script, environment): @@ -234,7 +234,7 @@ def test_complex(Script, environment): re.compile( return it * 2 """ - sig1, sig2 = sorted(Script(s, line=4, column=27).call_signatures(), key=lambda s: s.line) + sig1, sig2 = sorted(Script(s).find_signatures(line=4, column=27), key=lambda s: s.line) assert sig1.name == sig2.name == 'compile' assert sig1.index == sig2.index == 0 func1, = sig1._name.infer() @@ -243,14 +243,14 @@ def test_complex(Script, environment): if environment.version_info.major == 3: # Do these checks just for Python 3, I'm too lazy to deal with this # legacy stuff. ~ dave. - assert get_call_signature(func1.tree_node) \ + assert get_signature(func1.tree_node) \ == 'compile(pattern: AnyStr, flags: _FlagsType = ...) -> Pattern[AnyStr]' - assert get_call_signature(func2.tree_node) \ + assert get_signature(func2.tree_node) \ == 'compile(pattern: Pattern[AnyStr], flags: _FlagsType = ...) ->\nPattern[AnyStr]' # jedi-vim #70 s = """def foo(""" - assert Script(s).call_signatures() == [] + assert Script(s).find_signatures() == [] # jedi-vim #116 s = """import itertools; test = getattr(itertools, 'chain'); test(""" @@ -258,13 +258,13 @@ def test_complex(Script, environment): def _params(Script, source, line=None, column=None): - signatures = Script(source, line, column).call_signatures() + signatures = Script(source, line, column).find_signatures() assert len(signatures) == 1 return signatures[0].params def test_int_params(Script): - sig1, sig2 = Script('int(').call_signatures() + sig1, sig2 = Script('int(').find_signatures() # int is defined as: `int(x[, base])` assert len(sig1.params) == 1 assert sig1.params[0].name == 'x' @@ -275,13 +275,13 @@ def test_int_params(Script): def test_pow_params(Script): # See Github #1357. - for sig in Script('pow(').call_signatures(): + for sig in Script('pow(').find_signatures(): param_names = [p.name for p in sig.params] assert param_names in (['x', 'y'], ['x', 'y', 'z']) def test_param_name(Script): - sigs = Script('open(something,').call_signatures() + sigs = Script('open(something,').find_signatures() for sig in sigs: # All of the signatures (in Python the function is overloaded), # contain the same param names. @@ -304,19 +304,19 @@ def test_builtins(Script): def test_signature_is_definition(Script): """ - Through inheritance, a call signature is a sub class of Definition. + Through inheritance, a signature is a sub class of Definition. Check if the attributes match. """ s = """class Spam(): pass\nSpam""" - signature = Script(s + '(').call_signatures()[0] - definition = Script(s + '(', column=0).goto_definitions()[0] + signature = Script(s + '(').find_signatures()[0] + definition = Script(s + '(').infer(column=0)[0] signature.line == 1 signature.column == 6 - # Now compare all the attributes that a CallSignature must also have. + # Now compare all the attributes that a Signature must also have. for attr_name in dir(definition): dont_scan = ['defined_names', 'parent', 'goto_assignments', 'infer', - 'params', 'get_signatures', 'execute'] + 'params', 'get_signatures', 'execute', 'goto'] if attr_name.startswith('_') or attr_name in dont_scan: continue @@ -330,15 +330,15 @@ def test_signature_is_definition(Script): def test_no_signature(Script): # str doesn't have a __call__ method - assert Script('str()(').call_signatures() == [] + assert Script('str()(').find_signatures() == [] s = dedent("""\ class X(): pass X()(""") - assert Script(s).call_signatures() == [] - assert len(Script(s, column=2).call_signatures()) == 1 - assert Script('').call_signatures() == [] + assert Script(s).find_signatures() == [] + assert len(Script(s).find_signatures(column=2)) == 1 + assert Script('').find_signatures() == [] def test_dict_literal_in_incomplete_call(Script): @@ -354,24 +354,24 @@ def test_dict_literal_in_incomplete_call(Script): c = Foo() """ - script = Script(dedent(source), line=4, column=15) - assert script.call_signatures() + script = Script(dedent(source)) + assert script.find_signatures(line=4, column=15) def test_completion_interference(Script): """Seems to cause problems, see also #396.""" cache.parser_cache.pop(None, None) - assert Script('open(').call_signatures() + assert Script('open(').find_signatures() - # complete something usual, before doing the same call_signatures again. - assert Script('from datetime import ').completions() + # complete something usual, before doing the same find_signatures again. + assert Script('from datetime import ').complete() - assert Script('open(').call_signatures() + assert Script('open(').find_signatures() def test_keyword_argument_index(Script, environment): def get(source, column=None): - return Script(source, column=column).call_signatures()[0] + return Script(source).find_signatures(column=column)[0] # The signature of sorted changed from 2 to 3. py2_offset = int(environment.version_info.major == 2) @@ -509,7 +509,7 @@ def test_signature_index(skip_python2, Script, environment, code, call, expected if environment.version_info < (3, 8): code = code.replace('/,', '') - sig, = Script(code + '\n' + call + ending, column=len(call)).call_signatures() + sig, = Script(code + '\n' + call + ending).find_signatures(column=len(call)) index = sig.index assert expected_index == index @@ -547,14 +547,14 @@ def test_arg_defaults(Script, environment, code): yield Interpreter(code + '2(', namespaces=[executed_locals]) for script in iter_scripts(): - signatures = script.call_signatures() + signatures = script.find_signatures() assert signatures[0].params[0].description in ('param arg="bla"', "param arg='bla'") assert signatures[0].params[1].description == 'param arg1=1' def test_bracket_start(Script): def bracket_start(src): - signatures = Script(src).call_signatures() + signatures = Script(src).find_signatures() assert len(signatures) == 1 return signatures[0].bracket_start @@ -564,7 +564,7 @@ def test_bracket_start(Script): def test_different_caller(Script): """ It's possible to not use names, but another function result or an array - index and then get the call signature of it. + index and then get the signature of it. """ assert_signature(Script, '[abs][0](', 'abs', 0) @@ -579,14 +579,14 @@ def test_in_function(Script): class X(): @property def func(''') - assert not Script(code).call_signatures() + assert not Script(code).find_signatures() def test_lambda_params(Script): code = dedent('''\ my_lambda = lambda x: x+1 my_lambda(1)''') - sig, = Script(code, column=11).call_signatures() + sig, = Script(code).find_signatures(column=11) assert sig.index == 0 assert sig.name == '' assert [p.name for p in sig.params] == ['x'] @@ -601,19 +601,19 @@ class X(): def test_class_creation(Script): - sig, = Script(CLASS_CODE + 'X(').call_signatures() + sig, = Script(CLASS_CODE + 'X(').find_signatures() assert sig.index == 0 assert sig.name == 'X' assert [p.name for p in sig.params] == ['foo', 'bar'] def test_call_init_on_class(Script): - sig, = Script(CLASS_CODE + 'X.__init__(').call_signatures() + sig, = Script(CLASS_CODE + 'X.__init__(').find_signatures() assert [p.name for p in sig.params] == ['self', 'foo', 'bar'] def test_call_init_on_instance(Script): - sig, = Script(CLASS_CODE + 'X().__init__(').call_signatures() + sig, = Script(CLASS_CODE + 'X().__init__(').find_signatures() assert [p.name for p in sig.params] == ['foo', 'bar'] @@ -623,14 +623,14 @@ def test_call_magic_method(Script): def __call__(self, baz): pass ''') - sig, = Script(code + 'X()(').call_signatures() + sig, = Script(code + 'X()(').find_signatures() assert sig.index == 0 assert sig.name == 'X' assert [p.name for p in sig.params] == ['baz'] - sig, = Script(code + 'X.__call__(').call_signatures() + sig, = Script(code + 'X.__call__(').find_signatures() assert [p.name for p in sig.params] == ['self', 'baz'] - sig, = Script(code + 'X().__call__(').call_signatures() + sig, = Script(code + 'X().__call__(').find_signatures() assert [p.name for p in sig.params] == ['baz'] @@ -642,9 +642,9 @@ def test_cursor_after_signature(Script, column): foo() # _ """) - script = Script(source, 4, column) + script = Script(source) - assert not script.call_signatures() + assert not script.find_signatures(4, column) @pytest.mark.parametrize( @@ -661,7 +661,7 @@ def test_cursor_after_signature(Script, column): ] ) def test_base_signatures(Script, code, line, column, name, index): - sig, = Script(code, line=line, column=column).call_signatures() + sig, = Script(code).find_signatures(line=line, column=column) assert sig.name == name assert sig.index == index diff --git a/test/test_api/test_classes.py b/test/test_api/test_classes.py index 086eceab..7251426e 100644 --- a/test/test_api/test_classes.py +++ b/test/test_api/test_classes.py @@ -14,7 +14,7 @@ from ..helpers import get_example_dir def test_is_keyword(Script): - results = Script('str', 1, 1, None).goto_definitions() + results = Script('str', path=None).infer(1, 1) assert len(results) == 1 and results[0].is_keyword is False @@ -48,15 +48,15 @@ def test_basedefinition_type(Script, names): source += dedent(""" variable = sys or C or x or f or g or g() or h""") lines = source.splitlines() - script = Script(source, len(lines), len('variable'), None) - definitions += script.goto_definitions() + script = Script(source, path=None) + definitions += script.infer(len(lines), len('variable')) - script2 = Script(source, 4, len('class C'), None) - definitions += script2.usages() + script2 = Script(source, path=None) + definitions += script2.find_references(4, len('class C')) source_param = "def f(a): return a" - script_param = Script(source_param, 1, len(source_param), None) - definitions += script_param.goto_assignments() + script_param = Script(source_param, path=None) + definitions += script_param.goto(1, len(source_param)) return definitions @@ -88,15 +88,15 @@ def test_basedefinition_type(Script, names): ) def test_basedefinition_type_import(Script, src, expected_result, column): - types = {t.type for t in Script(src, column=column).completions()} + types = {t.type for t in Script(src).complete(column=column)} assert types == {expected_result} -def test_function_call_signature_in_doc(Script): +def test_function_signature_in_doc(Script): defs = Script(""" def f(x, y=1, z='a'): pass - f""").goto_definitions() + f""").infer() doc = defs[0].docstring() assert "f(x, y=1, z='a')" in str(doc) @@ -107,18 +107,18 @@ def test_param_docstring(names): assert param.docstring() == '' -def test_class_call_signature(Script): +def test_class_signature(Script): defs = Script(""" class Foo: def __init__(self, x, y=1, z='a'): pass - Foo""").goto_definitions() + Foo""").infer() doc = defs[0].docstring() assert doc == "Foo(x, y=1, z='a')" def test_position_none_if_builtin(Script): - gotos = Script('import sys; sys.path').goto_assignments() + gotos = Script('import sys; sys.path').goto() assert gotos[0].in_builtin_module() assert gotos[0].line is not None assert gotos[0].column is not None @@ -129,10 +129,10 @@ def test_completion_docstring(Script, jedi_path): Jedi should follow imports in certain conditions """ def docstr(src, result): - c = Script(src, sys_path=[jedi_path]).completions()[0] + c = Script(src, sys_path=[jedi_path]).complete()[0] assert c.docstring(raw=True, fast=False) == cleandoc(result) - c = Script('import jedi\njed', sys_path=[jedi_path]).completions()[0] + c = Script('import jedi\njed', sys_path=[jedi_path]).complete()[0] assert c.docstring(fast=False) == cleandoc(jedi_doc) docstr('import jedi\njedi.Scr', cleandoc(jedi.Script.__doc__)) @@ -174,12 +174,12 @@ def test_completion_docstring(Script, jedi_path): def test_completion_params(Script): - c = Script('import string; string.capwords').completions()[0] + c = Script('import string; string.capwords').complete()[0] assert [p.name for p in c.params] == ['s', 'sep'] def test_functions_should_have_params(Script): - for c in Script('bool.').completions(): + for c in Script('bool.').complete(): if c.type == 'function': assert isinstance(c.params, list) @@ -189,7 +189,7 @@ def test_hashlib_params(Script, environment): pytest.skip() script = Script(source='from hashlib import sha256') - c, = script.completions() + c, = script.complete() assert [p.name for p in c.params] == ['arg'] @@ -204,10 +204,10 @@ def test_signature_params(Script): pass foo''') - check(Script(s).goto_definitions()) + check(Script(s).infer()) - check(Script(s).goto_assignments()) - check(Script(s + '\nbar=foo\nbar').goto_assignments()) + check(Script(s).goto()) + check(Script(s + '\nbar=foo\nbar').goto()) def test_param_endings(Script): @@ -215,7 +215,7 @@ def test_param_endings(Script): Params should be represented without the comma and whitespace they have around them. """ - sig = Script('def x(a, b=5, c=""): pass\n x(').call_signatures()[0] + sig = Script('def x(a, b=5, c=""): pass\n x(').find_signatures()[0] assert [p.description for p in sig.params] == ['param a', 'param b=5', 'param c=""'] @@ -253,7 +253,7 @@ def test_is_definition_import(names, code, expected): def test_parent(Script): def _parent(source, line=None, column=None): - def_, = Script(dedent(source), line, column).goto_assignments() + def_, = Script(dedent(source)).goto(line, column) return def_.parent() parent = _parent('foo=1\nfoo') @@ -270,7 +270,7 @@ def test_parent(Script): def test_parent_on_function(Script): code = 'def spam():\n pass' - def_, = Script(code, line=1, column=len('def spam')).goto_assignments() + def_, = Script(code).goto(line=1, column=len('def spam')) parent = def_.parent() assert parent.name == '' assert parent.type == 'module' @@ -280,20 +280,20 @@ def test_parent_on_completion(Script): parent = Script(dedent('''\ class Foo(): def bar(): pass - Foo().bar''')).completions()[0].parent() + Foo().bar''')).complete()[0].parent() assert parent.name == 'Foo' assert parent.type == 'class' - parent = Script('str.join').completions()[0].parent() + parent = Script('str.join').complete()[0].parent() assert parent.name == 'str' assert parent.type == 'class' -def test_parent_on_comprehension(): - ns = jedi.names('''\ +def test_parent_on_comprehension(Script): + ns = Script('''\ def spam(): return [i for i in range(5)] - ''', all_scopes=True) + ''').names(all_scopes=True) assert [name.name for name in ns] == ['spam', 'i'] @@ -304,17 +304,17 @@ def test_parent_on_comprehension(): def test_type(Script): - for c in Script('a = [str()]; a[0].').completions(): + for c in Script('a = [str()]; a[0].').complete(): if c.name == '__class__' and False: # TODO fix. assert c.type == 'class' else: assert c.type in ('function', 'statement') - for c in Script('list.').completions(): + for c in Script('list.').complete(): assert c.type # Github issue #397, type should never raise an error. - for c in Script('import os; os.path.').completions(): + for c in Script('import os; os.path.').complete(): assert c.type @@ -322,36 +322,36 @@ def test_type_II(Script): """ GitHub Issue #833, `keyword`s are seen as `module`s """ - for c in Script('f').completions(): + for c in Script('f').complete(): if c.name == 'for': assert c.type == 'keyword' """ -This tests the BaseDefinition.goto_assignments function, not the jedi +This tests the BaseDefinition.goto function, not the jedi function. They are not really different in functionality, but really different as an implementation. """ -def test_goto_assignment_repetition(names): +def test_goto_repetition(names): defs = names('a = 1; a', references=True, definitions=False) # Repeat on the same variable. Shouldn't change once we're on a # definition. for _ in range(3): assert len(defs) == 1 - ass = defs[0].goto_assignments() + ass = defs[0].goto() assert ass[0].description == 'a = 1' -def test_goto_assignments_named_params(names): +def test_goto_named_params(names): src = """\ def foo(a=1, bar=2): pass foo(bar=1) """ bar = names(dedent(src), references=True)[-1] - param = bar.goto_assignments()[0] + param = bar.goto()[0] assert (param.line, param.column) == (1, 13) assert param.type == 'param' @@ -360,46 +360,46 @@ def test_class_call(names): src = 'from threading import Thread; Thread(group=1)' n = names(src, references=True)[-1] assert n.name == 'group' - param_def = n.goto_assignments()[0] + param_def = n.goto()[0] assert param_def.name == 'group' assert param_def.type == 'param' def test_parentheses(names): n = names('("").upper', references=True)[-1] - assert n.goto_assignments()[0].name == 'upper' + assert n.goto()[0].name == 'upper' def test_import(names): nms = names('from json import load', references=True) assert nms[0].name == 'json' assert nms[0].type == 'module' - n = nms[0].goto_assignments()[0] + n = nms[0].goto()[0] assert n.name == 'json' assert n.type == 'module' assert nms[1].name == 'load' assert nms[1].type == 'function' - n = nms[1].goto_assignments()[0] + n = nms[1].goto()[0] assert n.name == 'load' assert n.type == 'function' nms = names('import os; os.path', references=True) assert nms[0].name == 'os' assert nms[0].type == 'module' - n = nms[0].goto_assignments()[0] + n = nms[0].goto()[0] assert n.name == 'os' assert n.type == 'module' - n = nms[2].goto_assignments()[0] + n = nms[2].goto()[0] assert n.name == 'path' assert n.type == 'module' nms = names('import os.path', references=True) - n = nms[0].goto_assignments()[0] + n = nms[0].goto()[0] assert n.name == 'os' assert n.type == 'module' - n = nms[1].goto_assignments()[0] + n = nms[1].goto()[0] # This is very special, normally the name doesn't chance, but since # os.path is a sys.modules hack, it does. assert n.name in ('macpath', 'ntpath', 'posixpath', 'os2emxpath') @@ -411,7 +411,7 @@ def test_import_alias(names): assert nms[0].name == 'json' assert nms[0].type == 'module' assert nms[0]._name.tree_name.parent.type == 'dotted_as_name' - n = nms[0].goto_assignments()[0] + n = nms[0].goto()[0] assert n.name == 'json' assert n.type == 'module' assert n._name._value.tree_node.type == 'file_input' @@ -419,7 +419,7 @@ def test_import_alias(names): assert nms[1].name == 'foo' assert nms[1].type == 'module' assert nms[1]._name.tree_name.parent.type == 'dotted_as_name' - ass = nms[1].goto_assignments() + ass = nms[1].goto() assert len(ass) == 1 assert ass[0].name == 'json' assert ass[0].type == 'module' @@ -432,7 +432,7 @@ def test_added_equals_to_params(Script): def foo(bar, baz): pass """) - results = Script(source + rest_source).completions() + results = Script(source + rest_source).complete() assert len(results) == 1 return results[0] @@ -451,7 +451,7 @@ def test_builtin_module_with_path(Script): a path or not. It shouldn't have a module_path, because that is just confusing. """ - semlock, = Script('from _multiprocessing import SemLock').goto_definitions() + semlock, = Script('from _multiprocessing import SemLock').infer() assert isinstance(semlock._name, CompiledValueName) assert semlock.module_path is None assert semlock.in_builtin_module() is True @@ -468,7 +468,7 @@ def test_builtin_module_with_path(Script): ] ) def test_execute(Script, code, description): - definition, = Script(code).goto_assignments() + definition, = Script(code).goto() definitions = definition.execute() if description is None: assert not definitions @@ -477,7 +477,7 @@ def test_execute(Script, code, description): assert d.description == description -@pytest.mark.parametrize('goto_assignment', [False, True, None]) +@pytest.mark.parametrize('goto', [False, True, None]) @pytest.mark.parametrize( 'code, name, file_name', [ ('from pkg import Foo; Foo.foo', 'foo', '__init__.py'), @@ -485,15 +485,15 @@ def test_execute(Script, code, description): ('from pkg import Foo; Foo.bar', 'bar', 'module.py'), ('from pkg import Foo; Foo().bar', 'bar', 'module.py'), ]) -def test_inheritance_module_path(Script, goto_assignment, code, name, file_name): +def test_inheritance_module_path(Script, goto, code, name, file_name): base_path = os.path.join(get_example_dir('inheritance'), 'pkg') whatever_path = os.path.join(base_path, 'NOT_EXISTING.py') script = Script(code, path=whatever_path) - if goto_assignment is None: - func, = script.goto_definitions() + if goto is None: + func, = script.infer() else: - func, = script.goto_assignments(follow_imports=goto_assignment) + func, = script.goto(follow_imports=goto) assert func.type == 'function' assert func.name == name assert func.module_path == os.path.join(base_path, file_name) diff --git a/test/test_api/test_completion.py b/test/test_api/test_completion.py index 7c9f3ab2..039b28cd 100644 --- a/test/test_api/test_completion.py +++ b/test/test_api/test_completion.py @@ -4,14 +4,16 @@ import sys from textwrap import dedent import pytest + from ..helpers import root_dir +from jedi.api.helpers import start_match, fuzzy_match def test_in_whitespace(Script): code = dedent(''' def x(): pass''') - assert len(Script(code, column=2).completions()) > 20 + assert len(Script(code).complete(column=2)) > 20 def test_empty_init(Script): @@ -19,7 +21,7 @@ def test_empty_init(Script): code = dedent('''\ class X(object): pass X(''') - assert Script(code).completions() + assert Script(code).complete() def test_in_empty_space(Script): @@ -28,7 +30,7 @@ def test_in_empty_space(Script): def __init__(self): hello ''') - comps = Script(code, 3, 7).completions() + comps = Script(code).complete(3, 7) self, = [c for c in comps if c.name == 'self'] assert self.name == 'self' def_, = self.infer() @@ -41,13 +43,13 @@ def test_indent_value(Script): complete. """ code = 'if 1:\nisinstanc' - comp, = Script(code).completions() + comp, = Script(code).complete() assert comp.name == 'isinstance' def test_keyword_value(Script): def get_names(*args, **kwargs): - return [d.name for d in Script(*args, **kwargs).completions()] + return [d.name for d in Script(*args, **kwargs).complete()] names = get_names('if 1:\n pass\n') assert 'if' in names @@ -56,7 +58,7 @@ def test_keyword_value(Script): def test_os_nowait(Script): """ github issue #45 """ - s = Script("import os; os.P_").completions() + s = Script("import os; os.P_").complete() assert 'P_NOWAIT' in [i.name for i in s] @@ -64,7 +66,7 @@ def test_points_in_completion(Script): """At some point, points were inserted into the completions, this caused problems, sometimes. """ - c = Script("if IndentationErr").completions() + c = Script("if IndentationErr").complete() assert c[0].name == 'IndentationError' assert c[0].complete == 'or' @@ -80,9 +82,8 @@ def test_loading_unicode_files_with_bad_global_charset(Script, monkeypatch, tmpd with open(filename1, "wb") as f: f.write(data) - s = Script("from test1 import foo\nfoo.", - line=2, column=4, path=filename2) - s.completions() + s = Script("from test1 import foo\nfoo.", path=filename2) + s.complete(line=2, column=4) def test_fake_subnodes(Script): @@ -100,7 +101,7 @@ def test_fake_subnodes(Script): return c limit = None for i in range(2): - completions = Script('').completions() + completions = Script('').complete() c = get_str_completion(completions) str_value, = c._name.infer() n = len(str_value.tree_node.children[-1].children) @@ -116,17 +117,17 @@ def test_generator(Script): s = "def abc():\n" \ " yield 1\n" \ "abc()." - assert Script(s).completions() + assert Script(s).complete() def test_in_comment(Script): - assert Script(" # Comment").completions() + assert Script(" # Comment").complete() # TODO this is a bit ugly, that the behaviors in comments are different. - assert not Script("max_attr_value = int(2) # Cast to int for spe").completions() + assert not Script("max_attr_value = int(2) # Cast to int for spe").complete() def test_in_comment_before_string(Script): - assert not Script(" # Foo\n'asdf'", line=1).completions() + assert not Script(" # Foo\n'asdf'").complete(line=1) def test_async(Script, environment): @@ -137,16 +138,15 @@ def test_async(Script, environment): foo = 3 async def x(): hey = 3 - ho''' - ) - comps = Script(code, column=4).completions() + ho''') + comps = Script(code).complete(column=4) names = [c.name for c in comps] assert 'foo' in names assert 'hey' in names def test_with_stmt_error_recovery(Script): - assert Script('with open('') as foo: foo.\na', line=1).completions() + assert Script('with open('') as foo: foo.\na').complete(line=1) @pytest.mark.parametrize( @@ -161,7 +161,7 @@ def test_with_stmt_error_recovery(Script): ) ) def test_keyword_completion(Script, code, has_keywords): - assert has_keywords == any(x.is_keyword for x in Script(code).completions()) + assert has_keywords == any(x.is_keyword for x in Script(code).complete()) f1 = join(root_dir, 'example.py') @@ -187,7 +187,7 @@ current_dirname = os.path.basename(dirname(dirname(dirname(__file__)))) ('test%sexample.py' % se, 'r"test%scomp"' % s, 5, ['t' + s]), ('test%sexample.py' % se, 'r"test%scomp"' % s, 11, ['letion' + s]), ('test%sexample.py' % se, '"%s"' % join('test', 'completion', 'basi'), 21, ['c.py']), - ('example.py', 'rb"'+ join('..', current_dirname, 'tes'), None, ['t' + s]), + ('example.py', 'rb"' + join('..', current_dirname, 'tes'), None, ['t' + s]), # Absolute paths (None, '"' + join(root_dir, 'test', 'test_ca'), None, ['che.py"']), @@ -266,17 +266,17 @@ def test_file_path_completions(Script, file, code, column, expected): line = None if isinstance(column, tuple): line, column = column - comps = Script(code, path=file, line=line, column=column).completions() + comps = Script(code, path=file).complete(line=line, column=column) if expected == "A LOT": assert len(comps) > 100 # This is basically global completions. else: assert [c.complete for c in comps] == expected -from jedi.api.helpers import start_match, fuzzy_match def test_start_match(): assert start_match('Condition', 'C') - + + def test_fuzzy_match(): assert fuzzy_match('Condition', 'i') assert not fuzzy_match('Condition', 'p') diff --git a/test/test_api/test_defined_names.py b/test/test_api/test_defined_names.py index 259e3602..f037ca4b 100644 --- a/test/test_api/test_defined_names.py +++ b/test/test_api/test_defined_names.py @@ -139,12 +139,12 @@ def test_follow_imports(names): def test_names_twice(names): - source = dedent(''' + code = dedent(''' def lol(): pass ''') - defs = names(source=source) + defs = names(code) assert defs[0].defined_names() == [] @@ -166,4 +166,4 @@ def test_no_error(names): assert a.name == 'a' assert b.name == 'b' assert a20.name == 'a' - assert a20.goto_assignments() == [a20] + assert a20.goto() == [a20] diff --git a/test/test_api/test_environment.py b/test/test_api/test_environment.py index 4917341f..ff8687e3 100644 --- a/test/test_api/test_environment.py +++ b/test/test_api/test_environment.py @@ -66,13 +66,13 @@ def test_error_in_environment(inference_state, Script, environment): with pytest.raises(jedi.InternalError): inference_state.compiled_subprocess._test_raise_error(KeyboardInterrupt) # Jedi should still work. - def_, = Script('str').goto_definitions() + def_, = Script('str').infer() assert def_.name == 'str' def test_stdout_in_subprocess(inference_state, Script): inference_state.compiled_subprocess._test_print(stdout='.') - Script('1').goto_definitions() + Script('1').infer() def test_killed_subprocess(inference_state, Script, environment): @@ -83,9 +83,9 @@ def test_killed_subprocess(inference_state, Script, environment): # Since the process was terminated (and nobody knows about it) the first # Jedi call fails. with pytest.raises(jedi.InternalError): - Script('str').goto_definitions() + Script('str').infer() - def_, = Script('str').goto_definitions() + def_, = Script('str').infer() # Jedi should now work again. assert def_.name == 'str' diff --git a/test/test_api/test_full_name.py b/test/test_api/test_full_name.py index 829c1247..bd0469ef 100644 --- a/test/test_api/test_full_name.py +++ b/test/test_api/test_full_name.py @@ -31,7 +31,7 @@ class MixinTestFullName(object): def check(self, source, desired): script = self.Script(textwrap.dedent(source)) - definitions = getattr(script, type(self).operation)() + definitions = getattr(script, self.operation)() for d in definitions: self.assertEqual(d.full_name, desired) @@ -43,7 +43,7 @@ class MixinTestFullName(object): class TestFullNameWithGotoDefinitions(MixinTestFullName, TestCase): - operation = 'goto_definitions' + operation = 'infer' def test_tuple_mapping(self): if self.environment.version_info.major == 2: @@ -59,7 +59,7 @@ class TestFullNameWithGotoDefinitions(MixinTestFullName, TestCase): class TestFullNameWithCompletions(MixinTestFullName, TestCase): - operation = 'completions' + operation = 'complete' class TestFullDefinedName(TestCase): @@ -71,7 +71,8 @@ class TestFullDefinedName(TestCase): self.environment = environment def check(self, source, desired): - definitions = jedi.names(textwrap.dedent(source), environment=self.environment) + script = jedi.Script(textwrap.dedent(source), environment=self.environment) + definitions = script.names() full_names = [d.full_name for d in definitions] self.assertEqual(full_names, desired) @@ -96,19 +97,19 @@ def test_sub_module(Script, jedi_path): path. """ sys_path = [jedi_path] - defs = Script('from jedi.api import classes; classes', sys_path=sys_path).goto_definitions() + defs = Script('from jedi.api import classes; classes', sys_path=sys_path).infer() assert [d.full_name for d in defs] == ['jedi.api.classes'] - defs = Script('import jedi.api; jedi.api', sys_path=sys_path).goto_definitions() + defs = Script('import jedi.api; jedi.api', sys_path=sys_path).infer() assert [d.full_name for d in defs] == ['jedi.api'] def test_os_path(Script): - d, = Script('from os.path import join').completions() + d, = Script('from os.path import join').complete() assert d.full_name == 'os.path.join' - d, = Script('import os.p').completions() + d, = Script('import os.p').complete() assert d.full_name == 'os.path' def test_os_issues(Script): """Issue #873""" - assert [c.name for c in Script('import os\nos.nt''').completions()] == ['nt'] + assert [c.name for c in Script('import os\nos.nt''').complete()] == ['nt'] diff --git a/test/test_api/test_interpreter.py b/test/test_api/test_interpreter.py index e4d396ca..8b5343be 100644 --- a/test/test_api/test_interpreter.py +++ b/test/test_api/test_interpreter.py @@ -26,7 +26,7 @@ class _GlobalNameSpace: def get_completion(source, namespace): i = jedi.Interpreter(source, [namespace]) - completions = i.completions() + completions = i.complete() assert len(completions) == 1 return completions[0] @@ -111,7 +111,7 @@ def test_side_effect_completion(): def _assert_interpreter_complete(source, namespace, completions, **kwds): script = jedi.Interpreter(source, [namespace], **kwds) - cs = script.completions() + cs = script.complete() actual = [c.name for c in cs] assert sorted(actual) == sorted(completions) @@ -298,7 +298,7 @@ def test_property_content(): return 1 foo = Foo3() - def_, = jedi.Interpreter('foo.bar', [locals()]).goto_definitions() + def_, = jedi.Interpreter('foo.bar', [locals()]).infer() assert def_.name == 'int' @@ -310,7 +310,7 @@ def test_param_completion(): lambd = lambda xyz: 3 _assert_interpreter_complete('foo(bar', locals(), ['bar']) - assert bool(jedi.Interpreter('lambd(xyz', [locals()]).completions()) == is_py3 + assert bool(jedi.Interpreter('lambd(xyz', [locals()]).complete()) == is_py3 def test_endless_yield(): @@ -325,7 +325,7 @@ def test_completion_params(): foo = lambda a, b=3: None script = jedi.Interpreter('foo', [locals()]) - c, = script.completions() + c, = script.complete() assert [p.name for p in c.params] == ['a', 'b'] assert c.params[0].infer() == [] t, = c.params[1].infer() @@ -339,13 +339,13 @@ def test_completion_param_annotations(): code = 'def foo(a: 1, b: str, c: int = 1.0) -> bytes: pass' exec_(code, locals()) script = jedi.Interpreter('foo', [locals()]) - c, = script.completions() + c, = script.complete() a, b, c = c.params assert a.infer() == [] assert [d.name for d in b.infer()] == ['str'] assert {d.name for d in c.infer()} == {'int', 'float'} - d, = jedi.Interpreter('foo()', [locals()]).goto_definitions() + d, = jedi.Interpreter('foo()', [locals()]).infer() assert d.name == 'bytes' @@ -354,7 +354,7 @@ def test_keyword_argument(): def f(some_keyword_argument): pass - c, = jedi.Interpreter("f(some_keyw", [{'f': f}]).completions() + c, = jedi.Interpreter("f(some_keyw", [{'f': f}]).complete() assert c.name == 'some_keyword_argument' assert c.complete == 'ord_argument=' @@ -362,7 +362,7 @@ def test_keyword_argument(): if is_py3: # Make it impossible for jedi to find the source of the function. f.__name__ = 'xSOMETHING' - c, = jedi.Interpreter("x(some_keyw", [{'x': f}]).completions() + c, = jedi.Interpreter("x(some_keyw", [{'x': f}]).complete() assert c.name == 'some_keyword_argument' @@ -376,12 +376,12 @@ def test_more_complex_instances(): return Something() #script = jedi.Interpreter('Base().wow().foo', [locals()]) - #c, = script.completions() + #c, = script.complete() #assert c.name == 'foo' x = Base() script = jedi.Interpreter('x.wow().foo', [locals()]) - c, = script.completions() + c, = script.complete() assert c.name == 'foo' @@ -397,7 +397,7 @@ def test_repr_execution_issue(): er = ErrorRepr() script = jedi.Interpreter('er', [locals()]) - d, = script.goto_definitions() + d, = script.infer() assert d.name == 'ErrorRepr' assert d.type == 'instance' @@ -419,7 +419,7 @@ def test_dir_magic_method(allow_unsafe_getattr): return ['foo', 'bar'] + names itp = jedi.Interpreter("ca.", [{'ca': CompleteAttrs()}]) - completions = itp.completions() + completions = itp.complete() names = [c.name for c in completions] assert ('__dir__' in names) == is_py3 assert '__class__' in names @@ -447,19 +447,19 @@ def test_name_not_findable(): setattr(X, 'NOT_FINDABLE', X.hidden) - assert jedi.Interpreter("X.NOT_FINDA", [locals()]).completions() + assert jedi.Interpreter("X.NOT_FINDA", [locals()]).complete() def test_stubs_working(): from multiprocessing import cpu_count - defs = jedi.Interpreter("cpu_count()", [locals()]).goto_definitions() + defs = jedi.Interpreter("cpu_count()", [locals()]).infer() assert [d.name for d in defs] == ['int'] def test_sys_path_docstring(): # Was an issue in #1298 import jedi - s = jedi.Interpreter("from sys import path\npath", line=2, column=4, namespaces=[locals()]) - s.completions()[0].docstring() + s = jedi.Interpreter("from sys import path\npath", namespaces=[locals()]) + s.complete(line=2, column=4)[0].docstring() @pytest.mark.skipif(sys.version_info[0] == 2, reason="Ignore Python 2, because EOL") @@ -504,7 +504,7 @@ def test_simple_completions(code, completions): counter = collections.Counter(['asdf']) string = '' - defs = jedi.Interpreter(code, [locals()]).completions() + defs = jedi.Interpreter(code, [locals()]).complete() assert [d.name for d in defs] == completions @@ -516,7 +516,7 @@ def test__wrapped__(): def syslogs_to_df(): pass - c, = jedi.Interpreter('syslogs_to_df', [locals()]).completions() + c, = jedi.Interpreter('syslogs_to_df', [locals()]).complete() # Apparently the function starts on the line where the decorator starts. assert c.line == syslogs_to_df.__wrapped__.__code__.co_firstlineno + 1 @@ -525,7 +525,7 @@ def test__wrapped__(): @pytest.mark.parametrize('module_name', ['sys', 'time', 'unittest.mock']) def test_core_module_completes(module_name): module = import_module(module_name) - assert jedi.Interpreter('module.', [locals()]).completions() + assert jedi.Interpreter('module.', [locals()]).complete() @pytest.mark.skipif(sys.version_info[0] == 2, reason="Ignore Python 2, because EOL") @@ -548,7 +548,7 @@ def test_partial_signatures(code, expected, index): b = functools.partial(func, 1) c = functools.partial(func, 1, c=2) - sig, = jedi.Interpreter(code, [locals()]).call_signatures() + sig, = jedi.Interpreter(code, [locals()]).find_signatures() assert sig.name == 'partial' assert [p.name for p in sig.params] == expected assert index == sig.index @@ -559,7 +559,7 @@ def test_type_var(): """This was an issue before, see Github #1369""" import typing x = typing.TypeVar('myvar') - def_, = jedi.Interpreter('x', [locals()]).goto_definitions() + def_, = jedi.Interpreter('x', [locals()]).infer() assert def_.name == 'TypeVar' @@ -573,5 +573,5 @@ def test_param_annotation_completion(class_is_findable): Foo.__name__ = 'asdf' code = 'def CallFoo(x: Foo):\n x.ba' - def_, = jedi.Interpreter(code, [locals()]).completions() + def_, = jedi.Interpreter(code, [locals()]).complete() assert def_.name == 'bar' diff --git a/test/test_api/test_keyword.py b/test/test_api/test_keyword.py index 219e3ff8..3e5b9344 100644 --- a/test/test_api/test_keyword.py +++ b/test/test_api/test_keyword.py @@ -5,38 +5,38 @@ Test of keywords and ``jedi.keywords`` import pytest -def test_goto_assignments_keyword(Script): +def test_goto_keyword(Script): """ Bug: goto assignments on ``in`` used to raise AttributeError:: 'unicode' object has no attribute 'generate_call_path' """ - Script('in').goto_assignments() + Script('in').goto() def test_keyword(Script, environment): """ github jedi-vim issue #44 """ - defs = Script("print").goto_definitions() + defs = Script("print").infer() if environment.version_info.major < 3: assert defs == [] else: assert [d.docstring() for d in defs] - assert Script("import").goto_assignments() == [] + assert Script("import").goto() == [] - completions = Script("import", 1, 1).completions() + completions = Script("import").complete(1, 1) assert len(completions) > 10 and 'if' in [c.name for c in completions] - assert Script("assert").goto_definitions() == [] + assert Script("assert").infer() == [] def test_keyword_attributes(Script): - def_, = Script('def').completions() + def_, = Script('def').complete() assert def_.name == 'def' assert def_.complete == '' assert def_.is_keyword is True assert def_.is_stub() is False - assert def_.goto_assignments(only_stubs=True) == [] - assert def_.goto_assignments() == [] + assert def_.goto(only_stubs=True) == [] + assert def_.goto() == [] assert def_.infer() == [] assert def_.parent() is None assert def_.docstring() @@ -55,6 +55,6 @@ def test_none_keyword(Script, environment): # Just don't care about Python 2 anymore, it's almost gone. pytest.skip() - none, = Script('None').completions() + none, = Script('None').complete() assert not none.docstring() assert none.name == 'None' diff --git a/test/test_api/test_project.py b/test/test_api/test_project.py index 6750774a..f8bc8c60 100644 --- a/test/test_api/test_project.py +++ b/test/test_api/test_project.py @@ -11,7 +11,7 @@ def test_django_default_project(Script): "from app import models\nmodels.SomeMo", path=os.path.join(dir, 'models/x.py') ) - c, = script.completions() + c, = script.complete() assert c.name == "SomeModel" assert script._inference_state.project._django is True diff --git a/test/test_api/test_settings.py b/test/test_api/test_settings.py index f6629719..7a9d0c2c 100644 --- a/test/test_api/test_settings.py +++ b/test/test_api/test_settings.py @@ -18,7 +18,7 @@ def test_add_dynamic_mods(Script): src2 = 'from .. import setup; setup.r(1)' script = Script(src1, path='../setup.py') imports.load_module(script._inference_state, os.path.abspath(fname), src2) - result = script.goto_definitions() + result = script.infer() assert len(result) == 1 assert result[0].description == 'class int' @@ -30,5 +30,5 @@ def test_add_bracket_after_function(monkeypatch, Script): def foo(): pass foo''') - completions = script.completions() + completions = script.complete() assert completions[0].complete == '(' diff --git a/test/test_api/test_signatures.py b/test/test_api/test_signatures.py index 93bebb0b..c34504c1 100644 --- a/test/test_api/test_signatures.py +++ b/test/test_api/test_signatures.py @@ -21,7 +21,7 @@ _tuple_code = 'from typing import Tuple\ndef f(x: Tuple[int]): ...\nf' ] ) def test_param_annotation(Script, code, expected_params, execute_annotation, skip_python2): - func, = Script(code).goto_assignments() + func, = Script(code).goto() sig, = func.get_signatures() for p, expected in zip(sig.params, expected_params): annotations = p.infer_annotation(execute_annotation=execute_annotation) @@ -40,7 +40,7 @@ def test_param_annotation(Script, code, expected_params, execute_annotation, ski ] ) def test_param_default(Script, code, expected_params): - func, = Script(code).goto_assignments() + func, = Script(code).goto() sig, = func.get_signatures() for p, expected in zip(sig.params, expected_params): annotations = p.infer_default() @@ -62,7 +62,7 @@ def test_param_default(Script, code, expected_params): ] ) def test_param_kind_and_name(code, index, param_code, kind, Script, skip_python2): - func, = Script(code).goto_assignments() + func, = Script(code).goto() sig, = func.get_signatures() param = sig.params[index] assert param.to_string() == param_code @@ -70,5 +70,5 @@ def test_param_kind_and_name(code, index, param_code, kind, Script, skip_python2 def test_staticmethod(Script): - s, = Script('staticmethod(').call_signatures() + s, = Script('staticmethod(').find_signatures() assert s.to_string() == 'staticmethod(f: Callable[..., Any])' diff --git a/test/test_api/test_unicode.py b/test/test_api/test_unicode.py index 7fd28bb2..015048cd 100644 --- a/test/test_api/test_unicode.py +++ b/test/test_api/test_unicode.py @@ -8,18 +8,18 @@ from jedi._compatibility import u, unicode def test_unicode_script(Script): """ normally no unicode objects are being used. (<=2.7) """ s = unicode("import datetime; datetime.timedelta") - completions = Script(s).completions() + completions = Script(s).complete() assert len(completions) assert type(completions[0].description) is unicode s = u("author='öä'; author") - completions = Script(s).completions() + completions = Script(s).complete() x = completions[0].description assert type(x) is unicode s = u("#-*- coding: iso-8859-1 -*-\nauthor='öä'; author") s = s.encode('latin-1') - completions = Script(s).completions() + completions = Script(s).complete() assert type(completions[0].description) is unicode @@ -27,11 +27,11 @@ def test_unicode_attribute(Script): """ github jedi-vim issue #94 """ s1 = u('#-*- coding: utf-8 -*-\nclass Person():\n' ' name = "e"\n\nPerson().name.') - completions1 = Script(s1).completions() + completions1 = Script(s1).complete() assert 'strip' in [c.name for c in completions1] s2 = u('#-*- coding: utf-8 -*-\nclass Person():\n' ' name = "é"\n\nPerson().name.') - completions2 = Script(s2).completions() + completions2 = Script(s2).complete() assert 'strip' in [c.name for c in completions2] @@ -44,24 +44,24 @@ def test_multibyte_script(Script): except NameError: pass # python 3 has no unicode method else: - assert len(Script(s, 1, len(code)).completions()) + assert len(Script(s).complete(1, len(code))) def test_goto_definition_at_zero(Script): """At zero usually sometimes raises unicode issues.""" - assert Script("a", 1, 1).goto_definitions() == [] - s = Script("str", 1, 1).goto_definitions() + assert Script("a").infer(1, 1) == [] + s = Script("str").infer(1, 1) assert len(s) == 1 assert list(s)[0].description == 'class str' - assert Script("", 1, 0).goto_definitions() == [] + assert Script("").infer(1, 0) == [] def test_complete_at_zero(Script): - s = Script("str", 1, 3).completions() + s = Script("str").complete(1, 3) assert len(s) == 1 assert list(s)[0].name == 'str' - s = Script("", 1, 0).completions() + s = Script("").complete(1, 0) assert len(s) > 0 @@ -70,7 +70,7 @@ def test_wrong_encoding(Script, tmpdir): # Use both latin-1 and utf-8 (a really broken file). x.write_binary(u'foobar = 1\nä'.encode('latin-1') + u'ä'.encode('utf-8')) - c, = Script('import x; x.foo', sys_path=[tmpdir.strpath]).completions() + c, = Script('import x; x.foo', sys_path=[tmpdir.strpath]).complete() assert c.name == 'foobar' diff --git a/test/test_api/test_usages.py b/test/test_api/test_usages.py index 245951b7..30a6581a 100644 --- a/test/test_api/test_usages.py +++ b/test/test_api/test_usages.py @@ -1,11 +1,12 @@ -def test_import_usage(Script): - s = Script("from .. import foo", line=1, column=18, path="foo.py") - assert [usage.line for usage in s.usages()] == [1] +def test_import_references(Script): + s = Script("from .. import foo", path="foo.py") + assert [usage.line for usage in s.find_references(line=1, column=18)] == [1] def test_exclude_builtin_modules(Script): def get(include): - return [(d.line, d.column) for d in Script(source, column=8).usages(include_builtins=include)] + references = Script(source).find_references(column=8, include_builtins=include) + return [(d.line, d.column) for d in references] source = '''import sys\nprint(sys.path)''' places = get(include=True) assert len(places) > 2 # Includes stubs diff --git a/test/test_cache.py b/test/test_cache.py index 79bdefca..ac3e74c7 100644 --- a/test/test_cache.py +++ b/test/test_cache.py @@ -3,12 +3,12 @@ Test all things related to the ``jedi.cache`` module. """ -def test_cache_call_signatures(Script): +def test_cache_find_signatures(Script): """ See github issue #390. """ def check(column, call_name, path=None): - assert Script(s, 1, column, path).call_signatures()[0].name == call_name + assert Script(s, path=path).find_signatures(1, column)[0].name == call_name s = 'str(int())' @@ -26,4 +26,4 @@ def test_cache_call_signatures(Script): def test_cache_line_split_issues(Script): """Should still work even if there's a newline.""" - assert Script('int(\n').call_signatures()[0].name == 'int' + assert Script('int(\n').find_signatures()[0].name == 'int' diff --git a/test/test_deprecation.py b/test/test_deprecation.py new file mode 100644 index 00000000..ed3603e6 --- /dev/null +++ b/test/test_deprecation.py @@ -0,0 +1,27 @@ +def test_goto_definitions(Script): + int_, = Script('x = 1\nx, y\ny', line=2, column=0).goto_definitions() + assert int_.name == 'int' + + +def test_completions(Script): + c1, c2 = Script('foobar = 1\nfoobaz= 2\nfoobaz, ffff\nfool = 3', line=3, column=3).completions() + assert c1.name == 'foobar' + assert c2.name == 'foobaz' + + +def test_goto_assignments(Script): + int_, = Script('x = 1\nx, y\ny', line=2, column=0).goto_assignments() + assert int_.get_line_code() == 'x = 1\n' + + +def test_usages(Script): + d1, d2 = Script('x = 1\nx, y\ny', line=2, column=0).usages() + assert d1.name == 'x' + assert d1.line == 1 + assert d2.name == 'x' + assert d2.line == 2 + + +def test_call_signatures(Script): + d1, = Script('abs(float(\nstr(', line=1, column=4).call_signatures() + assert d1.name == 'abs' diff --git a/test/test_inference/test_absolute_import.py b/test/test_inference/test_absolute_import.py index 1052aa5d..9d3e518d 100644 --- a/test/test_inference/test_absolute_import.py +++ b/test/test_inference/test_absolute_import.py @@ -8,4 +8,4 @@ from .. import helpers @helpers.cwd_at("test/test_inference/absolute_import") def test_can_complete_when_shadowing(Script): script = Script(path="unittest.py") - assert script.completions() + assert script.complete() diff --git a/test/test_inference/test_annotations.py b/test/test_inference/test_annotations.py index dc2d3d71..7940d7db 100644 --- a/test/test_inference/test_annotations.py +++ b/test/test_inference/test_annotations.py @@ -18,7 +18,7 @@ def test_simple_annotations(Script, environment): annot('')""") - assert [d.name for d in Script(source).goto_definitions()] == ['str'] + assert [d.name for d in Script(source).infer()] == ['str'] source = dedent("""\ @@ -26,7 +26,7 @@ def test_simple_annotations(Script, environment): return a annot_ret('')""") - assert [d.name for d in Script(source).goto_definitions()] == ['str'] + assert [d.name for d in Script(source).infer()] == ['str'] source = dedent("""\ def annot(a:int): @@ -34,7 +34,7 @@ def test_simple_annotations(Script, environment): annot('')""") - assert [d.name for d in Script(source).goto_definitions()] == ['int'] + assert [d.name for d in Script(source).infer()] == ['int'] @pytest.mark.parametrize('reference', [ @@ -50,7 +50,7 @@ def test_illegal_forward_references(Script, environment, reference): source = 'def foo(bar: "%s"): bar' % reference - assert not Script(source).goto_definitions() + assert not Script(source).infer() def test_lambda_forward_references(Script, environment): @@ -61,4 +61,4 @@ def test_lambda_forward_references(Script, environment): # For now just receiving the 3 is ok. I'm doubting that this is what we # want. We also execute functions. Should we only execute classes? - assert Script(source).goto_definitions() + assert Script(source).infer() diff --git a/test/test_inference/test_compiled.py b/test/test_inference/test_compiled.py index e6e6991b..39f24c07 100644 --- a/test/test_inference/test_compiled.py +++ b/test/test_inference/test_compiled.py @@ -61,7 +61,7 @@ def test_doc(inference_state): def test_string_literals(Script, environment): def typ(string): - d = Script("a = %s; a" % string).goto_definitions()[0] + d = Script("a = %s; a" % string).infer()[0] return d.name assert typ('""') == 'str' @@ -83,12 +83,12 @@ def test_method_completion(Script, environment): foo = Foo() foo.bar.__func__''') - assert [c.name for c in Script(code).completions()] == ['__func__'] + assert [c.name for c in Script(code).complete()] == ['__func__'] def test_time_docstring(Script): import time - comp, = Script('import time\ntime.sleep').completions() + comp, = Script('import time\ntime.sleep').complete() assert comp.docstring(raw=True) == time.sleep.__doc__ expected = 'sleep(secs: float) -> None\n\n' + time.sleep.__doc__ assert comp.docstring() == expected @@ -98,12 +98,12 @@ def test_dict_values(Script, environment): if environment.version_info.major == 2: # It looks like typeshed for Python 2 returns Any. pytest.skip() - assert Script('import sys\nsys.modules["alshdb;lasdhf"]').goto_definitions() + assert Script('import sys\nsys.modules["alshdb;lasdhf"]').infer() def test_getitem_on_none(Script): script = Script('None[1j]') - assert not script.goto_definitions() + assert not script.infer() issue, = script._inference_state.analysis assert issue.name == 'type-error-not-subscriptable' diff --git a/test/test_inference/test_context.py b/test/test_inference/test_context.py index 7a64014b..9552f633 100644 --- a/test/test_inference/test_context.py +++ b/test/test_inference/test_context.py @@ -2,7 +2,7 @@ from jedi._compatibility import force_unicode def test_module_attributes(Script): - def_, = Script('__name__').completions() + def_, = Script('__name__').complete() assert def_.name == '__name__' assert def_.line is None assert def_.column is None @@ -11,11 +11,11 @@ def test_module_attributes(Script): def test_module__file__(Script, environment): - assert not Script('__file__').goto_definitions() - def_, = Script('__file__', path='example.py').goto_definitions() + assert not Script('__file__').infer() + def_, = Script('__file__', path='example.py').infer() value = force_unicode(def_._name._value.get_safe_value()) assert value.endswith('example.py') - def_, = Script('import antigravity; antigravity.__file__').goto_definitions() + def_, = Script('import antigravity; antigravity.__file__').infer() value = force_unicode(def_._name._value.get_safe_value()) assert value.endswith('.py') diff --git a/test/test_inference/test_docstring.py b/test/test_inference/test_docstring.py index a0ec9b7a..42042c22 100644 --- a/test/test_inference/test_docstring.py +++ b/test/test_inference/test_docstring.py @@ -32,7 +32,7 @@ def test_function_doc(Script): defs = Script(""" def func(): '''Docstring of `func`.''' - func""").goto_definitions() + func""").infer() assert defs[0].docstring() == 'func()\n\nDocstring of `func`.' @@ -40,7 +40,7 @@ def test_class_doc(Script): defs = Script(""" class TestClass(): '''Docstring of `TestClass`.''' - TestClass""").goto_definitions() + TestClass""").infer() expected = 'Docstring of `TestClass`.' assert defs[0].docstring(raw=True) == expected @@ -52,7 +52,7 @@ def test_class_doc_with_init(Script): class TestClass(): '''Docstring''' def __init__(self, foo, bar=3): pass - TestClass""").goto_definitions() + TestClass""").infer() assert d.docstring() == 'TestClass(foo, bar=3)\n\nDocstring' @@ -62,7 +62,7 @@ def test_instance_doc(Script): class TestClass(): '''Docstring of `TestClass`.''' tc = TestClass() - tc""").goto_definitions() + tc""").infer() assert defs[0].docstring() == 'Docstring of `TestClass`.' @@ -71,7 +71,7 @@ def test_attribute_docstring(Script): defs = Script(""" x = None '''Docstring of `x`.''' - x""").goto_definitions() + x""").infer() assert defs[0].docstring() == 'Docstring of `x`.' @@ -82,7 +82,7 @@ def test_multiple_docstrings(Script): '''Original docstring.''' x = func '''Docstring of `x`.''' - x""").goto_definitions() + x""").infer() docs = [d.docstring() for d in defs] assert docs == ['Original docstring.', 'Docstring of `x`.'] @@ -91,7 +91,7 @@ def test_completion(Script): assert Script(''' class DocstringCompletion(): #? [] - """ asdfas """''').completions() + """ asdfas """''').complete() def test_docstrings_type_dotted_import(Script): @@ -101,7 +101,7 @@ def test_docstrings_type_dotted_import(Script): :type arg: random.Random ''' arg.""" - names = [c.name for c in Script(s).completions()] + names = [c.name for c in Script(s).complete()] assert 'seed' in names @@ -112,7 +112,7 @@ def test_docstrings_param_type(Script): :param str arg: some description ''' arg.""" - names = [c.name for c in Script(s).completions()] + names = [c.name for c in Script(s).complete()] assert 'join' in names @@ -124,7 +124,7 @@ def test_docstrings_type_str(Script): ''' arg.""" - names = [c.name for c in Script(s).completions()] + names = [c.name for c in Script(s).complete()] assert 'join' in names @@ -150,14 +150,14 @@ def test_docstring_instance(Script): c.""") - names = [c.name for c in Script(s).completions()] + names = [c.name for c in Script(s).complete()] assert 'a' in names assert '__init__' in names assert 'mro' not in names # Exists only for types. def test_docstring_keyword(Script): - completions = Script('assert').completions() + completions = Script('assert').complete() assert 'assert' in completions[0].docstring() @@ -167,7 +167,7 @@ def test_docstring_params_formatting(Script): param2, param3): pass - func""").goto_definitions() + func""").infer() assert defs[0].docstring() == 'func(param1, param2, param3)' @@ -185,7 +185,7 @@ def test_numpydoc_parameters(): y : str """ y.''') - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'isupper' in names assert 'capitalize' in names @@ -201,7 +201,7 @@ def test_numpydoc_parameters_set_of_values(): x : {'foo', 'bar', 100500}, optional """ x.''') - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'isupper' in names assert 'capitalize' in names assert 'numerator' in names @@ -218,7 +218,7 @@ def test_numpydoc_parameters_alternative_types(): x : int or str or list """ x.''') - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'isupper' in names assert 'capitalize' in names assert 'numerator' in names @@ -237,7 +237,7 @@ def test_numpydoc_invalid(): """ x.''') - assert not jedi.Script(s).completions() + assert not jedi.Script(s).complete() @pytest.mark.skipif(numpydoc_unavailable, @@ -256,7 +256,7 @@ def test_numpydoc_returns(): def bazbiz(): z = foobar() z.''') - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'isupper' in names assert 'capitalize' in names assert 'numerator' in names @@ -277,7 +277,7 @@ def test_numpydoc_returns_set_of_values(): def bazbiz(): z = foobar() z.''') - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'isupper' in names assert 'capitalize' in names assert 'numerator' in names @@ -298,7 +298,7 @@ def test_numpydoc_returns_alternative_types(): def bazbiz(): z = foobar() z.''') - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'isupper' not in names assert 'capitalize' not in names assert 'numerator' in names @@ -320,7 +320,7 @@ def test_numpydoc_returns_list_of(): def bazbiz(): z = foobar() z.''') - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'append' in names assert 'isupper' not in names assert 'capitalize' not in names @@ -342,7 +342,7 @@ def test_numpydoc_returns_obj(): z = foobar(x, y) z.''') script = jedi.Script(s) - names = [c.name for c in script.completions()] + names = [c.name for c in script.complete()] assert 'numerator' in names assert 'seed' in names @@ -363,7 +363,7 @@ def test_numpydoc_yields(): def bazbiz(): z = foobar(): z.''') - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'isupper' in names assert 'capitalize' in names assert 'numerator' in names @@ -377,7 +377,7 @@ def test_numpy_returns(): x = numpy.asarray([]) x.d''' ) - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'diagonal' in names @@ -389,7 +389,7 @@ def test_numpy_comp_returns(): x = numpy.array([]) x.d''' ) - names = [c.name for c in jedi.Script(s).completions()] + names = [c.name for c in jedi.Script(s).complete()] assert 'diagonal' in names @@ -412,7 +412,7 @@ def test_decorator(Script): check_user''') - d, = Script(code).goto_definitions() + d, = Script(code).infer() assert d.docstring(raw=True) == 'Nice docstring' @@ -422,5 +422,5 @@ def test_basic_str_init_signature(Script, disable_typeshed): class Foo(str): pass Foo(''') - c, = Script(code).call_signatures() + c, = Script(code).find_signatures() assert c.name == 'Foo' diff --git a/test/test_inference/test_extension.py b/test/test_inference/test_extension.py index fb7801a3..6f72c4ba 100644 --- a/test/test_inference/test_extension.py +++ b/test/test_inference/test_extension.py @@ -10,10 +10,10 @@ import pytest def test_completions(Script): s = Script('import _ctypes; _ctypes.') - assert len(s.completions()) >= 15 + assert len(s.complete()) >= 15 -def test_call_signatures_extension(Script): +def test_find_signatures_extension(Script): if os.name == 'nt': func = 'LoadLibrary' params = 1 @@ -21,14 +21,14 @@ def test_call_signatures_extension(Script): func = 'dlopen' params = 2 s = Script('import _ctypes; _ctypes.%s(' % (func,)) - sigs = s.call_signatures() + sigs = s.find_signatures() assert len(sigs) == 1 assert len(sigs[0].params) == params -def test_call_signatures_stdlib(Script): +def test_find_signatures_stdlib(Script): s = Script('import math; math.cos(') - sigs = s.call_signatures() + sigs = s.find_signatures() assert len(sigs) == 1 assert len(sigs[0].params) == 1 @@ -51,7 +51,7 @@ def test_init_extension_module(Script): This is also why this test only runs on certain systems (and Python 3.4). """ s = jedi.Script('import init_extension_module as i\ni.', path='not_existing.py') - assert 'foo' in [c.name for c in s.completions()] + assert 'foo' in [c.name for c in s.complete()] s = jedi.Script('from init_extension_module import foo\nfoo', path='not_existing.py') - assert ['foo'] == [c.name for c in s.completions()] + assert ['foo'] == [c.name for c in s.complete()] diff --git a/test/test_inference/test_fstring.py b/test/test_inference/test_fstring.py index 2805e44b..ed303090 100644 --- a/test/test_inference/test_fstring.py +++ b/test/test_inference/test_fstring.py @@ -13,7 +13,6 @@ def test_fstring_multiline(Script): '' f'''s{ str.uppe ''' - """ - ) - c, = Script(code, line=2, column=9).completions() + """) + c, = Script(code).complete(line=2, column=9) assert c.name == 'upper' diff --git a/test/test_inference/test_gradual/test_conversion.py b/test/test_inference/test_gradual/test_conversion.py index 2d0fe5df..1e05e5cc 100644 --- a/test/test_inference/test_gradual/test_conversion.py +++ b/test/test_inference/test_gradual/test_conversion.py @@ -7,18 +7,18 @@ from jedi.inference.gradual.conversion import convert_names def test_sqlite3_conversion(Script): script1 = Script('import sqlite3; sqlite3.Connection') - d, = script1.goto_definitions() + d, = script1.infer() assert not d.module_path assert d.full_name == 'sqlite3.Connection' assert convert_names([d._name], only_stubs=True) - d, = script1.goto_definitions(only_stubs=True) + d, = script1.infer(only_stubs=True) assert d.is_stub() assert d.full_name == 'sqlite3.dbapi2.Connection' - script2 = Script(path=d.module_path, line=d.line, column=d.column) - d, = script2.goto_definitions() + script2 = Script(path=d.module_path) + d, = script2.infer(line=d.line, column=d.column) assert not d.is_stub() assert d.full_name == 'sqlite3.Connection' v, = d._name.infer() @@ -28,11 +28,11 @@ def test_sqlite3_conversion(Script): def test_conversion_of_stub_only(Script): project = Project(os.path.join(root_dir, 'test', 'completion', 'stub_folder')) code = 'import stub_only; stub_only.in_stub_only' - d1, = Script(code, _project=project).goto_assignments() + d1, = Script(code, _project=project).goto() assert d1.is_stub() - script = Script(path=d1.module_path, line=d1.line, column=d1.column, _project=project) - d2, = script.goto_assignments() + script = Script(path=d1.module_path, _project=project) + d2, = script.goto(line=d1.line, column=d1.column) assert d2.is_stub() assert d2.module_path == d1.module_path assert d2.line == d1.line @@ -43,7 +43,7 @@ def test_conversion_of_stub_only(Script): def test_goto_on_file(Script): project = Project(os.path.join(root_dir, 'test', 'completion', 'stub_folder')) script = Script('import stub_only; stub_only.Foo', _project=project) - d1, = script.goto_assignments() + d1, = script.goto() v, = d1._name.infer() foo, bar, obj = v.py__mro__() assert foo.py__name__() == 'Foo' @@ -51,6 +51,6 @@ def test_goto_on_file(Script): assert obj.py__name__() == 'object' # Make sure we go to Bar, because Foo is a bit before: `class Foo(Bar):` - script = Script(path=d1.module_path, line=d1.line, column=d1.column + 4, _project=project) - d2, = script.goto_assignments() + script = Script(path=d1.module_path, _project=project) + d2, = script.goto(line=d1.line, column=d1.column + 4) assert d2.name == 'Bar' diff --git a/test/test_inference/test_gradual/test_stub_loading.py b/test/test_inference/test_gradual/test_stub_loading.py index 40dcffa8..cb6b7aac 100644 --- a/test/test_inference/test_gradual/test_stub_loading.py +++ b/test/test_inference/test_gradual/test_stub_loading.py @@ -23,5 +23,5 @@ def ScriptInStubFolder(Script): ] ) def test_find_stubs_infer(ScriptInStubFolder, code, expected): - defs = ScriptInStubFolder(code).goto_definitions() + defs = ScriptInStubFolder(code).infer() assert [d.name for d in defs] == expected diff --git a/test/test_inference/test_gradual/test_stubs.py b/test/test_inference/test_gradual/test_stubs.py index 4642c466..8d7bdb02 100644 --- a/test/test_inference/test_gradual/test_stubs.py +++ b/test/test_inference/test_gradual/test_stubs.py @@ -64,17 +64,17 @@ def test_infer_and_goto(Script, code, full_name, has_stub, has_python, way, if way == 'direct': if type_ == 'goto': - defs = s.goto_assignments(follow_imports=True, **kwargs) + defs = s.goto(follow_imports=True, **kwargs) else: - defs = s.goto_definitions(**kwargs) + defs = s.infer(**kwargs) else: - goto_defs = s.goto_assignments( + goto_defs = s.goto( # Prefering stubs when we want to go to python and vice versa prefer_stubs=not (prefer_stubs or only_stubs), follow_imports=True, ) if type_ == 'goto': - defs = [d for goto_def in goto_defs for d in goto_def.goto_assignments(**kwargs)] + defs = [d for goto_def in goto_defs for d in goto_def.goto(**kwargs)] else: defs = [d for goto_def in goto_defs for d in goto_def.infer(**kwargs)] diff --git a/test/test_inference/test_gradual/test_typeshed.py b/test/test_inference/test_gradual/test_typeshed.py index 8b7285de..a3076bdc 100644 --- a/test/test_inference/test_gradual/test_typeshed.py +++ b/test/test_inference/test_gradual/test_typeshed.py @@ -46,53 +46,53 @@ def test_get_stub_files(): def test_function(Script, environment): code = 'import threading; threading.current_thread' - def_, = Script(code).goto_definitions() + def_, = Script(code).infer() value = def_._name._value assert isinstance(value, FunctionValue), value - def_, = Script(code + '()').goto_definitions() + def_, = Script(code + '()').infer() value = def_._name._value assert isinstance(value, TreeInstance) - def_, = Script('import threading; threading.Thread').goto_definitions() + def_, = Script('import threading; threading.Thread').infer() assert isinstance(def_._name._value, ClassValue), def_ def test_keywords_variable(Script): code = 'import keyword; keyword.kwlist' - for seq in Script(code).goto_definitions(): + for seq in Script(code).infer(): assert seq.name == 'Sequence' # This points towards the typeshed implementation - stub_seq, = seq.goto_assignments(only_stubs=True) + stub_seq, = seq.goto(only_stubs=True) assert typeshed.TYPESHED_PATH in stub_seq.module_path def test_class(Script): - def_, = Script('import threading; threading.Thread').goto_definitions() + def_, = Script('import threading; threading.Thread').infer() value = def_._name._value assert isinstance(value, ClassValue), value def test_instance(Script): - def_, = Script('import threading; threading.Thread()').goto_definitions() + def_, = Script('import threading; threading.Thread()').infer() value = def_._name._value assert isinstance(value, TreeInstance) def test_class_function(Script): - def_, = Script('import threading; threading.Thread.getName').goto_definitions() + def_, = Script('import threading; threading.Thread.getName').infer() value = def_._name._value assert isinstance(value, MethodValue), value def test_method(Script): code = 'import threading; threading.Thread().getName' - def_, = Script(code).goto_definitions() + def_, = Script(code).infer() value = def_._name._value assert isinstance(value, BoundMethod), value assert isinstance(value._wrapped_value, MethodValue), value - def_, = Script(code + '()').goto_definitions() + def_, = Script(code + '()').infer() value = def_._name._value assert isinstance(value, TreeInstance) assert value.class_value.py__name__() == 'str' @@ -100,13 +100,13 @@ def test_method(Script): def test_sys_exc_info(Script): code = 'import sys; sys.exc_info()' - none, def_ = Script(code + '[1]').goto_definitions() + none, def_ = Script(code + '[1]').infer() # It's an optional. assert def_.name == 'BaseException' assert def_.type == 'instance' assert none.name == 'NoneType' - none, def_ = Script(code + '[0]').goto_definitions() + none, def_ = Script(code + '[0]').infer() assert def_.name == 'BaseException' assert def_.type == 'class' @@ -114,7 +114,7 @@ def test_sys_exc_info(Script): def test_sys_getwindowsversion(Script, environment): # This should only exist on Windows, but type inference should happen # everywhere. - definitions = Script('import sys; sys.getwindowsversion().major').goto_definitions() + definitions = Script('import sys; sys.getwindowsversion().major').infer() if environment.version_info.major == 2: assert not definitions else: @@ -124,22 +124,22 @@ def test_sys_getwindowsversion(Script, environment): def test_sys_hexversion(Script): script = Script('import sys; sys.hexversion') - def_, = script.completions() + def_, = script.complete() assert isinstance(def_._name, stub_value._StubName), def_._name assert typeshed.TYPESHED_PATH in def_.module_path - def_, = script.goto_definitions() + def_, = script.infer() assert def_.name == 'int' def test_math(Script): - def_, = Script('import math; math.acos()').goto_definitions() + def_, = Script('import math; math.acos()').infer() assert def_.name == 'float' value = def_._name._value assert value def test_type_var(Script): - def_, = Script('import typing; T = typing.TypeVar("T1")').goto_definitions() + def_, = Script('import typing; T = typing.TypeVar("T1")').infer() assert def_.name == 'TypeVar' assert def_.description == 'TypeVar = object()' @@ -152,29 +152,29 @@ def test_type_var(Script): ) def test_math_is_stub(Script, code, full_name): s = Script(code) - cos, = s.goto_definitions() + cos, = s.infer() wanted = os.path.join('typeshed', 'stdlib', '2and3', 'math.pyi') assert cos.module_path.endswith(wanted) assert cos.is_stub() is True - assert cos.goto_assignments(only_stubs=True) == [cos] + assert cos.goto(only_stubs=True) == [cos] assert cos.full_name == full_name - cos, = s.goto_assignments() + cos, = s.goto() assert cos.module_path.endswith(wanted) - assert cos.goto_assignments(only_stubs=True) == [cos] + assert cos.goto(only_stubs=True) == [cos] assert cos.is_stub() is True assert cos.full_name == full_name def test_goto_stubs(Script): s = Script('import os; os') - os_module, = s.goto_definitions() + os_module, = s.infer() assert os_module.full_name == 'os' assert os_module.is_stub() is False - stub, = os_module.goto_assignments(only_stubs=True) + stub, = os_module.goto(only_stubs=True) assert stub.is_stub() is True - os_module, = s.goto_assignments() + os_module, = s.goto() def _assert_is_same(d1, d2): @@ -199,21 +199,17 @@ def test_goto_stubs_on_itself(Script, code, type_): """ s = Script(code) if type_ == 'infer': - def_, = s.goto_definitions() + def_, = s.infer() else: - def_, = s.goto_assignments(follow_imports=True) - stub, = def_.goto_assignments(only_stubs=True) + def_, = s.goto(follow_imports=True) + stub, = def_.goto(only_stubs=True) - script_on_source = Script( - path=def_.module_path, - line=def_.line, - column=def_.column - ) + script_on_source = Script(path=def_.module_path) if type_ == 'infer': - definition, = script_on_source.goto_definitions() + definition, = script_on_source.infer(def_.line, def_.column) else: - definition, = script_on_source.goto_assignments() - same_stub, = definition.goto_assignments(only_stubs=True) + definition, = script_on_source.goto(def_.line, def_.column) + same_stub, = definition.goto(only_stubs=True) _assert_is_same(same_stub, stub) _assert_is_same(definition, def_) assert same_stub.module_path != def_.module_path @@ -221,16 +217,14 @@ def test_goto_stubs_on_itself(Script, code, type_): # And the reverse. script_on_stub = Script( path=same_stub.module_path, - line=same_stub.line, - column=same_stub.column ) if type_ == 'infer': - same_definition, = script_on_stub.goto_definitions() + same_definition, = script_on_stub.infer(same_stub.line, same_stub.column) same_definition2, = same_stub.infer() else: - same_definition, = script_on_stub.goto_assignments() - same_definition2, = same_stub.goto_assignments() + same_definition, = script_on_stub.goto(same_stub.line, same_stub.column) + same_definition2, = same_stub.goto() _assert_is_same(same_definition, definition) _assert_is_same(same_definition, same_definition2) diff --git a/test/test_inference/test_helpers.py b/test/test_inference/test_helpers.py index adfb4221..03a54eb8 100644 --- a/test/test_inference/test_helpers.py +++ b/test/test_inference/test_helpers.py @@ -1,15 +1,14 @@ from textwrap import dedent -from jedi import names from jedi.inference import helpers -def test_call_of_leaf_in_brackets(environment): +def test_call_of_leaf_in_brackets(Script): s = dedent(""" x = 1 type(x) """) - last_x = names(s, references=True, definitions=False, environment=environment)[-1] + last_x = Script(s).names(references=True, definitions=False)[-1] name = last_x._name.tree_name call = helpers.call_of_leaf(name) diff --git a/test/test_inference/test_implicit_namespace_package.py b/test/test_inference/test_implicit_namespace_package.py index 9dd5044f..d8983cad 100644 --- a/test/test_inference/test_implicit_namespace_package.py +++ b/test/test_inference/test_implicit_namespace_package.py @@ -17,9 +17,9 @@ def test_implicit_namespace_package(Script): return Script(sys_path=sys_path, *args, **kwargs) # goto definition - assert script_with_path('from pkg import ns1_file').goto_definitions() - assert script_with_path('from pkg import ns2_file').goto_definitions() - assert not script_with_path('from pkg import ns3_file').goto_definitions() + assert script_with_path('from pkg import ns1_file').infer() + assert script_with_path('from pkg import ns2_file').infer() + assert not script_with_path('from pkg import ns3_file').infer() # goto assignment tests = { @@ -27,12 +27,12 @@ def test_implicit_namespace_package(Script): 'from pkg.ns1_file import foo': 'ns1_file!', } for source, solution in tests.items(): - ass = script_with_path(source).goto_assignments() + ass = script_with_path(source).goto() assert len(ass) == 1 assert ass[0].description == "foo = '%s'" % solution # completion - completions = script_with_path('from pkg import ').completions() + completions = script_with_path('from pkg import ').complete() names = [c.name for c in completions] compare = ['ns1_file', 'ns2_file'] # must at least contain these items, other items are not important @@ -43,7 +43,7 @@ def test_implicit_namespace_package(Script): 'from pkg import ns1_file as x': 'ns1_file!' } for source, solution in tests.items(): - for c in script_with_path(source + '; x.').completions(): + for c in script_with_path(source + '; x.').complete(): if c.name == 'foo': completion = c solution = "foo = '%s'" % solution @@ -57,11 +57,11 @@ def test_implicit_nested_namespace_package(Script): script = Script(sys_path=sys_path, source=code, line=1, column=61) - result = script.goto_definitions() + result = script.infer() assert len(result) == 1 - implicit_pkg, = Script(code, column=10, sys_path=sys_path).goto_definitions() + implicit_pkg, = Script(code, sys_path=sys_path).infer(column=10) assert implicit_pkg.type == 'module' assert implicit_pkg.module_path is None @@ -72,7 +72,7 @@ def test_implicit_namespace_package_import_autocomplete(Script): sys_path = [dirname(__file__)] script = Script(sys_path=sys_path, source=CODE) - compl = script.completions() + compl = script.complete() assert [c.name for c in compl] == ['implicit_namespace_package'] @@ -82,7 +82,7 @@ def test_namespace_package_in_multiple_directories_autocompletion(Script): for d in ['implicit_namespace_package/ns1', 'implicit_namespace_package/ns2']] script = Script(sys_path=sys_path, source=CODE) - compl = script.completions() + compl = script.complete() assert set(c.name for c in compl) == set(['ns1_file', 'ns2_file']) @@ -91,7 +91,7 @@ def test_namespace_package_in_multiple_directories_goto_definition(Script): sys_path = [join(dirname(__file__), d) for d in ['implicit_namespace_package/ns1', 'implicit_namespace_package/ns2']] script = Script(sys_path=sys_path, source=CODE) - result = script.goto_definitions() + result = script.infer() assert len(result) == 1 @@ -101,5 +101,5 @@ def test_namespace_name_autocompletion_full_name(Script): for d in ['implicit_namespace_package/ns1', 'implicit_namespace_package/ns2']] script = Script(sys_path=sys_path, source=CODE) - compl = script.completions() + compl = script.complete() assert set(c.full_name for c in compl) == set(['pkg']) diff --git a/test/test_inference/test_imports.py b/test/test_inference/test_imports.py index 17c5a578..f7ec0ebc 100644 --- a/test/test_inference/test_imports.py +++ b/test/test_inference/test_imports.py @@ -46,7 +46,7 @@ pkg_zip_path = os.path.join(os.path.dirname(__file__), def test_find_module_package_zipped(Script, inference_state, environment): sys_path = environment.get_sys_path() + [pkg_zip_path] script = Script('import pkg; pkg.mod', sys_path=sys_path) - assert len(script.completions()) == 1 + assert len(script.complete()) == 1 file_io, is_package = inference_state.compiled_subprocess.get_module_info( sys_path=sys_path, @@ -87,7 +87,7 @@ def test_find_module_package_zipped(Script, inference_state, environment): def test_correct_zip_package_behavior(Script, inference_state, environment, code, file, package, path, skip_python2): sys_path = environment.get_sys_path() + [pkg_zip_path] - pkg, = Script(code, sys_path=sys_path).goto_definitions() + pkg, = Script(code, sys_path=sys_path).infer() value, = pkg._name.infer() assert value.py__file__() == os.path.join(pkg_zip_path, 'pkg', file) assert '.'.join(value.py__package__()) == package @@ -100,7 +100,7 @@ def test_find_module_not_package_zipped(Script, inference_state, environment): path = os.path.join(os.path.dirname(__file__), 'zipped_imports/not_pkg.zip') sys_path = environment.get_sys_path() + [path] script = Script('import not_pkg; not_pkg.val', sys_path=sys_path) - assert len(script.completions()) == 1 + assert len(script.complete()) == 1 file_io, is_package = inference_state.compiled_subprocess.get_module_info( sys_path=sys_path, @@ -118,12 +118,12 @@ def test_import_not_in_sys_path(Script): This is in the end just a fallback. """ - a = Script(path='module.py', line=5).goto_definitions() + a = Script(path='module.py').infer(line=5) assert a[0].name == 'int' - a = Script(path='module.py', line=6).goto_definitions() + a = Script(path='module.py').infer(line=6) assert a[0].name == 'str' - a = Script(path='module.py', line=7).goto_definitions() + a = Script(path='module.py').infer(line=7) assert a[0].name == 'str' @@ -145,19 +145,19 @@ def test_flask_ext(Script, code, name): """flask.ext.foo is really imported from flaskext.foo or flask_foo. """ path = os.path.join(os.path.dirname(__file__), 'flask-site-packages') - completions = Script(code, sys_path=[path]).completions() + completions = Script(code, sys_path=[path]).complete() assert name in [c.name for c in completions] @cwd_at('test/test_inference/') def test_not_importable_file(Script): src = 'import not_importable_file as x; x.' - assert not Script(src, path='example.py').completions() + assert not Script(src, path='example.py').complete() def test_import_unique(Script): src = "import os; os.path" - defs = Script(src, path='example.py').goto_definitions() + defs = Script(src, path='example.py').infer() parent_contexts = [d._name._value for d in defs] assert len(parent_contexts) == len(set(parent_contexts)) @@ -168,9 +168,9 @@ def test_cache_works_with_sys_path_param(Script, tmpdir): foo_path.join('module.py').write('foo = 123', ensure=True) bar_path.join('module.py').write('bar = 123', ensure=True) foo_completions = Script('import module; module.', - sys_path=[foo_path.strpath]).completions() + sys_path=[foo_path.strpath]).complete() bar_completions = Script('import module; module.', - sys_path=[bar_path.strpath]).completions() + sys_path=[bar_path.strpath]).complete() assert 'foo' in [c.name for c in foo_completions] assert 'bar' not in [c.name for c in foo_completions] @@ -181,7 +181,7 @@ def test_cache_works_with_sys_path_param(Script, tmpdir): def test_import_completion_docstring(Script): import abc s = Script('"""test"""\nimport ab') - abc_completions = [c for c in s.completions() if c.name == 'abc'] + abc_completions = [c for c in s.complete() if c.name == 'abc'] assert len(abc_completions) == 1 assert abc_completions[0].docstring(fast=False) == abc.__doc__ @@ -191,72 +191,72 @@ def test_import_completion_docstring(Script): def test_goto_definition_on_import(Script): - assert Script("import sys_blabla", 1, 8).goto_definitions() == [] - assert len(Script("import sys", 1, 8).goto_definitions()) == 1 + assert Script("import sys_blabla").infer(1, 8) == [] + assert len(Script("import sys").infer(1, 8)) == 1 @cwd_at('jedi') def test_complete_on_empty_import(Script): - assert Script("from datetime import").completions()[0].name == 'import' + assert Script("from datetime import").complete()[0].name == 'import' # should just list the files in the directory - assert 10 < len(Script("from .", path='whatever.py').completions()) < 30 + assert 10 < len(Script("from .", path='whatever.py').complete()) < 30 # Global import - assert len(Script("from . import", 1, 5, 'whatever.py').completions()) > 30 + assert len(Script("from . import", 'whatever.py').complete(1, 5)) > 30 # relative import - assert 10 < len(Script("from . import", 1, 6, 'whatever.py').completions()) < 30 + assert 10 < len(Script("from . import", 'whatever.py').complete(1, 6)) < 30 # Global import - assert len(Script("from . import classes", 1, 5, 'whatever.py').completions()) > 30 + assert len(Script("from . import classes", 'whatever.py').complete(1, 5)) > 30 # relative import - assert 10 < len(Script("from . import classes", 1, 6, 'whatever.py').completions()) < 30 + assert 10 < len(Script("from . import classes", 'whatever.py').complete(1, 6)) < 30 wanted = {'ImportError', 'import', 'ImportWarning'} - assert {c.name for c in Script("import").completions()} == wanted - assert len(Script("import import", path='').completions()) > 0 + assert {c.name for c in Script("import").complete()} == wanted + assert len(Script("import import", path='').complete()) > 0 # 111 - assert Script("from datetime import").completions()[0].name == 'import' - assert Script("from datetime import ").completions() + assert Script("from datetime import").complete()[0].name == 'import' + assert Script("from datetime import ").complete() def test_imports_on_global_namespace_without_path(Script): """If the path is None, there shouldn't be any import problem""" - completions = Script("import operator").completions() + completions = Script("import operator").complete() assert [c.name for c in completions] == ['operator'] - completions = Script("import operator", path='example.py').completions() + completions = Script("import operator", path='example.py').complete() assert [c.name for c in completions] == ['operator'] # the first one has a path the second doesn't - completions = Script("import keyword", path='example.py').completions() + completions = Script("import keyword", path='example.py').complete() assert [c.name for c in completions] == ['keyword'] - completions = Script("import keyword").completions() + completions = Script("import keyword").complete() assert [c.name for c in completions] == ['keyword'] def test_named_import(Script): """named import - jedi-vim issue #8""" s = "import time as dt" - assert len(Script(s, 1, 15, '/').goto_definitions()) == 1 - assert len(Script(s, 1, 10, '/').goto_definitions()) == 1 + assert len(Script(s, path='/').infer(1, 15)) == 1 + assert len(Script(s, path='/').infer(1, 10)) == 1 @pytest.mark.skipif('True', reason='The nested import stuff is still very messy.') def test_goto_following_on_imports(Script): s = "import multiprocessing.dummy; multiprocessing.dummy" - g = Script(s).goto_assignments() + g = Script(s).goto() assert len(g) == 1 assert (g[0].line, g[0].column) != (0, 0) -def test_goto_assignments(Script): - sys, = Script("import sys", 1, 10).goto_assignments(follow_imports=True) +def test_goto(Script): + sys, = Script("import sys", 1, 10).goto(follow_imports=True) assert sys.type == 'module' def test_os_after_from(Script): def check(source, result, column=None): - completions = Script(source, column=column).completions() + completions = Script(source).complete(column=column) assert [c.name for c in completions] == result check('\nfrom os. ', ['path']) @@ -270,7 +270,7 @@ def test_os_after_from(Script): def test_os_issues(Script): def import_names(*args, **kwargs): - return [d.name for d in Script(*args, **kwargs).completions()] + return [d.name for d in Script(*args).complete(**kwargs)] # Github issue #759 s = 'import os, s' @@ -291,7 +291,7 @@ def test_path_issues(Script): See pull request #684 for details. """ source = '''from datetime import ''' - assert Script(source).completions() + assert Script(source).complete() def test_compiled_import_none(monkeypatch, Script): @@ -300,7 +300,7 @@ def test_compiled_import_none(monkeypatch, Script): """ script = Script('import sys') monkeypatch.setattr(compiled, 'load_module', lambda *args, **kwargs: None) - def_, = script.goto_definitions() + def_, = script.infer() assert def_.type == 'module' value, = def_._name.infer() assert not _stub_to_python_value_set(value) @@ -361,7 +361,7 @@ def test_relative_imports_with_multiple_similar_directories(Script, path, empty_ path=os.path.join(dir, path), _project=project, ) - name, import_ = script.completions() + name, import_ = script.complete() assert import_.name == 'import' assert name.name == 'api_test1' @@ -374,37 +374,37 @@ def test_relative_imports_with_outside_paths(Script): path=os.path.join(dir, 'api/whatever/test_this.py'), _project=project, ) - assert [c.name for c in script.completions()] == ['api', 'import', 'whatever'] + assert [c.name for c in script.complete()] == ['api', 'import', 'whatever'] script = Script( "from " + '.' * 100, path=os.path.join(dir, 'api/whatever/test_this.py'), _project=project, ) - assert [c.name for c in script.completions()] == ['import'] + assert [c.name for c in script.complete()] == ['import'] @cwd_at('test/examples/issue1209/api/whatever/') def test_relative_imports_without_path(Script): project = Project('.', sys_path=[], smart_sys_path=False) script = Script("from . ", _project=project) - assert [c.name for c in script.completions()] == ['api_test1', 'import'] + assert [c.name for c in script.complete()] == ['api_test1', 'import'] script = Script("from .. ", _project=project) - assert [c.name for c in script.completions()] == ['import', 'whatever'] + assert [c.name for c in script.complete()] == ['import', 'whatever'] script = Script("from ... ", _project=project) - assert [c.name for c in script.completions()] == ['api', 'import', 'whatever'] + assert [c.name for c in script.complete()] == ['api', 'import', 'whatever'] def test_relative_import_out_of_file_system(Script): script = Script("from " + '.' * 100) - import_, = script.completions() + import_, = script.complete() assert import_.name == 'import' script = Script("from " + '.' * 100 + 'abc import ABCMeta') - assert not script.goto_definitions() - assert not script.completions() + assert not script.infer() + assert not script.complete() @pytest.mark.parametrize( @@ -456,13 +456,13 @@ def test_import_needed_modules_by_jedi(Script, environment, tmpdir, name): path=tmpdir.join('something.py').strpath, sys_path=[tmpdir.strpath] + environment.get_sys_path(), ) - module, = script.goto_definitions() + module, = script.infer() assert module._inference_state.builtins_module.py__file__() != module_path assert module._inference_state.typing_module.py__file__() != module_path def test_import_with_semicolon(Script): - names = [c.name for c in Script('xzy; from abc import ').completions()] + names = [c.name for c in Script('xzy; from abc import ').complete()] assert 'ABCMeta' in names assert 'abc' not in names @@ -475,6 +475,6 @@ def test_relative_import_star(Script): from . import * furl.c """ - script = jedi.Script(source, 3, len("furl.c"), 'export.py') + script = jedi.Script(source, 'export.py') - assert script.completions() + assert script.complete(3, len("furl.c")) diff --git a/test/test_inference/test_literals.py b/test/test_inference/test_literals.py index c137656f..42305d72 100644 --- a/test/test_inference/test_literals.py +++ b/test/test_inference/test_literals.py @@ -3,7 +3,7 @@ from jedi.inference.value import TreeInstance def _infer_literal(Script, code, is_fstring=False): - def_, = Script(code).goto_definitions() + def_, = Script(code).infer() if is_fstring: assert def_.name == 'str' assert isinstance(def_._name._value, TreeInstance) diff --git a/test/test_inference/test_mixed.py b/test/test_inference/test_mixed.py index e9873c87..daca6501 100644 --- a/test/test_inference/test_mixed.py +++ b/test/test_inference/test_mixed.py @@ -14,7 +14,7 @@ def interpreter(code, namespace, *args, **kwargs): def test_on_code(): from functools import wraps i = interpreter("wraps.__code__", {'wraps': wraps}) - assert i.goto_definitions() + assert i.infer() @pytest.mark.skipif('sys.version_info < (3,5)') @@ -39,4 +39,4 @@ def test_generics(): self.stack.push(1) s = StackWrapper() - print(interpreter('s.stack.pop().', locals()).completions()) + print(interpreter('s.stack.pop().', locals()).complete()) diff --git a/test/test_inference/test_namespace_package.py b/test/test_inference/test_namespace_package.py index 1b156583..240c76b6 100644 --- a/test/test_inference/test_namespace_package.py +++ b/test/test_inference/test_namespace_package.py @@ -15,9 +15,9 @@ def script_with_path(Script, *args, **kwargs): def test_goto_definition(Script): - assert script_with_path(Script, 'from pkg import ns1_file').goto_definitions() - assert script_with_path(Script, 'from pkg import ns2_file').goto_definitions() - assert not script_with_path(Script, 'from pkg import ns3_file').goto_definitions() + assert script_with_path(Script, 'from pkg import ns1_file').infer() + assert script_with_path(Script, 'from pkg import ns2_file').infer() + assert not script_with_path(Script, 'from pkg import ns3_file').infer() @pytest.mark.parametrize( @@ -31,14 +31,14 @@ def test_goto_definition(Script): ] ) def test_goto_assignment(Script, source, solution): - ass = script_with_path(Script, source).goto_assignments() + ass = script_with_path(Script, source).goto() assert len(ass) == 1 assert ass[0].description == "foo = '%s'" % solution def test_simple_completions(Script): # completion - completions = script_with_path(Script, 'from pkg import ').completions() + completions = script_with_path(Script, 'from pkg import ').complete() names = [str(c.name) for c in completions] # str because of unicode compare = ['foo', 'ns1_file', 'ns1_folder', 'ns2_folder', 'ns2_file', 'pkg_resources', 'pkgutil', '__name__', '__path__', @@ -58,7 +58,7 @@ def test_simple_completions(Script): ] ) def test_completions(Script, source, solution): - for c in script_with_path(Script, source + '; x.').completions(): + for c in script_with_path(Script, source + '; x.').complete(): if c.name == 'foo': completion = c solution = "foo = '%s'" % solution @@ -70,9 +70,9 @@ def test_nested_namespace_package(Script): sys_path = [dirname(__file__)] - script = Script(sys_path=sys_path, source=code, line=1, column=45) + script = Script(sys_path=sys_path, source=code) - result = script.goto_definitions() + result = script.infer(line=1, column=45) assert len(result) == 1 @@ -88,9 +88,9 @@ def test_relative_import(Script, environment, tmpdir): # Need to copy the content in a directory where there's no __init__.py. py.path.local(directory).copy(tmpdir) file_path = join(tmpdir.strpath, "rel1.py") - script = Script(path=file_path, line=1) - d, = script.goto_definitions() + script = Script(path=file_path) + d, = script.infer(line=1) assert d.name == 'int' - d, = script.goto_assignments() + d, = script.goto(line=1) assert d.name == 'name' assert d.module_name == 'rel2' diff --git a/test/test_inference/test_pyc.py b/test/test_inference/test_pyc.py index 37449572..615fd1cd 100644 --- a/test/test_inference/test_pyc.py +++ b/test/test_inference/test_pyc.py @@ -70,4 +70,4 @@ def test_pyc(pyc_project_path, environment): "from dummy_package import dummy; dummy.", path=path, environment=environment) - assert len(s.completions()) >= 2 + assert len(s.complete()) >= 2 diff --git a/test/test_inference/test_representation.py b/test/test_inference/test_representation.py index a602b900..fff323f7 100644 --- a/test/test_inference/test_representation.py +++ b/test/test_inference/test_representation.py @@ -2,7 +2,7 @@ from textwrap import dedent def get_definition_and_inference_state(Script, source): - first, = Script(dedent(source)).goto_definitions() + first, = Script(dedent(source)).infer() return first._name._value, first._inference_state diff --git a/test/test_inference/test_signature.py b/test/test_inference/test_signature.py index ad45b564..759ea99f 100644 --- a/test/test_inference/test_signature.py +++ b/test/test_inference/test_signature.py @@ -32,7 +32,7 @@ def test_compiled_signature(Script, environment, code, sig, names, op, version): if not op(environment.version_info, version): return # The test right next to it should take over. - d, = Script(code).goto_definitions() + d, = Script(code).infer() value, = d._name.infer() compiled, = _stub_to_python_value_set(value) signature, = compiled.get_signatures() @@ -90,9 +90,9 @@ def test_tree_signature(Script, environment, code, expected): pytest.skip() if expected is None: - assert not Script(code).call_signatures() + assert not Script(code).find_signatures() else: - sig, = Script(code).call_signatures() + sig, = Script(code).find_signatures() assert expected == sig.to_string() @@ -182,7 +182,7 @@ def test_nested_signatures(Script, environment, combination, expected, skip_pre_ super().foo(**kwargs) ''') code += 'z = ' + combination + '\nz(' - sig, = Script(code).call_signatures() + sig, = Script(code).find_signatures() computed = sig.to_string() if not re.match(r'\w+\(', expected): expected = '(' + expected + ')' @@ -191,7 +191,7 @@ def test_nested_signatures(Script, environment, combination, expected, skip_pre_ def test_pow_signature(Script): # See github #1357 - sigs = Script('pow(').call_signatures() + sigs = Script('pow(').find_signatures() strings = {sig.to_string() for sig in sigs} assert strings == {'pow(x: float, y: float, z: float, /) -> float', 'pow(x: float, y: float, /) -> float', @@ -230,7 +230,7 @@ def test_pow_signature(Script): ] ) def test_wraps_signature(Script, code, signature, skip_pre_python35): - sigs = Script(code).call_signatures() + sigs = Script(code).find_signatures() assert {sig.to_string() for sig in sigs} == {signature} @@ -263,7 +263,7 @@ def test_dataclass_signature(Script, skip_pre_python37, start, start_params): code = 'from dataclasses import dataclass\n' + start + code - sig, = Script(code).call_signatures() + sig, = Script(code).find_signatures() assert [p.name for p in sig.params] == start_params + ['name', 'price', 'quantity'] quantity, = sig.params[-1].infer() assert quantity.name == 'int' @@ -289,13 +289,13 @@ def test_param_resolving_to_static(Script, stmt, expected, skip_pre_python35): def simple(a, b, *, c): ... full_redirect(simple)('''.format(stmt=stmt)) - sig, = Script(code).call_signatures() + sig, = Script(code).find_signatures() assert sig.to_string() == expected def test_overload(Script): dir_ = get_example_dir('typing_overload') code = 'from file import with_overload; with_overload(' - x1, x2 = Script(code, path=os.path.join(dir_, 'foo.py')).call_signatures() + x1, x2 = Script(code, path=os.path.join(dir_, 'foo.py')).find_signatures() assert x1.to_string() == 'with_overload(x: int, y: int) -> float' assert x2.to_string() == 'with_overload(x: str, y: list) -> float' diff --git a/test/test_inference/test_stdlib.py b/test/test_inference/test_stdlib.py index fb98d8a4..40f38053 100644 --- a/test/test_inference/test_stdlib.py +++ b/test/test_inference/test_stdlib.py @@ -17,7 +17,7 @@ def test_namedtuple_str(letter, expected, Script): Person = collections.namedtuple('Person', 'name smart') dave = Person('Dave', False) dave.%s""") % letter - result = Script(source).completions() + result = Script(source).complete() completions = set(r.name for r in result) assert completions == set(expected) @@ -28,7 +28,7 @@ def test_namedtuple_list(Script): Cat = collections.namedtuple('Person', ['legs', u'length', 'large']) garfield = Cat(4, '85cm', True) garfield.l""") - result = Script(source).completions() + result = Script(source).complete() completions = set(r.name for r in result) assert completions == {'legs', 'length', 'large'} @@ -42,7 +42,7 @@ def test_namedtuple_content(Script): """) def d(source): - x, = Script(source).goto_definitions() + x, = Script(source).infer() return x.name assert d(source + 'unnamed.bar') == 'int' @@ -62,10 +62,10 @@ def test_nested_namedtuples(Script): train_x = Datasets(train=Dataset('data_value')) train_x.train.''' )) - assert 'data' in [c.name for c in s.completions()] + assert 'data' in [c.name for c in s.complete()] -def test_namedtuple_goto_definitions(Script): +def test_namedtuple_infer(Script): source = dedent(""" from collections import namedtuple @@ -74,7 +74,7 @@ def test_namedtuple_goto_definitions(Script): from jedi.api import Script - d1, = Script(source).goto_definitions() + d1, = Script(source).infer() assert d1.get_line_code() == "class Foo(tuple):\n" assert d1.module_path is None @@ -86,7 +86,7 @@ def test_re_sub(Script, environment): version differences. """ def run(code): - defs = Script(code).goto_definitions() + defs = Script(code).infer() return {d.name for d in defs} names = run("import re; re.sub('a', 'a', 'f')") diff --git a/test/test_parso_integration/test_basic.py b/test/test_parso_integration/test_basic.py index 289bad57..a89f478e 100644 --- a/test/test_parso_integration/test_basic.py +++ b/test/test_parso_integration/test_basic.py @@ -6,7 +6,7 @@ from parso import parse def test_form_feed_characters(Script): s = "\f\nclass Test(object):\n pass" - Script(s, line=2, column=18).call_signatures() + Script(s).find_signatures(line=2, column=18) def check_p(src): @@ -29,7 +29,7 @@ def test_if(Script): # Two parsers needed, one for pass and one for the function. check_p(src) - assert [d.name for d in Script(src, 8, 6).goto_definitions()] == ['int'] + assert [d.name for d in Script(src).infer(8, 6)] == ['int'] def test_class_and_if(Script): @@ -47,7 +47,7 @@ def test_class_and_if(Script): # COMMENT a_func()""") check_p(src) - assert [d.name for d in Script(src).goto_definitions()] == ['int'] + assert [d.name for d in Script(src).infer()] == ['int'] def test_add_to_end(Script): @@ -70,8 +70,8 @@ def test_add_to_end(Script): " self." def complete(code, line=None, column=None): - script = Script(code, line, column, 'example.py') - assert script.completions() + script = Script(code, 'example.py') + assert script.complete(line, column) complete(a, 7, 12) complete(a + b) @@ -82,7 +82,7 @@ def test_add_to_end(Script): def test_tokenizer_with_string_literal_backslash(Script): - c = Script("statement = u'foo\\\n'; statement").goto_definitions() + c = Script("statement = u'foo\\\n'; statement").infer() assert c[0]._name._value.get_safe_value() == 'foo' @@ -90,6 +90,6 @@ def test_ellipsis_without_getitem(Script, environment): if environment.version_info.major == 2: pytest.skip('In 2.7 Ellipsis can only be used like x[...]') - def_, = Script('x=...;x').goto_definitions() + def_, = Script('x=...;x').infer() assert def_.name == 'ellipsis' diff --git a/test/test_parso_integration/test_error_correction.py b/test/test_parso_integration/test_error_correction.py index 02bd9af3..3ecb32e1 100644 --- a/test/test_parso_integration/test_error_correction.py +++ b/test/test_parso_integration/test_error_correction.py @@ -6,7 +6,7 @@ def test_error_correction_with(Script): with open() as f: try: f.""" - comps = Script(source).completions() + comps = Script(source).complete() assert len(comps) > 30 # `open` completions have a closed attribute. assert [1 for c in comps if c.name == 'closed'] @@ -23,14 +23,14 @@ def test_string_literals(Script): script = Script(dedent(source)) assert script._get_module_context().tree_node.end_pos == (6, 0) - assert script.completions() + assert script.complete() def test_incomplete_function(Script): source = '''return ImportErr''' - script = Script(dedent(source), 1, 3) - assert script.completions() + script = Script(dedent(source)) + assert script.complete(1, 3) def test_decorator_string_issue(Script): @@ -46,5 +46,5 @@ def test_decorator_string_issue(Script): bla.''') s = Script(source) - assert s.completions() + assert s.complete() assert s._get_module_context().tree_node.get_code() == source diff --git a/test/test_parso_integration/test_parser_utils.py b/test/test_parso_integration/test_parser_utils.py index a411e6e3..b5a3167a 100644 --- a/test/test_parso_integration/test_parser_utils.py +++ b/test/test_parso_integration/test_parser_utils.py @@ -62,13 +62,13 @@ def test_hex_values_in_docstring(): @pytest.mark.parametrize( - 'code,call_signature', [ + 'code,signature', [ ('def my_function(x, typed: Type, z):\n return', 'my_function(x, typed: Type, z)'), ('def my_function(x, y, z) -> str:\n return', 'my_function(x, y, z) -> str'), ('lambda x, y, z: x + y * z\n', '(x, y, z)') ]) -def test_get_call_signature(code, call_signature): +def test_get_signature(code, signature): node = parse(code, version='3.5').children[0] if node.type == 'simple_stmt': node = node.children[0] - assert parser_utils.get_call_signature(node) == call_signature + assert parser_utils.get_signature(node) == signature diff --git a/test/test_settings.py b/test/test_settings.py index 015d699e..ea90d923 100644 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -12,14 +12,14 @@ def auto_import_json(monkeypatch): def test_base_auto_import_modules(auto_import_json, Script): - loads, = Script('import json; json.loads').goto_definitions() + loads, = Script('import json; json.loads').infer() assert isinstance(loads._name, ValueName) value, = loads._name.infer() assert isinstance(value.parent_context._value, StubModuleValue) def test_auto_import_modules_imports(auto_import_json, Script): - main, = Script('from json import tool; tool.main').goto_definitions() + main, = Script('from json import tool; tool.main').infer() assert isinstance(main._name, CompiledValueName) @@ -31,7 +31,7 @@ def test_additional_dynamic_modules(monkeypatch, Script): 'additional_dynamic_modules', ['/foo/bar/jedi_not_existing_file.py'] ) - assert not Script('def some_func(f):\n f.').completions() + assert not Script('def some_func(f):\n f.').complete() def test_cropped_file_size(monkeypatch, names, Script): @@ -47,5 +47,5 @@ def test_cropped_file_size(monkeypatch, names, Script): # It should just not crash if we are outside of the cropped range. script = Script(code + code + 'Foo') - assert not script.goto_definitions() - assert 'Foo' in [c.name for c in script.completions()] + assert not script.infer() + assert 'Foo' in [c.name for c in script.complete()] diff --git a/test/test_speed.py b/test/test_speed.py index ba5784ac..91f172b5 100644 --- a/test/test_speed.py +++ b/test/test_speed.py @@ -33,14 +33,14 @@ def _check_speed(time_per_run, number=4, run_warm=True): @_check_speed(0.5) def test_os_path_join(Script): s = "from posixpath import join; join('', '')." - assert len(Script(s).completions()) > 10 # is a str completion + assert len(Script(s).complete()) > 10 # is a str completion @_check_speed(0.15) def test_scipy_speed(Script): s = 'import scipy.weave; scipy.weave.inline(' - script = Script(s, 1, len(s), '') - script.call_signatures() + script = Script(s, path='') + script.find_signatures(1, len(s)) @_check_speed(0.8) @@ -52,7 +52,7 @@ def test_precedence_slowdown(Script): """ with open('speed/precedence.py') as f: line = len(f.read().splitlines()) - assert Script(line=line, path='speed/precedence.py').goto_definitions() + assert Script(path='speed/precedence.py').infer(line=line) @_check_speed(0.1) @@ -70,4 +70,4 @@ def test_no_repr_computation(Script): def __repr__(self): time.sleep(0.2) test = SlowRepr() - jedi.Interpreter('test.som', [locals()]).completions() + jedi.Interpreter('test.som', [locals()]).complete() diff --git a/test/test_utils.py b/test/test_utils.py index 3ac76389..a4c510e0 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -19,7 +19,7 @@ class TestSetupReadline(unittest.TestCase): self.namespace = self.NameSpace() utils.setup_readline(self.namespace) - def completions(self, text): + def complete(self, text): completer = readline.get_completer() i = 0 completions = [] @@ -32,18 +32,18 @@ class TestSetupReadline(unittest.TestCase): return completions def test_simple(self): - assert self.completions('list') == ['list'] - assert self.completions('importerror') == ['ImportError'] + assert self.complete('list') == ['list'] + assert self.complete('importerror') == ['ImportError'] s = "print(BaseE" - assert self.completions(s) == [s + 'xception'] + assert self.complete(s) == [s + 'xception'] def test_nested(self): - assert self.completions('list.Insert') == ['list.insert'] - assert self.completions('list().Insert') == ['list().insert'] + assert self.complete('list.Insert') == ['list.insert'] + assert self.complete('list().Insert') == ['list().insert'] def test_magic_methods(self): - assert self.completions('list.__getitem__') == ['list.__getitem__'] - assert self.completions('list().__getitem__') == ['list().__getitem__'] + assert self.complete('list.__getitem__') == ['list.__getitem__'] + assert self.complete('list().__getitem__') == ['list().__getitem__'] def test_modules(self): import sys @@ -52,31 +52,31 @@ class TestSetupReadline(unittest.TestCase): self.namespace.os = os try: - assert self.completions('os.path.join') == ['os.path.join'] + assert self.complete('os.path.join') == ['os.path.join'] string = 'os.path.join("a").upper' - assert self.completions(string) == [string] + assert self.complete(string) == [string] c = {'os.' + d for d in dir(os) if d.startswith('ch')} - assert set(self.completions('os.ch')) == set(c) + assert set(self.complete('os.ch')) == set(c) finally: del self.namespace.sys del self.namespace.os def test_calls(self): s = 'str(bytes' - assert self.completions(s) == [s, 'str(BytesWarning'] + assert self.complete(s) == [s, 'str(BytesWarning'] def test_import(self): s = 'from os.path import a' - assert set(self.completions(s)) == {s + 'ltsep', s + 'bspath'} - assert self.completions('import keyword') == ['import keyword'] + assert set(self.complete(s)) == {s + 'ltsep', s + 'bspath'} + assert self.complete('import keyword') == ['import keyword'] import os s = 'from os import ' goal = {s + el for el in dir(os)} # There are minor differences, e.g. the dir doesn't include deleted # items as well as items that are not only available on linux. - difference = set(self.completions(s)).symmetric_difference(goal) + difference = set(self.complete(s)).symmetric_difference(goal) difference = { x for x in difference if all(not x.startswith('from os import ' + s) @@ -89,11 +89,11 @@ class TestSetupReadline(unittest.TestCase): @cwd_at('test') def test_local_import(self): s = 'import test_utils' - assert self.completions(s) == [s] + assert self.complete(s) == [s] def test_preexisting_values(self): self.namespace.a = range(10) - assert set(self.completions('a.')) == {'a.' + n for n in dir(range(1))} + assert set(self.complete('a.')) == {'a.' + n for n in dir(range(1))} del self.namespace.a def test_colorama(self): @@ -110,8 +110,8 @@ class TestSetupReadline(unittest.TestCase): pass else: self.namespace.colorama = colorama - assert self.completions('colorama') - assert self.completions('colorama.Fore.BLACK') == ['colorama.Fore.BLACK'] + assert self.complete('colorama') + assert self.complete('colorama.Fore.BLACK') == ['colorama.Fore.BLACK'] del self.namespace.colorama