From ad563ee9eccd084c21e9f6fe104630f16b299b5e Mon Sep 17 00:00:00 2001 From: Costa Huang Date: Thu, 20 Jul 2017 08:03:52 -0400 Subject: [PATCH 1/2] Add PEP 526 AutoCompletion (#1102) By following instructions similar to this link: https://github.com/davidhalter/jedi/commit/3f09f3a30432dacdc224a2f819a458a8218e3723 It is now possible to give autocompletion for variable declared in the following fashion: test: str = "PEP 562 Support" Related issues can be found here: https://github.com/DonJayamanne/pythonVSCode/issues/1101 --- pythonFiles/preview/jedi/evaluate/__init__.py | 4 +++- pythonFiles/preview/jedi/parser/tree.py | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pythonFiles/preview/jedi/evaluate/__init__.py b/pythonFiles/preview/jedi/evaluate/__init__.py index 9a6ad64a377e..fe2c70237afd 100644 --- a/pythonFiles/preview/jedi/evaluate/__init__.py +++ b/pythonFiles/preview/jedi/evaluate/__init__.py @@ -162,7 +162,7 @@ def eval_statement(self, stmt, seek_name=None): types = finder.check_tuple_assignments(self, types, seek_name) first_operation = stmt.first_operation() - if first_operation not in ('=', None) and not isinstance(stmt, er.InstanceElement): # TODO don't check for this. + if first_operation not in ('=', None) and not isinstance(stmt, er.InstanceElement) and first_operation.type == 'operator': # TODO don't check for this. # `=` is always the last character in aug assignments -> -1 operator = copy.copy(first_operation) operator.value = operator.value[:-1] @@ -327,6 +327,8 @@ def _eval_element_not_cached(self, element): types = types elif element.type == 'eval_input': types = self._eval_element_not_cached(element.children[0]) + elif element.type == 'annassign': + types = self.eval_element(element.children[1]) else: types = precedence.calculate_children(self, element.children) debug.dbg('eval_element result %s', types) diff --git a/pythonFiles/preview/jedi/parser/tree.py b/pythonFiles/preview/jedi/parser/tree.py index c5a2d554d10e..0033a49cbfde 100644 --- a/pythonFiles/preview/jedi/parser/tree.py +++ b/pythonFiles/preview/jedi/parser/tree.py @@ -1522,9 +1522,14 @@ class ExprStmt(BaseNode, DocstringMixin): __slots__ = () def get_defined_names(self): - return list(chain.from_iterable(_defined_names(self.children[i]) - for i in range(0, len(self.children) - 2, 2) - if '=' in self.children[i + 1].value)) + names = [] + if self.children[1].type == 'annassign': + names = _defined_names(self.children[0]) + return list(chain.from_iterable( + _defined_names(self.children[i]) + for i in range(0, len(self.children) - 2, 2) + if '=' in self.children[i + 1].value) + ) + names def get_rhs(self): """Returns the right-hand-side of the equals.""" From 4c0e740e07880ad02ab5a13909dbe8286a12f285 Mon Sep 17 00:00:00 2001 From: Mike Poindexter Date: Thu, 20 Jul 2017 05:07:50 -0700 Subject: [PATCH 2/2] Add code to make definition lookup work with latest version of Jedi (#1085) * Add code to make definition lookup work with latest version of Jedi * Change function names to include Jedi version they are associated with --- pythonFiles/completion.py | 72 +++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/pythonFiles/completion.py b/pythonFiles/completion.py index 266707c46d19..ebef3e2606cb 100644 --- a/pythonFiles/completion.py +++ b/pythonFiles/completion.py @@ -313,20 +313,7 @@ def _top_definition(self, definition): return d return definition - def _extract_range(self, definition): - """Provides the definition range of a given definition - - For regular symbols it returns the start and end location of the - characters making up the symbol. - - For scoped containers it will return the entire definition of the - scope. - - The scope that jedi provides ends with the first character of the next - scope so it's not ideal. For vscode we need the scope to end with the - last character of actual code. That's why we extract the lines that - make up our scope and trim the trailing whitespace. - """ + def _extract_range_jedi_0_9_0(self, definition): from jedi import common from jedi.parser.utils import load_parser # get the scope range @@ -366,6 +353,63 @@ def _extract_range(self, definition): 'end_line': definition.line - 1, 'end_column': definition.column } + + def _extract_range_jedi_0_10_1(self, definition): + from jedi import common + from jedi.parser.python import parse + # get the scope range + try: + if definition.type in ['class', 'function']: + tree_name = definition._name.tree_name + scope = tree_name.get_definition() + start_line = scope.start_pos[0] - 1 + start_column = scope.start_pos[1] + # get the lines + code = scope.get_code(include_prefix=False) + lines = common.splitlines(code) + # trim the lines + lines = '\n'.join(lines).rstrip().split('\n') + end_line = start_line + len(lines) - 1 + end_column = len(lines[-1]) - 1 + else: + symbol = definition._name.tree_name + start_line = symbol.start_pos[0] - 1 + start_column = symbol.start_pos[1] + end_line = symbol.end_pos[0] - 1 + end_column = symbol.end_pos[1] + return { + 'start_line': start_line, + 'start_column': start_column, + 'end_line': end_line, + 'end_column': end_column + } + except Exception as e: + return { + 'start_line': definition.line - 1, + 'start_column': definition.column, + 'end_line': definition.line - 1, + 'end_column': definition.column + } + + def _extract_range(self, definition): + """Provides the definition range of a given definition + + For regular symbols it returns the start and end location of the + characters making up the symbol. + + For scoped containers it will return the entire definition of the + scope. + + The scope that jedi provides ends with the first character of the next + scope so it's not ideal. For vscode we need the scope to end with the + last character of actual code. That's why we extract the lines that + make up our scope and trim the trailing whitespace. + """ + if jedi.__version__ in ('0.9.0', '0.10.0'): + return self._extract_range_jedi_0_9_0(definition) + else: + return self._extract_range_jedi_0_10_1(definition) + def _get_definitionsx(self, definitions, identifier=None, ignoreNoModulePath=False): """Serialize response to be read from VSCode.