This commit is contained in:
Dave Halter
2014-08-22 00:46:24 +02:00
parent 6ba0b7b81e
commit ed3b507ab7
2 changed files with 18 additions and 29 deletions
+2 -1
View File
@@ -7,7 +7,8 @@ from jedi import debug
def fast_parent_copy(obj, new_elements_default=None): 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 Parser elements (Doesn't
copy parents).
""" """
new_elements = new_elements_default or {} new_elements = new_elements_default or {}
accept = (pr.Simple, pr.NamePart, pr.KeywordStatement) accept = (pr.Simple, pr.NamePart, pr.KeywordStatement)
+16 -28
View File
@@ -567,25 +567,19 @@ class FunctionExecution(Executed):
names = pr.filter_after_position(pr.Scope.get_defined_names(self), position) names = pr.filter_after_position(pr.Scope.get_defined_names(self), position)
yield self, self._get_params() + names yield self, self._get_params() + names
def _copy_properties(self, prop): def _copy_list(self, list_name):
""" """
Literally copies a property of a Function. Copying is very expensive, Copies a list attribute of a parser Function. Copying is very
because it is something like `copy.deepcopy`. However, these copied expensive, because it is something like `copy.deepcopy`. However, these
objects can be used for the executions, as if they were in the copied objects can be used for the executions, as if they were in the
execution. execution.
""" """
# Copy all these lists into this local function. # Copy all these lists into this local function.
attr = getattr(self.base, prop) lst = getattr(self.base, list_name)
objects = [] objects = []
for element in attr: for element in lst:
if element is None: self._scope_copy(element.parent)
copied = None copied = helpers.fast_parent_copy(element, self._copy_dict)
else:
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)
objects.append(copied) objects.append(copied)
return objects return objects
@@ -594,38 +588,32 @@ class FunctionExecution(Executed):
raise AttributeError('Tried to access %s: %s. Why?' % (name, self)) raise AttributeError('Tried to access %s: %s. Why?' % (name, self))
return getattr(self.base, name) return getattr(self.base, name)
@memoize_default()
def _scope_copy(self, scope): def _scope_copy(self, scope):
""" Copies a scope (e.g. if) in an execution """ """ Copies a scope (e.g. `if foo:`) in an execution """
# just check the start_pos, sometimes it's difficult with closures if scope != self.base.base_func:
# to compare the scopes directly. # Just make sure the parents been copied.
if scope.start_pos == self.start_pos:
return self
else:
self._scope_copy(scope.parent) self._scope_copy(scope.parent)
copied = helpers.fast_parent_copy(scope, self._copy_dict) helpers.fast_parent_copy(scope, self._copy_dict)
#copied.parent = self._scope_copy(copied.parent)
return copied
@common.safe_property @common.safe_property
@memoize_default([]) @memoize_default([])
def returns(self): def returns(self):
return self._copy_properties('returns') return self._copy_list('returns')
@common.safe_property @common.safe_property
@memoize_default([]) @memoize_default([])
def asserts(self): def asserts(self):
return self._copy_properties('asserts') return self._copy_list('asserts')
@common.safe_property @common.safe_property
@memoize_default([]) @memoize_default([])
def statements(self): def statements(self):
return self._copy_properties('statements') return self._copy_list('statements')
@common.safe_property @common.safe_property
@memoize_default([]) @memoize_default([])
def subscopes(self): def subscopes(self):
return self._copy_properties('subscopes') return self._copy_list('subscopes')
def get_statement_for_position(self, pos): def get_statement_for_position(self, pos):
return pr.Scope.get_statement_for_position(self, pos) return pr.Scope.get_statement_for_position(self, pos)