1
0
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:
Dave Halter
2014-08-21 13:17:33 +02:00
parent 3cf8bfa8e1
commit 0ef030848d
3 changed files with 24 additions and 20 deletions

View File

@@ -5,11 +5,11 @@ from jedi.parser import representation as pr
from jedi import debug 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. Much, much faster than copy.deepcopy, but just for certain elements.
""" """
new_elements = {} new_elements = new_elements_default or {}
accept = (pr.Simple, pr.NamePart) accept = (pr.Simple, pr.NamePart)
def recursion(obj): def recursion(obj):
@@ -18,8 +18,11 @@ def fast_parent_copy(obj):
# correctly, don't know why. # correctly, don't know why.
obj.get_defined_names() obj.get_defined_names()
new_obj = copy.copy(obj) try:
new_elements[obj] = new_obj return new_elements[obj]
except KeyError:
new_obj = copy.copy(obj)
new_elements[obj] = new_obj
try: try:
items = list(new_obj.__dict__.items()) items = list(new_obj.__dict__.items())
@@ -48,10 +51,7 @@ def fast_parent_copy(obj):
elif isinstance(value, (list, tuple)): elif isinstance(value, (list, tuple)):
setattr(new_obj, key, list_or_tuple_rec(value)) setattr(new_obj, key, list_or_tuple_rec(value))
elif isinstance(value, accept): elif isinstance(value, accept):
try: setattr(new_obj, key, recursion(value))
setattr(new_obj, key, new_elements[value])
except KeyError:
setattr(new_obj, key, recursion(value))
return new_obj return new_obj
def list_or_tuple_rec(array_obj): def list_or_tuple_rec(array_obj):
@@ -61,10 +61,7 @@ def fast_parent_copy(obj):
copied_array = array_obj[:] # lists, tuples, strings, unicode copied_array = array_obj[:] # lists, tuples, strings, unicode
for i, el in enumerate(copied_array): for i, el in enumerate(copied_array):
if isinstance(el, accept): if isinstance(el, accept):
try: copied_array[i] = recursion(el)
copied_array[i] = new_elements[el]
except KeyError:
copied_array[i] = recursion(el)
elif isinstance(el, (tuple, list)): elif isinstance(el, (tuple, list)):
copied_array[i] = list_or_tuple_rec(el) copied_array[i] = list_or_tuple_rec(el)

View File

@@ -507,6 +507,11 @@ class FunctionExecution(Executed):
multiple calls to functions and recursion has to be avoided. But this is multiple calls to functions and recursion has to be avoided. But this is
responsibility of the decorators. 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=()) @memoize_default(default=())
@recursion.execution_recursion_decorator @recursion.execution_recursion_decorator
def get_return_types(self): def get_return_types(self):
@@ -571,13 +576,13 @@ class FunctionExecution(Executed):
objects = [] objects = []
for element in attr: for element in attr:
if element is None: if element is None:
copied = element copied = None
else: else:
copied = helpers.fast_parent_copy(element) self._scope_copy(element.parent)
copied.parent = self._scope_copy(copied.parent) copied = helpers.fast_parent_copy(element, self._copy_dict)
# TODO remove? Doesn't make sense, at least explain. # TODO remove? Doesn't make sense, at least explain.
if isinstance(copied, pr.Function): #if isinstance(copied, pr.Function):
copied = Function(self._evaluator, copied) #copied = Function(self._evaluator, copied)
objects.append(copied) objects.append(copied)
return objects return objects
@@ -596,8 +601,9 @@ class FunctionExecution(Executed):
if scope.start_pos == self.start_pos: if scope.start_pos == self.start_pos:
return self return self
else: else:
copied = helpers.fast_parent_copy(scope) self._scope_copy(scope.parent)
copied.parent = self._scope_copy(copied.parent) copied = helpers.fast_parent_copy(scope, self._copy_dict)
#copied.parent = self._scope_copy(copied.parent)
return copied return copied
@common.safe_property @common.safe_property

View File

@@ -43,11 +43,12 @@ def fooooo(obj):
def fooooo2(obj): def fooooo2(obj):
if isinstance(obj, datetime.datetime): if isinstance(obj, datetime.date):
return obj return obj
else: else:
return 1 return 1
a
# In earlier versions of Jedi, this returned both datetime and int, but now # 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. # Jedi does flow checks and realizes that the top return isn't executed.
#? int() #? int()