summaryrefslogtreecommitdiff
path: root/astroid/protocols.py
diff options
context:
space:
mode:
authorHoverHell <hoverhell@gmail.com>2018-04-24 13:10:26 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2018-04-24 12:10:26 +0200
commitceeee09743079d07ffc3918969ab203f766b29e0 (patch)
tree1276a95208f7294b5c2eafadfb148ad39ccc2293 /astroid/protocols.py
parent8575ac1c0bd247bc314f6752355d1ea647dec911 (diff)
downloadastroid-git-ceeee09743079d07ffc3918969ab203f766b29e0.tar.gz
Fix StopIteration raising for python3.7 (#534)
Because we don't support Python 2 any longer in the master branch, we can return values from generators to signal that we want to throw a StopIteration, without actually raising the StopIteration itself.
Diffstat (limited to 'astroid/protocols.py')
-rw-r--r--astroid/protocols.py39
1 files changed, 24 insertions, 15 deletions
diff --git a/astroid/protocols.py b/astroid/protocols.py
index bd1d594f..7ae93976 100644
--- a/astroid/protocols.py
+++ b/astroid/protocols.py
@@ -246,8 +246,8 @@ def _resolve_looppart(parts, asspath, context):
def for_assigned_stmts(self, node=None, context=None, asspath=None):
if isinstance(self, nodes.AsyncFor) or getattr(self, 'is_async', False):
# Skip inferring of async code for now
- raise StopIteration(dict(node=self, unknown=node,
- assign_path=asspath, context=context))
+ return dict(node=self, unknown=node,
+ assign_path=asspath, context=context)
if asspath is None:
for lst in self.iter.infer(context):
if isinstance(lst, (nodes.Tuple, nodes.List)):
@@ -259,8 +259,8 @@ def for_assigned_stmts(self, node=None, context=None, asspath=None):
yield inferred
# Explicit StopIteration to return error information, see comment
# in raise_if_nothing_inferred.
- raise StopIteration(dict(node=self, unknown=node,
- assign_path=asspath, context=context))
+ return dict(node=self, unknown=node,
+ assign_path=asspath, context=context)
nodes.For.assigned_stmts = for_assigned_stmts
nodes.Comprehension.assigned_stmts = for_assigned_stmts
@@ -359,8 +359,8 @@ def assign_assigned_stmts(self, node=None, context=None, asspath=None):
yield inferred
# Explicit StopIteration to return error information, see comment
# in raise_if_nothing_inferred.
- raise StopIteration(dict(node=self, unknown=node,
- assign_path=asspath, context=context))
+ return dict(node=self, unknown=node,
+ assign_path=asspath, context=context)
def assign_annassigned_stmts(self, node=None, context=None, asspath=None):
@@ -414,8 +414,8 @@ def excepthandler_assigned_stmts(self, node=None, context=None, asspath=None):
yield assigned
# Explicit StopIteration to return error information, see comment
# in raise_if_nothing_inferred.
- raise StopIteration(dict(node=self, unknown=node,
- assign_path=asspath, context=context))
+ return dict(node=self, unknown=node,
+ assign_path=asspath, context=context)
nodes.ExceptHandler.assigned_stmts = excepthandler_assigned_stmts
@@ -424,7 +424,7 @@ nodes.ExceptHandler.assigned_stmts = excepthandler_assigned_stmts
def _infer_context_manager(self, mgr, context):
try:
inferred = next(mgr.infer(context=context))
- except exceptions.InferenceError:
+ except (StopIteration, exceptions.InferenceError):
return
if isinstance(inferred, bases.Generator):
# Check if it is decorated with contextlib.contextmanager.
@@ -432,7 +432,10 @@ def _infer_context_manager(self, mgr, context):
if not func.decorators:
return
for decorator_node in func.decorators.nodes:
- decorator = next(decorator_node.infer(context))
+ try:
+ decorator = next(decorator_node.infer(context))
+ except StopIteration:
+ return
if isinstance(decorator, nodes.FunctionDef):
if decorator.qname() == _CONTEXTLIB_MGR:
break
@@ -446,7 +449,8 @@ def _infer_context_manager(self, mgr, context):
possible_yield_points = func.nodes_of_class(nodes.Yield)
# Ignore yields in nested functions
yield_point = next((node for node in possible_yield_points
- if node.scope() == func), None)
+ if node.scope() == func),
+ None)
if yield_point:
if not yield_point.value:
# TODO(cpopa): an empty yield. Should be wrapped to Const.
@@ -460,7 +464,7 @@ def _infer_context_manager(self, mgr, context):
elif isinstance(inferred, bases.Instance):
try:
enter = next(inferred.igetattr('__enter__', context=context))
- except (exceptions.InferenceError, exceptions.AttributeInferenceError):
+ except (StopIteration, exceptions.InferenceError, exceptions.AttributeInferenceError):
return
if not isinstance(enter, bases.BoundMethod):
return
@@ -496,7 +500,10 @@ def with_assigned_stmts(self, node=None, context=None, asspath=None):
context: TODO
asspath: TODO
"""
- mgr = next(mgr for (mgr, vars) in self.items if vars == node)
+ try:
+ mgr = next(mgr for (mgr, vars) in self.items if vars == node)
+ except StopIteration:
+ return
if asspath is None:
for result in _infer_context_manager(self, mgr, context):
yield result
@@ -525,8 +532,8 @@ def with_assigned_stmts(self, node=None, context=None, asspath=None):
yield obj
# Explicit StopIteration to return error information, see comment
# in raise_if_nothing_inferred.
- raise StopIteration(dict(node=self, unknown=node,
- assign_path=asspath, context=context))
+ return dict(node=self, unknown=node,
+ assign_path=asspath, context=context)
nodes.With.assigned_stmts = with_assigned_stmts
@@ -561,6 +568,8 @@ def starred_assigned_stmts(self, node=None, context=None, asspath=None):
context = contextmod.InferenceContext()
try:
rhs = next(value.infer(context))
+ except StopIteration:
+ return
except exceptions.InferenceError:
yield util.Uninferable
return