diff options
author | Eevee (Alex Munroe) <amunroe@yelp.com> | 2014-07-02 17:13:48 -0700 |
---|---|---|
committer | Eevee (Alex Munroe) <amunroe@yelp.com> | 2014-07-02 17:13:48 -0700 |
commit | 58e5e9774ba6a5cb378f2e30eb026489d66922fd (patch) | |
tree | 0b98872d959d4c0959d697f54a4cfa88c544a07f /scoped_nodes.py | |
parent | bbc107fb2afed934eef85c3682aa4b3a20cbe450 (diff) | |
download | astroid-git-58e5e9774ba6a5cb378f2e30eb026489d66922fd.tar.gz |
Fix some deep recursion problems.
They used to be avoided by returning generators in a few places rather
than re-yielding, but I broke that with the context managers. Oops.
So:
- context.push now returns a new context, which should just be passed
into the child generator instead of the original context. This solves
the awkward problem of returning a generator from within a `with`
block, where the block will end before the generator is actually
evaluated.
- The inference cache no longer eagerly evaluates whatever's being
cached; instead it wraps the original generator in a new one that only
caches the results once it's done.
Diffstat (limited to 'scoped_nodes.py')
-rw-r--r-- | scoped_nodes.py | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/scoped_nodes.py b/scoped_nodes.py index 60185717..7e6349df 100644 --- a/scoped_nodes.py +++ b/scoped_nodes.py @@ -886,28 +886,27 @@ class Class(Statement, LocalsDictNodeNG, FilterStmtsMixin): if context is None: context = InferenceContext() for stmt in self.bases: - with context.restore_path(): - try: - for baseobj in stmt.infer(context): - if not isinstance(baseobj, Class): - if isinstance(baseobj, Instance): - baseobj = baseobj._proxied - else: - # duh ? - continue - if baseobj in yielded: - continue # cf xxx above - yielded.add(baseobj) - yield baseobj - if recurs: - for grandpa in baseobj.ancestors(True, context): - if grandpa in yielded: - continue # cf xxx above - yielded.add(grandpa) - yield grandpa - except InferenceError: - # XXX log error ? - continue + try: + for baseobj in stmt.infer(context): + if not isinstance(baseobj, Class): + if isinstance(baseobj, Instance): + baseobj = baseobj._proxied + else: + # duh ? + continue + if baseobj in yielded: + continue # cf xxx above + yielded.add(baseobj) + yield baseobj + if recurs: + for grandpa in baseobj.ancestors(True, context): + if grandpa in yielded: + continue # cf xxx above + yielded.add(grandpa) + yield grandpa + except InferenceError: + # XXX log error ? + continue def local_attr_ancestors(self, name, context=None): """return an iterator on astroid representation of parent classes |