diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2015-11-05 15:44:59 +0200 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2015-11-05 15:44:59 +0200 |
commit | ef2e48a4842c0d30a3d8379c0570731aab8243ef (patch) | |
tree | 33dfead9c99912efa6970be0632c5157151e96ec | |
parent | 282ee076e73e0683752cafeba9c64156074b5e88 (diff) | |
download | astroid-git-ef2e48a4842c0d30a3d8379c0570731aab8243ef.tar.gz |
The inference functions are implemented as dispatch-functions on virtual base classes, instead of monkey-patching nodes
This has the nice side effect that circular the dependency between inference.py and node_classes
is finally removed.
-rw-r--r-- | astroid/helpers.py | 3 | ||||
-rw-r--r-- | astroid/inference.py | 188 | ||||
-rw-r--r-- | astroid/interpreter/objects.py | 8 | ||||
-rw-r--r-- | astroid/interpreter/runtimeabc.py | 8 | ||||
-rw-r--r-- | astroid/protocols.py | 5 | ||||
-rw-r--r-- | astroid/tree/base.py | 5 | ||||
-rw-r--r-- | astroid/tree/node_classes.py | 50 |
7 files changed, 147 insertions, 120 deletions
diff --git a/astroid/helpers.py b/astroid/helpers.py index 437b39de..a0ba6c18 100644 --- a/astroid/helpers.py +++ b/astroid/helpers.py @@ -26,7 +26,6 @@ from astroid import context as contextmod from astroid import exceptions
from astroid.interpreter import runtimeabc
from astroid import manager
-from astroid import raw_building
from astroid.tree import treeabc
from astroid import util
@@ -35,6 +34,8 @@ BUILTINS = six.moves.builtins.__name__ def _build_proxy_class(cls_name, builtins):
+ # TODO(cpopa): remove this when merging with modular-locals.
+ from astroid import raw_building
proxy = raw_building.build_class(cls_name)
proxy.parent = builtins
return proxy
diff --git a/astroid/inference.py b/astroid/inference.py index 871af194..20efeae7 100644 --- a/astroid/inference.py +++ b/astroid/inference.py @@ -25,39 +25,39 @@ import itertools import operator from astroid import context as contextmod -from astroid import exceptions from astroid import decorators +from astroid import exceptions from astroid import helpers +from astroid.interpreter import runtimeabc +from astroid.interpreter import util as inferenceutil from astroid import manager -from astroid import nodes from astroid import protocols -from astroid.interpreter import util as inferenceutil -from astroid.interpreter import objects +from astroid.tree import treeabc from astroid import util MANAGER = manager.AstroidManager() -# .infer method ############################################################### +@util.singledispatch +def infer(self, context=None): + raise exceptions.InferenceError +@infer.register(treeabc.Module) +@infer.register(treeabc.ClassDef) +@infer.register(treeabc.FunctionDef) +@infer.register(treeabc.Lambda) +@infer.register(treeabc.Const) +@infer.register(treeabc.List) +@infer.register(treeabc.Tuple) +@infer.register(treeabc.Dict) +@infer.register(treeabc.Set) +@infer.register(treeabc.Slice) +@infer.register(runtimeabc.Super) +@infer.register(runtimeabc.FrozenSet) def infer_end(self, context=None): - """inference's end for node such as Module, ClassDef, FunctionDef, - Const... - - """ yield self -nodes.Module._infer = infer_end -nodes.ClassDef._infer = infer_end -nodes.FunctionDef._infer = infer_end -nodes.Lambda._infer = infer_end -nodes.Const._infer = infer_end -nodes.List._infer = infer_end -nodes.Tuple._infer = infer_end -nodes.Dict._infer = infer_end -nodes.Set._infer = infer_end -nodes.Slice._infer = infer_end def _higher_function_scope(node): @@ -73,11 +73,12 @@ def _higher_function_scope(node): which encloses the given node. """ current = node - while current.parent and not isinstance(current.parent, nodes.FunctionDef): + while current.parent and not isinstance(current.parent, treeabc.FunctionDef): current = current.parent if current and current.parent: return current.parent + def infer_name(self, context=None): """infer a Name: use name lookup rules""" frame, stmts = self.lookup(self.name) @@ -94,10 +95,11 @@ def infer_name(self, context=None): context = context.clone() context.lookupname = self.name return inferenceutil.infer_stmts(stmts, context, frame) -nodes.Name._infer = decorators.path_wrapper(infer_name) -nodes.AssignName.infer_lhs = infer_name # won't work with a path wrapper + +infer.register(treeabc.Name, decorators.path_wrapper(infer_name)) +@infer.register(treeabc.Call) @decorators.raise_if_nothing_inferred @decorators.path_wrapper def infer_call(self, context=None): @@ -117,9 +119,9 @@ def infer_call(self, context=None): except exceptions.InferenceError: ## XXX log error ? continue -nodes.Call._infer = infer_call +@infer.register(treeabc.Import) @decorators.path_wrapper def infer_import(self, context=None, asname=True): """infer an Import node: return the imported module/object""" @@ -130,16 +132,9 @@ def infer_import(self, context=None, asname=True): yield self.do_import_module(self.real_name(name)) else: yield self.do_import_module(name) -nodes.Import._infer = infer_import - - -def infer_name_module(self, name): - context = contextmod.InferenceContext() - context.lookupname = name - return self.infer(context, asname=False) -nodes.Import.infer_name_module = infer_name_module +@infer.register(treeabc.ImportFrom) @decorators.path_wrapper def infer_import_from(self, context=None, asname=True): """infer a ImportFrom node: return the imported module/object""" @@ -156,7 +151,6 @@ def infer_import_from(self, context=None, asname=True): return inferenceutil.infer_stmts(stmts, context) except exceptions.NotFoundError: util.reraise(exceptions.InferenceError(name)) -nodes.ImportFrom._infer = infer_import_from @decorators.raise_if_nothing_inferred @@ -176,10 +170,11 @@ def infer_attribute(self, context=None): except AttributeError: # XXX method / function context.boundnode = None -nodes.Attribute._infer = decorators.path_wrapper(infer_attribute) -nodes.AssignAttr.infer_lhs = infer_attribute # # won't work with a path wrapper +infer.register(treeabc.Attribute, decorators.path_wrapper(infer_attribute)) + +@infer.register(treeabc.Global) @decorators.path_wrapper def infer_global(self, context=None): if context.lookupname is None: @@ -189,14 +184,13 @@ def infer_global(self, context=None): context) except exceptions.NotFoundError: util.reraise(exceptions.InferenceError()) -nodes.Global._infer = infer_global _SLICE_SENTINEL = object() def _slice_value(index, context=None): """Get the value of the given slice index.""" - if isinstance(index, nodes.Const): + if isinstance(index, treeabc.Const): if isinstance(index.value, (int, type(None))): return index.value elif index is None: @@ -210,7 +204,7 @@ def _slice_value(index, context=None): except exceptions.InferenceError: pass else: - if isinstance(inferred, nodes.Const): + if isinstance(inferred, treeabc.Const): if isinstance(inferred.value, (int, type(None))): return inferred.value @@ -240,20 +234,20 @@ def infer_subscript(self, context=None): yield util.YES return - if value.__class__ == objects.Instance: + if value.__class__.__name__ == 'Instance': index_value = index else: index_value = _SLICE_SENTINEL - if isinstance(index, nodes.Const): + if isinstance(index, treeabc.Const): index_value = index.value - elif isinstance(index, nodes.Slice): + elif isinstance(index, treeabc.Slice): # Infer slices from the original object. lower = _slice_value(index.lower, context) upper = _slice_value(index.upper, context) step = _slice_value(index.step, context) if all(elem is not _SLICE_SENTINEL for elem in (lower, upper, step)): index_value = slice(lower, upper, step) - elif isinstance(index, objects.Instance): + elif isinstance(index, runtimeabc.Instance): index = inferenceutil.class_instance_as_index(index) if index: index_value = index.value @@ -276,10 +270,10 @@ def infer_subscript(self, context=None): for inferred in assigned.infer(context): yield inferred -nodes.Subscript._infer = decorators.path_wrapper(infer_subscript) -nodes.Subscript.infer_lhs = infer_subscript +infer.register(treeabc.Subscript, decorators.path_wrapper(infer_subscript)) +@infer.register(treeabc.BoolOp) @decorators.raise_if_nothing_inferred @decorators.path_wrapper def _infer_boolop(self, context=None): @@ -330,8 +324,6 @@ def _infer_boolop(self, context=None): else: yield value -nodes.BoolOp._infer = _infer_boolop - # UnaryOp, BinOp and AugAssign inferences @@ -346,7 +338,7 @@ def _filter_operation_errors(self, infer_callable, context, error): yield result -def _infer_unaryop(self, context=None): +def infer_unaryop(self, context=None, nodes=None): """Infer what an UnaryOp should return when evaluated.""" for operand in self.operand.infer(context): try: @@ -366,7 +358,7 @@ def _infer_unaryop(self, context=None): else: yield util.YES else: - if not isinstance(operand, objects.Instance): + if not isinstance(operand, runtimeabc.Instance): # The operation was used on something which # doesn't support it. yield exceptions.UnaryOperationError(operand, self.op, exc) @@ -396,38 +388,37 @@ def _infer_unaryop(self, context=None): @decorators.raise_if_nothing_inferred @decorators.path_wrapper -def infer_unaryop(self, context=None): +def filtered_infer_unaryop(self, context=None, nodes=None): """Infer what an UnaryOp should return when evaluated.""" - return _filter_operation_errors(self, _infer_unaryop, context, + with_nodes_func = functools.partial(infer_unaryop, nodes=nodes) + return _filter_operation_errors(self, with_nodes_func, context, exceptions.UnaryOperationError) -nodes.UnaryOp._infer_unaryop = _infer_unaryop -nodes.UnaryOp._infer = infer_unaryop - def _is_not_implemented(const): """Check if the given const node is NotImplemented.""" - return isinstance(const, nodes.Const) and const.value is NotImplemented + return isinstance(const, treeabc.Const) and const.value is NotImplemented -def _invoke_binop_inference(instance, op, other, context, method_name): +def _invoke_binop_inference(instance, op, other, context, method_name, nodes): """Invoke binary operation inference on the given instance.""" method = instance.getattr(method_name)[0] inferred = next(method.infer(context=context)) return protocols.infer_binary_op(instance, op, other, context, inferred, nodes) -def _aug_op(instance, op, other, context, reverse=False): +def _aug_op(instance, op, other, context, nodes, reverse=False): """Get an inference callable for an augmented binary operation.""" method_name = protocols.AUGMENTED_OP_METHOD[op] return functools.partial(_invoke_binop_inference, instance=instance, op=op, other=other, context=context, - method_name=method_name) + method_name=method_name, + nodes=nodes) -def _bin_op(instance, op, other, context, reverse=False): +def _bin_op(instance, op, other, context, nodes, reverse=False): """Get an inference callable for a normal binary operation. If *reverse* is True, then the reflected method will be used instead. @@ -440,7 +431,8 @@ def _bin_op(instance, op, other, context, reverse=False): instance=instance, op=op, other=other, context=context, - method_name=method_name) + method_name=method_name, + nodes=nodes) def _get_binop_contexts(context, left, right): @@ -465,7 +457,7 @@ def _same_type(type1, type2): def _get_binop_flow(left, left_type, op, right, right_type, - context, reverse_context): + context, reverse_context, nodes): """Get the flow for binary operations. The rules are a bit messy: @@ -481,20 +473,20 @@ def _get_binop_flow(left, left_type, op, right, right_type, is first tried and then left.__op__(right) """ if _same_type(left_type, right_type): - methods = [_bin_op(left, op, right, context)] + methods = [_bin_op(left, op, right, context, nodes)] elif inferenceutil.is_subtype(left_type, right_type): - methods = [_bin_op(left, op, right, context)] + methods = [_bin_op(left, op, right, context, nodes)] elif inferenceutil.is_supertype(left_type, right_type): - methods = [_bin_op(right, op, left, reverse_context, reverse=True), - _bin_op(left, op, right, context)] + methods = [_bin_op(right, op, left, reverse_context, nodes, reverse=True), + _bin_op(left, op, right, context, nodes)] else: - methods = [_bin_op(left, op, right, context), - _bin_op(right, op, left, reverse_context, reverse=True)] + methods = [_bin_op(left, op, right, context, nodes), + _bin_op(right, op, left, reverse_context, nodes, reverse=True)] return methods def _get_aug_flow(left, left_type, aug_op, right, right_type, - context, reverse_context): + context, reverse_context, nodes): """Get the flow for augmented binary operations. The rules are a bit messy: @@ -512,23 +504,23 @@ def _get_aug_flow(left, left_type, aug_op, right, right_type, """ op = aug_op.strip("=") if _same_type(left_type, right_type): - methods = [_aug_op(left, aug_op, right, context), - _bin_op(left, op, right, context)] + methods = [_aug_op(left, aug_op, right, context, nodes), + _bin_op(left, op, right, context, nodes)] elif inferenceutil.is_subtype(left_type, right_type): - methods = [_aug_op(left, aug_op, right, context), - _bin_op(left, op, right, context)] + methods = [_aug_op(left, aug_op, right, context, nodes), + _bin_op(left, op, right, context, nodes)] elif inferenceutil.is_supertype(left_type, right_type): - methods = [_aug_op(left, aug_op, right, context), - _bin_op(right, op, left, reverse_context, reverse=True), - _bin_op(left, op, right, context)] + methods = [_aug_op(left, aug_op, right, context, nodes), + _bin_op(right, op, left, reverse_context, nodes, reverse=True), + _bin_op(left, op, right, context, nodes)] else: - methods = [_aug_op(left, aug_op, right, context), - _bin_op(left, op, right, context), - _bin_op(right, op, left, reverse_context, reverse=True)] + methods = [_aug_op(left, aug_op, right, context, nodes), + _bin_op(left, op, right, context, nodes), + _bin_op(right, op, left, reverse_context, nodes, reverse=True)] return methods -def _infer_binary_operation(left, right, op, context, flow_factory): +def _infer_binary_operation(left, right, op, context, flow_factory, nodes): """Infer a binary operation between a left operand and a right operand This is used by both normal binary operations and augmented binary @@ -539,12 +531,12 @@ def _infer_binary_operation(left, right, op, context, flow_factory): left_type = helpers.object_type(left) right_type = helpers.object_type(right) methods = flow_factory(left, left_type, op, right, right_type, - context, reverse_context) + context, reverse_context, nodes) for method in methods: try: results = list(method()) except exceptions.BinaryOperationNotSupportedError: - continue + continue except (AttributeError, exceptions.NotFoundError): continue except exceptions.InferenceError: @@ -575,7 +567,7 @@ def _infer_binary_operation(left, right, op, context, flow_factory): yield exceptions.BinaryOperationError(left_type, op, right_type) -def _infer_binop(self, context): +def infer_binop(self, context, nodes): """Binary operation inferrence logic.""" if context is None: context = contextmod.InferenceContext() @@ -601,23 +593,21 @@ def _infer_binop(self, context): yield util.YES return - results = _infer_binary_operation(lhs, rhs, op, - context, _get_binop_flow) + results = _infer_binary_operation(lhs, rhs, op, context, + _get_binop_flow, nodes) for result in results: yield result @decorators.yes_if_nothing_inferred @decorators.path_wrapper -def infer_binop(self, context=None): - return _filter_operation_errors(self, _infer_binop, context, +def filtered_infer_binop(self, context=None, nodes=None): + with_nodes_func = functools.partial(infer_binop, nodes=nodes) + return _filter_operation_errors(self, with_nodes_func, context, exceptions.BinaryOperationError) -nodes.BinOp._infer_binop = _infer_binop -nodes.BinOp._infer = infer_binop - -def _infer_augassign(self, context=None): +def infer_augassign(self, context=None, nodes=None): """Inferrence logic for augmented binary operations.""" if context is None: context = contextmod.InferenceContext() @@ -642,47 +632,46 @@ def _infer_augassign(self, context=None): return results = _infer_binary_operation(lhs, rhs, op, - context, _get_aug_flow) + context, _get_aug_flow, nodes) for result in results: yield result @decorators.path_wrapper -def infer_augassign(self, context=None): - return _filter_operation_errors(self, _infer_augassign, context, +def filtered_infer_augassign(self, context=None, nodes=None): + with_nodes_func = functools.partial(infer_augassign, nodes=nodes) + return _filter_operation_errors(self, with_nodes_func, context, exceptions.BinaryOperationError) -nodes.AugAssign._infer_augassign = _infer_augassign -nodes.AugAssign._infer = infer_augassign # End of binary operation inference. -def infer_arguments(self, context=None): +def infer_arguments(self, context=None, nodes=None): name = context.lookupname if name is None: raise exceptions.InferenceError() return protocols._arguments_infer_argname(self, name, context, nodes) -nodes.Arguments._infer = infer_arguments +@infer.register(treeabc.AssignName) +@infer.register(treeabc.AssignAttr) @decorators.path_wrapper def infer_assign(self, context=None): """infer a AssignName/AssignAttr: need to inspect the RHS part of the assign node """ stmt = self.statement() - if isinstance(stmt, nodes.AugAssign): + if isinstance(stmt, treeabc.AugAssign): return stmt.infer(context) stmts = list(self.assigned_stmts(context=context)) return inferenceutil.infer_stmts(stmts, context) -nodes.AssignName._infer = infer_assign -nodes.AssignAttr._infer = infer_assign # no infer method on DelName and DelAttr (expected InferenceError) +@infer.register(treeabc.EmptyNode) @decorators.path_wrapper def infer_empty_node(self, context=None): if not self.has_underlying_object(): @@ -694,9 +683,8 @@ def infer_empty_node(self, context=None): yield inferred except exceptions.AstroidError: yield util.YES -nodes.EmptyNode._infer = infer_empty_node +@infer.register(treeabc.Index) def infer_index(self, context=None): return self.value.infer(context) -nodes.Index._infer = infer_index diff --git a/astroid/interpreter/objects.py b/astroid/interpreter/objects.py index 1c062878..504b9f9c 100644 --- a/astroid/interpreter/objects.py +++ b/astroid/interpreter/objects.py @@ -342,21 +342,20 @@ class Generator(Instance): return 'Generator(%s)' % (self._proxied.name) +@util.register_implementation(runtimeabc.FrozenSet) class FrozenSet(base.BaseContainer, Instance): """Class representing a FrozenSet composite node.""" def pytype(self): return '%s.frozenset' % BUILTINS - def _infer(self, context=None): - yield self - @decorators.cachedproperty def _proxied(self): builtins = MANAGER.astroid_cache[BUILTINS] return builtins.getattr('frozenset')[0] +@util.register_implementation(runtimeabc.Super) class Super(base.NodeNG): """Proxy class over a super call. @@ -383,9 +382,6 @@ class Super(base.NodeNG): '__class__': self._proxied, } - def _infer(self, context=None): - yield self - def super_mro(self): """Get the MRO which will be used to lookup attributes in this super.""" if not isinstance(self.mro_pointer, treeabc.ClassDef): diff --git a/astroid/interpreter/runtimeabc.py b/astroid/interpreter/runtimeabc.py index 612996ae..ad873ce9 100644 --- a/astroid/interpreter/runtimeabc.py +++ b/astroid/interpreter/runtimeabc.py @@ -46,3 +46,11 @@ class BoundMethod(UnboundMethod): class Generator(RuntimeObject): """Class representing a Generator.""" + + +class Super(RuntimeObject): + """Class representing a super proxy.""" + + +class FrozenSet(RuntimeObject): + """Class representing a frozenset.""" diff --git a/astroid/protocols.py b/astroid/protocols.py index 2ef24716..7eb8a1b1 100644 --- a/astroid/protocols.py +++ b/astroid/protocols.py @@ -28,7 +28,6 @@ import six from astroid import context as contextmod from astroid import decorators from astroid import exceptions -from astroid.interpreter import objects from astroid.interpreter import runtimeabc from astroid.interpreter import util as inferenceutil from astroid.tree import treeabc @@ -304,7 +303,7 @@ def _arguments_infer_argname(self, name, context, nodes): yield cls return if functype == 'method': - yield objects.Instance(self.parent.parent.frame()) + yield self.parent.parent.frame().instanciate_class() return if context and context.callcontext: @@ -394,7 +393,7 @@ def _resolve_asspart(parts, asspath, context): def excepthandler_assigned_stmts(self, nodes, node=None, context=None, asspath=None): for assigned in inferenceutil.unpack_infer(self.type): if isinstance(assigned, treeabc.ClassDef): - assigned = objects.Instance(assigned) + assigned = assigned.instanciate_class() yield assigned diff --git a/astroid/tree/base.py b/astroid/tree/base.py index f4ca188a..f5b598a2 100644 --- a/astroid/tree/base.py +++ b/astroid/tree/base.py @@ -25,6 +25,7 @@ import six from astroid import as_string from astroid import decorators from astroid import exceptions +from astroid import inference from astroid.interpreter import scope from astroid import mixins from astroid.tree import treeabc @@ -75,14 +76,14 @@ class NodeNG(object): pass if not context: - return self._infer(context, **kwargs) + return inference.infer(self, context, **kwargs) key = (self, context.lookupname, context.callcontext, context.boundnode) if key in context.inferred: return iter(context.inferred[key]) - return context.cache_generator(key, self._infer(context, **kwargs)) + return context.cache_generator(key, inference.infer(self, context, **kwargs)) def _repr_name(self): """return self.name or self.attrname or '' for nice representation""" diff --git a/astroid/tree/node_classes.py b/astroid/tree/node_classes.py index 9963e2f5..479d8772 100644 --- a/astroid/tree/node_classes.py +++ b/astroid/tree/node_classes.py @@ -18,6 +18,7 @@ """Module for some node classes. More nodes in scoped_nodes.py """ +import functools import warnings import sys @@ -26,6 +27,7 @@ import six from astroid import context as contextmod from astroid import decorators from astroid import exceptions +from astroid import inference from astroid.interpreter.util import infer_stmts from astroid.interpreter import runtimeabc from astroid.interpreter import objects @@ -255,6 +257,8 @@ class AssignName(LookupMixIn, mixins.ParentAssignTypeMixin, self.name = name super(AssignName, self).__init__(lineno, col_offset, parent) + infer_lhs = inference.infer_name + @util.register_implementation(treeabc.DelName) class DelName(LookupMixIn, mixins.ParentAssignTypeMixin, base.NodeNG): @@ -435,6 +439,8 @@ class AssignAttr(mixins.ParentAssignTypeMixin, def postinit(self, expr=None): self.expr = expr + infer_lhs = inference.infer_attribute + @util.register_implementation(treeabc.Assert) class Assert(Statement): @@ -476,9 +482,9 @@ class AugAssign(mixins.AssignTypeMixin, AssignedStmtsMixin, Statement): self.target = target self.value = value - # This is set by inference.py - def _infer_augassign(self, context=None): - raise NotImplementedError + def _infer_augassign(self, context): + return inference.infer_augassign(self, nodes=sys.modules[__name__], + context=context) def type_errors(self, context=None): """Return a list of TypeErrors which can occur during inference. @@ -520,9 +526,9 @@ class BinOp(base.NodeNG): self.left = left self.right = right - # This is set by inference.py - def _infer_binop(self, context=None): - raise NotImplementedError + def _infer_binop(self, context): + return inference.infer_binop(self, nodes=sys.modules[__name__], + context=context) def type_errors(self, context=None): """Return a list of TypeErrors which can occur during inference. @@ -982,6 +988,11 @@ class Import(mixins.ImportFromMixin, Statement): self.names = names super(Import, self).__init__(lineno, col_offset, parent) + def infer_name_module(self, name): + context = contextmod.InferenceContext() + context.lookupname = name + return self.infer(context, asname=False) + @util.register_implementation(treeabc.Index) class Index(base.NodeNG): @@ -1166,6 +1177,8 @@ class Subscript(base.NodeNG): self.value = value self.slice = slice + infer_lhs = inference.infer_subscript + @util.register_implementation(treeabc.TryExcept) class TryExcept(mixins.BlockRangeMixIn, Statement): @@ -1242,9 +1255,9 @@ class UnaryOp(base.NodeNG): def postinit(self, operand=None): self.operand = operand - # This is set by inference.py def _infer_unaryop(self, context=None): - raise NotImplementedError + return inference.infer_unaryop(self, nodes=sys.modules[__name__], + context=context) def type_errors(self, context=None): """Return a list of TypeErrors which can occur during inference. @@ -1379,3 +1392,24 @@ AssAttr = util.proxy_alias('AssAttr', AssignAttr) Getattr = util.proxy_alias('Getattr', Attribute) CallFunc = util.proxy_alias('CallFunc', Call) From = util.proxy_alias('From', ImportFrom) + + +# Register additional inference dispatched functions. We do +# this here, since we need to pass this module as an argument +# to these functions, in order to avoid circular dependencies +# between inference and node_classes. + +_module = sys.modules[__name__] +inference.infer.register(treeabc.UnaryOp, + functools.partial(inference.filtered_infer_unaryop, + nodes=_module)) +inference.infer.register(treeabc.Arguments, + functools.partial(inference.infer_arguments, + nodes=_module)) +inference.infer.register(treeabc.BinOp, + functools.partial(inference.filtered_infer_binop, + nodes=_module)) +inference.infer.register(treeabc.AugAssign, + functools.partial(inference.filtered_infer_augassign, + nodes=_module)) +del _module |