Another time avoiding a memory leak, also part of #1723

This commit is contained in:
Dave Halter
2021-01-14 01:18:00 +01:00
parent 0ff532b937
commit b6fd81f1e1
4 changed files with 15 additions and 8 deletions

View File

@@ -149,7 +149,7 @@ class ParserTreeFilter(_AbstractUsedNamesFilter):
if parent.type == 'trailer': if parent.type == 'trailer':
return False return False
base_node = parent if parent.type in ('classdef', 'funcdef') else name base_node = parent if parent.type in ('classdef', 'funcdef') else name
return get_cached_parent_scope(self._used_names, base_node) == self._parser_scope return get_cached_parent_scope(self._parso_cache_node, base_node) == self._parser_scope
def _check_flows(self, names): def _check_flows(self, names):
for name in sorted(names, key=lambda name: name.start_pos, reverse=True): for name in sorted(names, key=lambda name: name.start_pos, reverse=True):

View File

@@ -114,7 +114,7 @@ class ClassFilter(ParserTreeFilter):
while node is not None: while node is not None:
if node == self._parser_scope or node == self.parent_context: if node == self._parser_scope or node == self.parent_context:
return True return True
node = get_cached_parent_scope(self._used_names, node) node = get_cached_parent_scope(self._parso_cache_node, node)
return False return False
def _access_possible(self, name): def _access_possible(self, name):

View File

@@ -216,11 +216,14 @@ def is_scope(node):
def _get_parent_scope_cache(func): def _get_parent_scope_cache(func):
cache = WeakKeyDictionary() cache = WeakKeyDictionary()
def wrapper(used_names, node, include_flows=False): def wrapper(parso_cache_node, node, include_flows=False):
if parso_cache_node is None:
return func(node, include_flows)
try: try:
for_module = cache[used_names] for_module = cache[parso_cache_node]
except KeyError: except KeyError:
for_module = cache[used_names] = {} for_module = cache[parso_cache_node] = {}
try: try:
return for_module[node] return for_module[node]
@@ -274,6 +277,13 @@ def get_cached_code_lines(grammar, path):
def get_parso_cache_node(grammar, path): def get_parso_cache_node(grammar, path):
"""
This is of course not public. But as long as I control parso, this
shouldn't be a problem. ~ Dave
The reason for this is mostly caching. This is obviously also a sign of a
broken caching architecture.
"""
return parser_cache[grammar._hashed][path] return parser_cache[grammar._hashed][path]

View File

@@ -84,8 +84,5 @@ def test_parser_cache_clear(Script):
del parser_cache[script._inference_state.grammar._hashed][script.path] del parser_cache[script._inference_state.grammar._hashed][script.path]
del script del script
import jedi
jedi.parser_utils.get_cached_parent_scope.__closure__[0].cell_contents.clear()
gc.collect() gc.collect()
assert module_id not in [id(m) for m in gc.get_referrers(tree.Module)] assert module_id not in [id(m) for m in gc.get_referrers(tree.Module)]