Skip to content

Commit

Permalink
FIXED: Simplify jedi_utils by dropping support for older versions tho…
Browse files Browse the repository at this point in the history
  • Loading branch information
aivarannamaa committed Jul 23, 2020
1 parent 1880ea9 commit 164e37c
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 129 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
jedi>=0.13
parso>=0.3
setuptools>=33.1
pyserial>=3.4
pylint>=1.9
Expand Down
110 changes: 10 additions & 100 deletions thonny/jedi_utils.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,18 @@
"""Utils to handle different jedi versions
Because of Debian Stretch, Thonny needs to support jedi 0.10,
which doesn't use separate parso
"""


def import_python_tree():
# pylint: disable=import-error,no-name-in-module

if get_version_tuple() < (0, 11, 0):
# make sure not to import parso in this case, even if it exits
from jedi.parser import tree # @UnresolvedImport @UnusedImport
else:
# assume older versions, which use parso
from parso.python import tree # @UnresolvedImport @UnusedImport @Reimport

return tree


def get_params(func_node):
if hasattr(func_node, "get_params"):
# parso
return func_node.get_params()
else:
# older jedi
return func_node.params


def get_parent_scope(node):
try:
# jedi 0.11
from jedi import parser_utils

return parser_utils.get_parent_scope(node)
except ImportError:
# Older versions
return node.get_parent_scope()
Utils to handle different jedi versions
"""


def get_statement_of_position(node, pos):
try:
# jedi 0.11
# pylint: disable=redefined-outer-name
import jedi.parser_utils
import jedi.parser_utils

func = getattr(
jedi.parser_utils, "get_statement_of_position", _copy_of_get_statement_of_position
)
return func(node, pos)
except ImportError:
# Older versions
return node.get_statement_for_position(pos)
func = getattr(
jedi.parser_utils, "get_statement_of_position", _copy_of_get_statement_of_position
)
return func(node, pos)


# TODO: try to get rid of this
def _copy_of_get_statement_of_position(node, pos):
# https://github.com/davidhalter/jedi/commit/9f3a2f93c48eda24e2dcc25e54eb7cc10aa73848
from parso.python import tree
Expand All @@ -75,57 +35,7 @@ def _copy_of_get_statement_of_position(node, pos):
return None


def get_module_node(script):
if hasattr(script, "_module_node"): # Jedi 0.12
return script._module_node
elif hasattr(script, "_get_module_node"): # Jedi 0.10 - 0.11
return script._get_module_node()
elif hasattr(script, "_get_module"):
return script._get_module()
else:
return script._parser.module()


def is_scope(node):
try:
# jedi 0.11 and older
from jedi import parser_utils

return parser_utils.is_scope(node)
except ImportError:
# Older versions
return node.is_scope()


def get_name_of_position(obj, position):
if hasattr(obj, "get_name_of_position"):
# parso
return obj.get_name_of_position(position)
else:
# older jedi
return obj.name_for_position(position)


def parse_source(source):
try:
import parso

return parso.parse(source)
except ImportError:
import jedi

script = jedi.Script(source)
return get_module_node(script)


def get_version_tuple():
import jedi

nums = []
for item in jedi.__version__.split("."):
try:
nums.append(int(item))
except Exception:
nums.append(0)
import parso

return tuple(nums)
return parso.parse(source)
41 changes: 20 additions & 21 deletions thonny/plugins/highlight_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def _is_name_function_definition(self, name):
)

def _get_def_from_function_params(self, func_node, name):
params = jedi_utils.get_params(func_node)
params = func_node.get_params()
for param in params:
if param.children[0].value == name.value:
return param.children[0]
Expand Down Expand Up @@ -107,6 +107,7 @@ def _is_global_stmt_with_name(self, node, name_str):
)

def _find_definition(self, scope, name):
from jedi import parser_utils

# if the name is the name of a function definition
if isinstance(scope, tree.Function):
Expand All @@ -130,21 +131,21 @@ def _find_definition(self, scope, name):
if (
isinstance(c, tree.Function)
and c.children[1].value == name.value
and not isinstance(jedi_utils.get_parent_scope(c), tree.Class)
and not isinstance(parser_utils.get_parent_scope(c), tree.Class)
):
return c.children[1]
if isinstance(c, tree.BaseNode) and c.type == "suite":
for x in c.children:
if self._is_global_stmt_with_name(x, name.value):
return self._find_definition(jedi_utils.get_parent_scope(scope), name)
return self._find_definition(parser_utils.get_parent_scope(scope), name)
if isinstance(x, tree.Name) and x.is_definition() and x.value == name.value:
return x
def_candidate = self._find_def_in_simple_node(x, name)
if def_candidate:
return def_candidate

if not isinstance(scope, tree.Module):
return self._find_definition(jedi_utils.get_parent_scope(scope), name)
return self._find_definition(parser_utils.get_parent_scope(scope), name)

# if name itself is the left side of an assignment statement, then the name is the definition
if name.is_definition():
Expand All @@ -169,13 +170,15 @@ def _get_dot_names(self, stmt):
return ()

def _find_usages(self, name, stmt):
from jedi import parser_utils

# check if stmt is dot qualified, disregard these
dot_names = self._get_dot_names(stmt)
if len(dot_names) > 1 and dot_names[1].value == name.value:
return set()

# search for definition
definition = self._find_definition(jedi_utils.get_parent_scope(name), name)
definition = self._find_definition(parser_utils.get_parent_scope(name), name)

searched_scopes = set()

Expand All @@ -186,7 +189,7 @@ def _find_usages(self, name, stmt):
def find_usages_in_node(node, global_encountered=False):
names = []
if isinstance(node, tree.BaseNode):
if jedi_utils.is_scope(node):
if parser_utils.is_scope(node):
global_encountered = False
if node in searched_scopes:
return names
Expand All @@ -203,10 +206,10 @@ def find_usages_in_node(node, global_encountered=False):
sub_result = find_usages_in_node(c, global_encountered=global_encountered)

if sub_result is None:
if not jedi_utils.is_scope(node):
if not parser_utils.is_scope(node):
return (
None
if definition and node != jedi_utils.get_parent_scope(definition)
if definition and node != parser_utils.get_parent_scope(definition)
else [definition]
)
else:
Expand All @@ -218,7 +221,7 @@ def find_usages_in_node(node, global_encountered=False):
if definition and definition != node:
if self._is_name_function_definition(node):
if isinstance(
jedi_utils.get_parent_scope(jedi_utils.get_parent_scope(node)),
parser_utils.get_parent_scope(parser_utils.get_parent_scope(node)),
tree.Class,
):
return []
Expand All @@ -229,13 +232,13 @@ def find_usages_in_node(node, global_encountered=False):
and not global_encountered
and (
is_function_definition
or jedi_utils.get_parent_scope(node)
!= jedi_utils.get_parent_scope(definition)
or parser_utils.get_parent_scope(node)
!= parser_utils.get_parent_scope(definition)
)
):
return None
if self._is_name_function_definition(definition) and isinstance(
jedi_utils.get_parent_scope(jedi_utils.get_parent_scope(definition)),
parser_utils.get_parent_scope(parser_utils.get_parent_scope(definition)),
tree.Class,
):
return None
Expand All @@ -244,11 +247,11 @@ def find_usages_in_node(node, global_encountered=False):

if definition:
if self._is_name_function_definition(definition):
scope = jedi_utils.get_parent_scope(jedi_utils.get_parent_scope(definition))
scope = parser_utils.get_parent_scope(parser_utils.get_parent_scope(definition))
else:
scope = jedi_utils.get_parent_scope(definition)
scope = parser_utils.get_parent_scope(definition)
else:
scope = jedi_utils.get_parent_scope(name)
scope = parser_utils.get_parent_scope(name)

usages = find_usages_in_node(scope)
return usages
Expand All @@ -262,7 +265,7 @@ def get_positions_for(self, source, line, column):
if isinstance(stmt, tree.Name):
name = stmt
elif isinstance(stmt, tree.BaseNode):
name = jedi_utils.get_name_of_position(stmt, pos)
name = stmt.get_name_of_position(pos)

if not name:
return set()
Expand Down Expand Up @@ -319,14 +322,10 @@ def update_highlighting(event):
# don't slow down loading process
return

if jedi_utils.get_version_tuple() < (0, 9):
logging.warning("Jedi version is too old. Disabling name highlighter")
return

global tree
if not tree:
# using lazy importing to speed up Thonny loading
tree = jedi_utils.import_python_tree()
from parso.python import tree

assert isinstance(event.widget, tk.Text)
text = event.widget
Expand Down
9 changes: 3 additions & 6 deletions thonny/plugins/locals_marker.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ def __init__(self, text):
self._update_scheduled = False

def get_positions(self):
tree = jedi_utils.import_python_tree()
from parso.python import tree
from jedi import parser_utils

locs = []

Expand Down Expand Up @@ -60,7 +61,7 @@ def process_node(node, local_names, global_names):
source = self.text.get("1.0", "end")
module = jedi_utils.parse_source(source)
for child in module.children:
if isinstance(child, tree.BaseNode) and jedi_utils.is_scope(child):
if isinstance(child, tree.BaseNode) and parser_utils.is_scope(child):
process_scope(child)

loc_pos = set(
Expand Down Expand Up @@ -105,10 +106,6 @@ def update_highlighting(event):
# don't slow down loading process
return

if jedi_utils.get_version_tuple() < (0, 9):
logging.warning("Jedi version is too old. Disabling locals marker")
return

assert isinstance(event.widget, tk.Text)
text = event.widget

Expand Down
4 changes: 2 additions & 2 deletions thonny/plugins/statement_boxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def predicate(


def print_tree(node, level=0):
python_tree = jedi_utils.import_python_tree()
from parso.python import tree as python_tree
indent = " " * level
# if (isinstance(node, python_tree.PythonNode) and node.type == "sim"
if node.type in ("simple_stmt",) or isinstance(node, python_tree.Flow):
Expand Down Expand Up @@ -154,7 +154,7 @@ def add_tags(text):

def tag_tree(node):
nonlocal last_line, last_col
python_tree = jedi_utils.import_python_tree()
from parso.python import tree as python_tree

if node.type == "simple_stmt" or isinstance(node, (python_tree.Flow, python_tree.Scope)):

Expand Down

0 comments on commit 164e37c

Please sign in to comment.