summaryrefslogtreecommitdiff
path: root/astroid/protocols.py
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2018-10-02 09:43:56 +0200
committerClaudiu Popa <pcmanticore@gmail.com>2018-10-02 09:43:56 +0200
commitadd5f7b8eba427de9d39caae864bbc6dc37ef980 (patch)
tree86bb7df77f389062879365e97df0c3d53d38a8a6 /astroid/protocols.py
parentbb46cd198b93f3715da94089d42f39fc910892ff (diff)
downloadastroid-git-add5f7b8eba427de9d39caae864bbc6dc37ef980.tar.gz
Initial formatting of astroid
Diffstat (limited to 'astroid/protocols.py')
-rw-r--r--astroid/protocols.py276
1 files changed, 158 insertions, 118 deletions
diff --git a/astroid/protocols.py b/astroid/protocols.py
index 6a051cc2..77d0ceb4 100644
--- a/astroid/protocols.py
+++ b/astroid/protocols.py
@@ -35,51 +35,53 @@ from astroid import helpers
from astroid import nodes
from astroid import util
-raw_building = util.lazy_import('raw_building')
-objects = util.lazy_import('objects')
+raw_building = util.lazy_import("raw_building")
+objects = util.lazy_import("objects")
+
def _reflected_name(name):
return "__r" + name[2:]
+
def _augmented_name(name):
return "__i" + name[2:]
-_CONTEXTLIB_MGR = 'contextlib.contextmanager'
-BIN_OP_METHOD = {'+': '__add__',
- '-': '__sub__',
- '/': '__truediv__',
- '//': '__floordiv__',
- '*': '__mul__',
- '**': '__pow__',
- '%': '__mod__',
- '&': '__and__',
- '|': '__or__',
- '^': '__xor__',
- '<<': '__lshift__',
- '>>': '__rshift__',
- '@': '__matmul__'
- }
+_CONTEXTLIB_MGR = "contextlib.contextmanager"
+BIN_OP_METHOD = {
+ "+": "__add__",
+ "-": "__sub__",
+ "/": "__truediv__",
+ "//": "__floordiv__",
+ "*": "__mul__",
+ "**": "__pow__",
+ "%": "__mod__",
+ "&": "__and__",
+ "|": "__or__",
+ "^": "__xor__",
+ "<<": "__lshift__",
+ ">>": "__rshift__",
+ "@": "__matmul__",
+}
REFLECTED_BIN_OP_METHOD = {
- key: _reflected_name(value)
- for (key, value) in BIN_OP_METHOD.items()
+ key: _reflected_name(value) for (key, value) in BIN_OP_METHOD.items()
}
AUGMENTED_OP_METHOD = {
- key + "=": _augmented_name(value)
- for (key, value) in BIN_OP_METHOD.items()
+ key + "=": _augmented_name(value) for (key, value) in BIN_OP_METHOD.items()
}
-UNARY_OP_METHOD = {'+': '__pos__',
- '-': '__neg__',
- '~': '__invert__',
- 'not': None, # XXX not '__nonzero__'
- }
+UNARY_OP_METHOD = {
+ "+": "__pos__",
+ "-": "__neg__",
+ "~": "__invert__",
+ "not": None, # XXX not '__nonzero__'
+}
_UNARY_OPERATORS = {
- '+': operator_mod.pos,
- '-': operator_mod.neg,
- '~': operator_mod.invert,
- 'not': operator_mod.not_,
+ "+": operator_mod.pos,
+ "-": operator_mod.neg,
+ "~": operator_mod.invert,
+ "not": operator_mod.not_,
}
@@ -88,6 +90,7 @@ def _infer_unary_op(obj, op):
value = func(obj)
return nodes.const_factory(value)
+
nodes.Tuple.infer_unary_op = lambda self, op: _infer_unary_op(tuple(self.elts), op)
nodes.List.infer_unary_op = lambda self, op: _infer_unary_op(self.elts, op)
nodes.Set.infer_unary_op = lambda self, op: _infer_unary_op(set(self.elts), op)
@@ -96,25 +99,26 @@ nodes.Dict.infer_unary_op = lambda self, op: _infer_unary_op(dict(self.items), o
# Binary operations
-BIN_OP_IMPL = {'+': lambda a, b: a + b,
- '-': lambda a, b: a - b,
- '/': lambda a, b: a / b,
- '//': lambda a, b: a // b,
- '*': lambda a, b: a * b,
- '**': lambda a, b: a ** b,
- '%': lambda a, b: a % b,
- '&': lambda a, b: a & b,
- '|': lambda a, b: a | b,
- '^': lambda a, b: a ^ b,
- '<<': lambda a, b: a << b,
- '>>': lambda a, b: a >> b,
- }
+BIN_OP_IMPL = {
+ "+": lambda a, b: a + b,
+ "-": lambda a, b: a - b,
+ "/": lambda a, b: a / b,
+ "//": lambda a, b: a // b,
+ "*": lambda a, b: a * b,
+ "**": lambda a, b: a ** b,
+ "%": lambda a, b: a % b,
+ "&": lambda a, b: a & b,
+ "|": lambda a, b: a | b,
+ "^": lambda a, b: a ^ b,
+ "<<": lambda a, b: a << b,
+ ">>": lambda a, b: a >> b,
+}
if sys.version_info >= (3, 5):
# MatMult is available since Python 3.5+.
- BIN_OP_IMPL['@'] = operator_mod.matmul
+ BIN_OP_IMPL["@"] = operator_mod.matmul
for _KEY, _IMPL in list(BIN_OP_IMPL.items()):
- BIN_OP_IMPL[_KEY + '='] = _IMPL
+ BIN_OP_IMPL[_KEY + "="] = _IMPL
@decorators.yes_if_nothing_inferred
@@ -128,16 +132,17 @@ def const_infer_binary_op(self, opnode, operator, other, context, _):
except TypeError:
# ArithmeticError is not enough: float >> float is a TypeError
yield not_implemented
- except Exception: # pylint: disable=broad-except
+ except Exception: # pylint: disable=broad-except
yield util.Uninferable
except TypeError:
yield not_implemented
- elif isinstance(self.value, str) and operator == '%':
+ elif isinstance(self.value, str) and operator == "%":
# TODO(cpopa): implement string interpolation later on.
yield util.Uninferable
else:
yield not_implemented
+
nodes.Const.infer_binary_op = const_infer_binary_op
@@ -169,18 +174,18 @@ def _filter_uninferable_nodes(elts, context):
@decorators.yes_if_nothing_inferred
def tl_infer_binary_op(self, opnode, operator, other, context, method):
not_implemented = nodes.Const(NotImplemented)
- if isinstance(other, self.__class__) and operator == '+':
+ if isinstance(other, self.__class__) and operator == "+":
node = self.__class__(parent=opnode)
elts = list(_filter_uninferable_nodes(self.elts, context))
elts += list(_filter_uninferable_nodes(other.elts, context))
node.elts = elts
yield node
- elif isinstance(other, nodes.Const) and operator == '*':
+ elif isinstance(other, nodes.Const) and operator == "*":
if not isinstance(other.value, int):
yield not_implemented
return
yield _multiply_seq_by_int(self, opnode, other, context)
- elif isinstance(other, bases.Instance) and operator == '*':
+ elif isinstance(other, bases.Instance) and operator == "*":
# Verify if the instance supports __index__.
as_index = helpers.class_instance_as_index(other)
if not as_index:
@@ -190,6 +195,7 @@ def tl_infer_binary_op(self, opnode, operator, other, context, method):
else:
yield not_implemented
+
nodes.Tuple.infer_binary_op = tl_infer_binary_op
nodes.List.infer_binary_op = tl_infer_binary_op
@@ -198,6 +204,7 @@ nodes.List.infer_binary_op = tl_infer_binary_op
def instance_class_infer_binary_op(self, opnode, operator, other, context, method):
return method.infer_call_result(self, context)
+
bases.Instance.infer_binary_op = instance_class_infer_binary_op
nodes.ClassDef.infer_binary_op = instance_class_infer_binary_op
@@ -215,6 +222,7 @@ The `context` argument is the current inference context which should be given
to any intermediary inference necessary.
"""
+
def _resolve_looppart(parts, assign_path, context):
"""recursive function to resolve multiple assignments on loops"""
assign_path = assign_path[:]
@@ -223,19 +231,21 @@ def _resolve_looppart(parts, assign_path, context):
if part is util.Uninferable:
continue
# XXX handle __iter__ and log potentially detected errors
- if not hasattr(part, 'itered'):
+ if not hasattr(part, "itered"):
continue
try:
itered = part.itered()
except TypeError:
- continue # XXX log error
+ continue # XXX log error
for stmt in itered:
index_node = nodes.Const(index)
try:
assigned = stmt.getitem(index_node, context)
- except (AttributeError,
- exceptions.AstroidTypeError,
- exceptions.AstroidIndexError):
+ except (
+ AttributeError,
+ exceptions.AstroidTypeError,
+ exceptions.AstroidIndexError,
+ ):
continue
if not assign_path:
# we achieved to resolved the assignment path,
@@ -247,25 +257,26 @@ def _resolve_looppart(parts, assign_path, context):
# we are not yet on the last part of the path
# search on each possibly inferred value
try:
- yield from _resolve_looppart(assigned.infer(context), assign_path, context)
+ yield from _resolve_looppart(
+ assigned.infer(context), assign_path, context
+ )
except exceptions.InferenceError:
break
@decorators.raise_if_nothing_inferred
def for_assigned_stmts(self, node=None, context=None, assign_path=None):
- if isinstance(self, nodes.AsyncFor) or getattr(self, 'is_async', False):
+ if isinstance(self, nodes.AsyncFor) or getattr(self, "is_async", False):
# Skip inferring of async code for now
- return dict(node=self, unknown=node,
- assign_path=assign_path, context=context)
+ return dict(node=self, unknown=node, assign_path=assign_path, context=context)
if assign_path is None:
for lst in self.iter.infer(context):
if isinstance(lst, (nodes.Tuple, nodes.List)):
yield from lst.elts
else:
yield from _resolve_looppart(self.iter.infer(context), assign_path, context)
- return dict(node=self, unknown=node,
- assign_path=assign_path, context=context)
+ return dict(node=self, unknown=node, assign_path=assign_path, context=context)
+
nodes.For.assigned_stmts = for_assigned_stmts
nodes.Comprehension.assigned_stmts = for_assigned_stmts
@@ -278,11 +289,17 @@ def sequence_assigned_stmts(self, node=None, context=None, assign_path=None):
index = self.elts.index(node)
except ValueError as exc:
raise exceptions.InferenceError(
- 'Tried to retrieve a node {node!r} which does not exist',
- node=self, assign_path=assign_path, context=context) from exc
+ "Tried to retrieve a node {node!r} which does not exist",
+ node=self,
+ assign_path=assign_path,
+ context=context,
+ ) from exc
assign_path.insert(0, index)
- return self.parent.assigned_stmts(node=self, context=context, assign_path=assign_path)
+ return self.parent.assigned_stmts(
+ node=self, context=context, assign_path=assign_path
+ )
+
nodes.Tuple.assigned_stmts = sequence_assigned_stmts
nodes.List.assigned_stmts = sequence_assigned_stmts
@@ -290,6 +307,8 @@ nodes.List.assigned_stmts = sequence_assigned_stmts
def assend_assigned_stmts(self, node=None, context=None, assign_path=None):
return self.parent.assigned_stmts(node=self, context=context)
+
+
nodes.AssignName.assigned_stmts = assend_assigned_stmts
nodes.AssignAttr.assigned_stmts = assend_assigned_stmts
@@ -301,22 +320,21 @@ def _arguments_infer_argname(self, name, context):
yield util.Uninferable
return
# first argument of instance/class method
- if self.args and getattr(self.args[0], 'name', None) == name:
+ if self.args and getattr(self.args[0], "name", None) == name:
functype = self.parent.type
cls = self.parent.parent.scope()
- is_metaclass = isinstance(cls, nodes.ClassDef) and cls.type == 'metaclass'
+ is_metaclass = isinstance(cls, nodes.ClassDef) and cls.type == "metaclass"
# If this is a metaclass, then the first argument will always
# be the class, not an instance.
- if is_metaclass or functype == 'classmethod':
+ if is_metaclass or functype == "classmethod":
yield cls
return
- if functype == 'method':
+ if functype == "method":
yield bases.Instance(self.parent.parent.frame())
return
if context and context.callcontext:
- call_site = arguments.CallSite(context.callcontext,
- context.extra_context)
+ call_site = arguments.CallSite(context.callcontext, context.extra_context)
for value in call_site.infer_argument(self.parent, name, context):
yield value
return
@@ -351,6 +369,7 @@ def arguments_assigned_stmts(self, node=None, context=None, assign_path=None):
return args.infer_argument(self.parent, node.name, context)
return _arguments_infer_argname(self, node.name, context)
+
nodes.Arguments.assigned_stmts = arguments_assigned_stmts
@@ -359,10 +378,11 @@ def assign_assigned_stmts(self, node=None, context=None, assign_path=None):
if not assign_path:
yield self.value
return None
- yield from _resolve_assignment_parts(self.value.infer(context), assign_path, context)
+ yield from _resolve_assignment_parts(
+ self.value.infer(context), assign_path, context
+ )
- return dict(node=self, unknown=node,
- assign_path=assign_path, context=context)
+ return dict(node=self, unknown=node, assign_path=assign_path, context=context)
def assign_annassigned_stmts(self, node=None, context=None, assign_path=None):
@@ -372,6 +392,7 @@ def assign_annassigned_stmts(self, node=None, context=None, assign_path=None):
else:
yield inferred
+
nodes.Assign.assigned_stmts = assign_assigned_stmts
nodes.AnnAssign.assigned_stmts = assign_annassigned_stmts
nodes.AugAssign.assigned_stmts = assign_assigned_stmts
@@ -390,7 +411,7 @@ def _resolve_assignment_parts(parts, assign_path, context):
except IndexError:
return
- elif hasattr(part, 'getitem'):
+ elif hasattr(part, "getitem"):
index_node = nodes.Const(index)
try:
assigned = part.getitem(index_node, context)
@@ -412,7 +433,9 @@ def _resolve_assignment_parts(parts, assign_path, context):
# we are not yet on the last part of the path search on each
# possibly inferred value
try:
- yield from _resolve_assignment_parts(assigned.infer(context), assign_path, context)
+ yield from _resolve_assignment_parts(
+ assigned.infer(context), assign_path, context
+ )
except exceptions.InferenceError:
return
@@ -424,8 +447,7 @@ def excepthandler_assigned_stmts(self, node=None, context=None, assign_path=None
assigned = objects.ExceptionInstance(assigned)
yield assigned
- return dict(node=self, unknown=node,
- assign_path=assign_path, context=context)
+ return dict(node=self, unknown=node, assign_path=assign_path, context=context)
nodes.ExceptHandler.assigned_stmts = excepthandler_assigned_stmts
@@ -458,9 +480,9 @@ 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)
+ yield_point = next(
+ (node for node in possible_yield_points if node.scope() == func), None
+ )
if yield_point:
if not yield_point.value:
const = nodes.Const(None)
@@ -471,8 +493,12 @@ def _infer_context_manager(self, mgr, context):
yield from yield_point.value.infer(context=context)
elif isinstance(inferred, bases.Instance):
try:
- enter = next(inferred.igetattr('__enter__', context=context))
- except (StopIteration, exceptions.InferenceError, exceptions.AttributeInferenceError):
+ enter = next(inferred.igetattr("__enter__", context=context))
+ except (
+ StopIteration,
+ exceptions.InferenceError,
+ exceptions.AttributeInferenceError,
+ ):
return
if not isinstance(enter, bases.BoundMethod):
return
@@ -519,26 +545,36 @@ def with_assigned_stmts(self, node=None, context=None, assign_path=None):
# Walk the assign_path and get the item at the final index.
obj = result
for index in assign_path:
- if not hasattr(obj, 'elts'):
+ if not hasattr(obj, "elts"):
raise exceptions.InferenceError(
- 'Wrong type ({targets!r}) for {node!r} assignment',
- node=self, targets=node, assign_path=assign_path,
- context=context)
+ "Wrong type ({targets!r}) for {node!r} assignment",
+ node=self,
+ targets=node,
+ assign_path=assign_path,
+ context=context,
+ )
try:
obj = obj.elts[index]
except IndexError as exc:
raise exceptions.InferenceError(
- 'Tried to infer a nonexistent target with index {index} '
- 'in {node!r}.', node=self, targets=node,
- assign_path=assign_path, context=context) from exc
+ "Tried to infer a nonexistent target with index {index} "
+ "in {node!r}.",
+ node=self,
+ targets=node,
+ assign_path=assign_path,
+ context=context,
+ ) from exc
except TypeError as exc:
raise exceptions.InferenceError(
- 'Tried to unpack a non-iterable value '
- 'in {node!r}.', node=self, targets=node,
- assign_path=assign_path, context=context) from exc
+ "Tried to unpack a non-iterable value " "in {node!r}.",
+ node=self,
+ targets=node,
+ assign_path=assign_path,
+ context=context,
+ ) from exc
yield obj
- return dict(node=self, unknown=node,
- assign_path=assign_path, context=context)
+ return dict(node=self, unknown=node, assign_path=assign_path, context=context)
+
nodes.With.assigned_stmts = with_assigned_stmts
@@ -557,7 +593,10 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
# Determine the lookups for the rhs of the iteration
itered = target.itered()
for index, element in enumerate(itered):
- if isinstance(element, nodes.Starred) and element.value.name == starred.value.name:
+ if (
+ isinstance(element, nodes.Starred)
+ and element.value.name == starred.value.name
+ ):
lookups.append((index, len(itered)))
break
if isinstance(element, nodes.Tuple):
@@ -566,10 +605,13 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
stmt = self.statement()
if not isinstance(stmt, (nodes.Assign, nodes.For)):
- raise exceptions.InferenceError('Statement {stmt!r} enclosing {node!r} '
- 'must be an Assign or For node.',
- node=self, stmt=stmt, unknown=node,
- context=context)
+ raise exceptions.InferenceError(
+ "Statement {stmt!r} enclosing {node!r} " "must be an Assign or For node.",
+ node=self,
+ stmt=stmt,
+ unknown=node,
+ context=context,
+ )
if context is None:
context = contextmod.InferenceContext()
@@ -579,17 +621,20 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
lhs = stmt.targets[0]
if sum(1 for _ in lhs.nodes_of_class(nodes.Starred)) > 1:
- raise exceptions.InferenceError('Too many starred arguments in the '
- ' assignment targets {lhs!r}.',
- node=self, targets=lhs,
- unknown=node, context=context)
+ raise exceptions.InferenceError(
+ "Too many starred arguments in the " " assignment targets {lhs!r}.",
+ node=self,
+ targets=lhs,
+ unknown=node,
+ context=context,
+ )
try:
rhs = next(value.infer(context))
except exceptions.InferenceError:
yield util.Uninferable
return
- if rhs is util.Uninferable or not hasattr(rhs, 'itered'):
+ if rhs is util.Uninferable or not hasattr(rhs, "itered"):
yield util.Uninferable
return
@@ -621,10 +666,7 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
continue
# We're done
packed = nodes.List(
- ctx=Store,
- parent=self,
- lineno=lhs.lineno,
- col_offset=lhs.col_offset,
+ ctx=Store, parent=self, lineno=lhs.lineno, col_offset=lhs.col_offset
)
packed.postinit(elts=elts)
yield packed
@@ -636,7 +678,9 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
except exceptions.InferenceError:
yield util.Uninferable
return
- if inferred_iterable is util.Uninferable or not hasattr(inferred_iterable, 'itered'):
+ if inferred_iterable is util.Uninferable or not hasattr(
+ inferred_iterable, "itered"
+ ):
yield util.Uninferable
return
try:
@@ -649,7 +693,7 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
if not isinstance(target, nodes.Tuple):
raise exceptions.InferenceError(
- 'Could not make sense of this, the target must be a tuple',
+ "Could not make sense of this, the target must be a tuple",
context=context,
)
@@ -657,8 +701,7 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
_determine_starred_iteration_lookups(self, target, lookups)
if not lookups:
raise exceptions.InferenceError(
- 'Could not make sense of this, needs at least a lookup',
- context=context,
+ "Could not make sense of this, needs at least a lookup", context=context
)
# Make the last lookup a slice, since that what we want for a Starred node
@@ -667,7 +710,7 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
lookup_slice = slice(
last_element_index,
- None if is_starred_last else (last_element_length - last_element_index)
+ None if is_starred_last else (last_element_length - last_element_index),
)
lookups[-1] = lookup_slice
@@ -685,7 +728,7 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
found_element = None
for lookup in lookups:
- if not hasattr(element, 'itered'):
+ if not hasattr(element, "itered"):
break
if not isinstance(lookup, slice):
# Grab just the index, not the whole length
@@ -703,10 +746,7 @@ def starred_assigned_stmts(self, node=None, context=None, assign_path=None):
found_element = element
unpacked = nodes.List(
- ctx=Store,
- parent=self,
- lineno=self.lineno,
- col_offset=self.col_offset,
+ ctx=Store, parent=self, lineno=self.lineno, col_offset=self.col_offset
)
unpacked.postinit(elts=found_element or [])
yield unpacked