forked from VimPlug/jedi
refactor fast_parent_copy, use new_elements_default to hand in a dictionary, that contains all the generated duplicates.
This commit is contained in:
@@ -5,11 +5,11 @@ from jedi.parser import representation as pr
|
||||
from jedi import debug
|
||||
|
||||
|
||||
def fast_parent_copy(obj):
|
||||
def fast_parent_copy(obj, new_elements_default=None):
|
||||
"""
|
||||
Much, much faster than copy.deepcopy, but just for certain elements.
|
||||
"""
|
||||
new_elements = {}
|
||||
new_elements = new_elements_default or {}
|
||||
accept = (pr.Simple, pr.NamePart)
|
||||
|
||||
def recursion(obj):
|
||||
@@ -18,6 +18,9 @@ def fast_parent_copy(obj):
|
||||
# correctly, don't know why.
|
||||
obj.get_defined_names()
|
||||
|
||||
try:
|
||||
return new_elements[obj]
|
||||
except KeyError:
|
||||
new_obj = copy.copy(obj)
|
||||
new_elements[obj] = new_obj
|
||||
|
||||
@@ -48,9 +51,6 @@ def fast_parent_copy(obj):
|
||||
elif isinstance(value, (list, tuple)):
|
||||
setattr(new_obj, key, list_or_tuple_rec(value))
|
||||
elif isinstance(value, accept):
|
||||
try:
|
||||
setattr(new_obj, key, new_elements[value])
|
||||
except KeyError:
|
||||
setattr(new_obj, key, recursion(value))
|
||||
return new_obj
|
||||
|
||||
@@ -61,9 +61,6 @@ def fast_parent_copy(obj):
|
||||
copied_array = array_obj[:] # lists, tuples, strings, unicode
|
||||
for i, el in enumerate(copied_array):
|
||||
if isinstance(el, accept):
|
||||
try:
|
||||
copied_array[i] = new_elements[el]
|
||||
except KeyError:
|
||||
copied_array[i] = recursion(el)
|
||||
elif isinstance(el, (tuple, list)):
|
||||
copied_array[i] = list_or_tuple_rec(el)
|
||||
|
||||
@@ -507,6 +507,11 @@ class FunctionExecution(Executed):
|
||||
multiple calls to functions and recursion has to be avoided. But this is
|
||||
responsibility of the decorators.
|
||||
"""
|
||||
def __init__(self, evaluator, base, *args, **kwargs):
|
||||
super(FunctionExecution, self).__init__(evaluator, base, *args, **kwargs)
|
||||
# for fast_parent_copy
|
||||
self._copy_dict = {base.base_func: self}
|
||||
|
||||
@memoize_default(default=())
|
||||
@recursion.execution_recursion_decorator
|
||||
def get_return_types(self):
|
||||
@@ -571,13 +576,13 @@ class FunctionExecution(Executed):
|
||||
objects = []
|
||||
for element in attr:
|
||||
if element is None:
|
||||
copied = element
|
||||
copied = None
|
||||
else:
|
||||
copied = helpers.fast_parent_copy(element)
|
||||
copied.parent = self._scope_copy(copied.parent)
|
||||
self._scope_copy(element.parent)
|
||||
copied = helpers.fast_parent_copy(element, self._copy_dict)
|
||||
# TODO remove? Doesn't make sense, at least explain.
|
||||
if isinstance(copied, pr.Function):
|
||||
copied = Function(self._evaluator, copied)
|
||||
#if isinstance(copied, pr.Function):
|
||||
#copied = Function(self._evaluator, copied)
|
||||
objects.append(copied)
|
||||
return objects
|
||||
|
||||
@@ -596,8 +601,9 @@ class FunctionExecution(Executed):
|
||||
if scope.start_pos == self.start_pos:
|
||||
return self
|
||||
else:
|
||||
copied = helpers.fast_parent_copy(scope)
|
||||
copied.parent = self._scope_copy(copied.parent)
|
||||
self._scope_copy(scope.parent)
|
||||
copied = helpers.fast_parent_copy(scope, self._copy_dict)
|
||||
#copied.parent = self._scope_copy(copied.parent)
|
||||
return copied
|
||||
|
||||
@common.safe_property
|
||||
|
||||
@@ -43,11 +43,12 @@ def fooooo(obj):
|
||||
|
||||
|
||||
def fooooo2(obj):
|
||||
if isinstance(obj, datetime.datetime):
|
||||
if isinstance(obj, datetime.date):
|
||||
return obj
|
||||
else:
|
||||
return 1
|
||||
|
||||
a
|
||||
# In earlier versions of Jedi, this returned both datetime and int, but now
|
||||
# Jedi does flow checks and realizes that the top return isn't executed.
|
||||
#? int()
|
||||
|
||||
Reference in New Issue
Block a user