diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2015-10-11 19:14:45 +0300 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2015-10-11 19:14:45 +0300 |
commit | 5e926cc63701a54f8982fa1adb4ccb70f2067133 (patch) | |
tree | 33c0d1880129cb48db86029543db5140aabe5c1a | |
parent | fe16fb4d0ef01db3eb1411a8a278cb5839b078f6 (diff) | |
download | astroid-5e926cc63701a54f8982fa1adb4ccb70f2067133.tar.gz |
Move decorators from bases to decorators module.
-rw-r--r-- | astroid/bases.py | 46 | ||||
-rw-r--r-- | astroid/decorators.py | 48 | ||||
-rw-r--r-- | astroid/inference.py | 39 | ||||
-rw-r--r-- | astroid/protocols.py | 17 | ||||
-rw-r--r-- | astroid/tests/unittest_inference.py | 7 |
5 files changed, 81 insertions, 76 deletions
diff --git a/astroid/bases.py b/astroid/bases.py index 01f7bde..2ba953b 100644 --- a/astroid/bases.py +++ b/astroid/bases.py @@ -22,12 +22,9 @@ inference utils. from __future__ import print_function import collections -import functools import sys import warnings -import wrapt - from astroid import context as contextmod from astroid import exceptions from astroid import util @@ -424,46 +421,3 @@ class Generator(Instance): def __str__(self): return 'Generator(%s)' % (self._proxied.name) - -# decorators ################################################################## - -def path_wrapper(func): - """return the given infer function wrapped to handle the path""" - # TODO: switch this to wrapt after the monkey-patching is fixed (ceridwen) - @functools.wraps(func) - def wrapped(node, context=None, _func=func, **kwargs): - """wrapper function handling context""" - if context is None: - context = contextmod.InferenceContext() - if context.push(node): - return - - yielded = set() - for res in _func(node, context, **kwargs): - # unproxy only true instance, not const, tuple, dict... - if res.__class__ is Instance: - ares = res._proxied - else: - ares = res - if ares not in yielded: - yield res - yielded.add(ares) - return wrapped - -@wrapt.decorator -def yes_if_nothing_inferred(func, instance, args, kwargs): - inferred = False - for node in func(*args, **kwargs): - inferred = True - yield node - if not inferred: - yield util.YES - -@wrapt.decorator -def raise_if_nothing_inferred(func, instance, args, kwargs): - inferred = False - for node in func(*args, **kwargs): - inferred = True - yield node - if not inferred: - raise exceptions.InferenceError() diff --git a/astroid/decorators.py b/astroid/decorators.py index 2303f41..0709744 100644 --- a/astroid/decorators.py +++ b/astroid/decorators.py @@ -21,8 +21,12 @@ """ A few useful function/method decorators.""" +import functools + import wrapt +from astroid import context as contextmod +from astroid import exceptions from astroid import util @@ -75,3 +79,47 @@ class cachedproperty(object): val = self.wrapped(inst) setattr(inst, self.wrapped.__name__, val) return val + + +def path_wrapper(func): + """return the given infer function wrapped to handle the path""" + # TODO: switch this to wrapt after the monkey-patching is fixed (ceridwen) + @functools.wraps(func) + def wrapped(node, context=None, _func=func, **kwargs): + """wrapper function handling context""" + if context is None: + context = contextmod.InferenceContext() + if context.push(node): + return + + yielded = set() + for res in _func(node, context, **kwargs): + # unproxy only true instance, not const, tuple, dict... + if res.__class__.__name__ == 'Instance': + ares = res._proxied + else: + ares = res + if ares not in yielded: + yield res + yielded.add(ares) + return wrapped + + +@wrapt.decorator +def yes_if_nothing_inferred(func, instance, args, kwargs): + inferred = False + for node in func(*args, **kwargs): + inferred = True + yield node + if not inferred: + yield util.YES + + +@wrapt.decorator +def raise_if_nothing_inferred(func, instance, args, kwargs): + inferred = False + for node in func(*args, **kwargs): + inferred = True + yield node + if not inferred: + raise exceptions.InferenceError() diff --git a/astroid/inference.py b/astroid/inference.py index 16d6913..58194fa 100644 --- a/astroid/inference.py +++ b/astroid/inference.py @@ -29,6 +29,7 @@ import operator from astroid import bases from astroid import context as contextmod from astroid import exceptions +from astroid import decorators from astroid import helpers from astroid import manager from astroid import nodes @@ -94,12 +95,12 @@ def infer_name(self, context=None): context = context.clone() context.lookupname = self.name return bases._infer_stmts(stmts, context, frame) -nodes.Name._infer = bases.path_wrapper(infer_name) +nodes.Name._infer = decorators.path_wrapper(infer_name) nodes.AssignName.infer_lhs = infer_name # won't work with a path wrapper -@bases.raise_if_nothing_inferred -@bases.path_wrapper +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper def infer_call(self, context=None): """infer a Call node by trying to guess what the function returns""" callcontext = context.clone() @@ -120,7 +121,7 @@ def infer_call(self, context=None): nodes.Call._infer = infer_call -@bases.path_wrapper +@decorators.path_wrapper def infer_import(self, context=None, asname=True): """infer an Import node: return the imported module/object""" name = context.lookupname @@ -140,7 +141,7 @@ def infer_name_module(self, name): nodes.Import.infer_name_module = infer_name_module -@bases.path_wrapper +@decorators.path_wrapper def infer_import_from(self, context=None, asname=True): """infer a ImportFrom node: return the imported module/object""" name = context.lookupname @@ -159,7 +160,7 @@ def infer_import_from(self, context=None, asname=True): nodes.ImportFrom._infer = infer_import_from -@bases.raise_if_nothing_inferred +@decorators.raise_if_nothing_inferred def infer_attribute(self, context=None): """infer an Attribute node by using getattr on the associated object""" for owner in self.expr.infer(context): @@ -176,11 +177,11 @@ def infer_attribute(self, context=None): except AttributeError: # XXX method / function context.boundnode = None -nodes.Attribute._infer = bases.path_wrapper(infer_attribute) +nodes.Attribute._infer = decorators.path_wrapper(infer_attribute) nodes.AssignAttr.infer_lhs = infer_attribute # # won't work with a path wrapper -@bases.path_wrapper +@decorators.path_wrapper def infer_global(self, context=None): if context.lookupname is None: raise exceptions.InferenceError() @@ -220,7 +221,7 @@ def _slice_value(index, context=None): return _SLICE_SENTINEL -@bases.raise_if_nothing_inferred +@decorators.raise_if_nothing_inferred def infer_subscript(self, context=None): """Inference for subscripts @@ -272,12 +273,12 @@ def infer_subscript(self, context=None): for inferred in assigned.infer(context): yield inferred -nodes.Subscript._infer = bases.path_wrapper(infer_subscript) +nodes.Subscript._infer = decorators.path_wrapper(infer_subscript) nodes.Subscript.infer_lhs = infer_subscript -@bases.raise_if_nothing_inferred -@bases.path_wrapper +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper def _infer_boolop(self, context=None): """Infer a boolean operation (and / or / not). @@ -387,8 +388,8 @@ def _infer_unaryop(self, context=None): yield util.YES -@bases.raise_if_nothing_inferred -@bases.path_wrapper +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper def infer_unaryop(self, context=None): """Infer what an UnaryOp should return when evaluated.""" return _filter_operation_errors(self, _infer_unaryop, context, @@ -600,8 +601,8 @@ def _infer_binop(self, context): yield result -@bases.yes_if_nothing_inferred -@bases.path_wrapper +@decorators.yes_if_nothing_inferred +@decorators.path_wrapper def infer_binop(self, context=None): return _filter_operation_errors(self, _infer_binop, context, exceptions.BinaryOperationError) @@ -640,7 +641,7 @@ def _infer_augassign(self, context=None): yield result -@bases.path_wrapper +@decorators.path_wrapper def infer_augassign(self, context=None): return _filter_operation_errors(self, _infer_augassign, context, exceptions.BinaryOperationError) @@ -659,7 +660,7 @@ def infer_arguments(self, context=None): nodes.Arguments._infer = infer_arguments -@bases.path_wrapper +@decorators.path_wrapper def infer_assign(self, context=None): """infer a AssignName/AssignAttr: need to inspect the RHS part of the assign node @@ -676,7 +677,7 @@ nodes.AssignAttr._infer = infer_assign # no infer method on DelName and DelAttr (expected InferenceError) -@bases.path_wrapper +@decorators.path_wrapper def infer_empty_node(self, context=None): if not self.has_underlying_object(): yield util.YES diff --git a/astroid/protocols.py b/astroid/protocols.py index 2780573..8bd3813 100644 --- a/astroid/protocols.py +++ b/astroid/protocols.py @@ -29,6 +29,7 @@ from astroid import arguments from astroid import bases from astroid import context as contextmod from astroid import exceptions +from astroid import decorators from astroid import node_classes from astroid import nodes from astroid import util @@ -113,7 +114,7 @@ for _KEY, _IMPL in list(BIN_OP_IMPL.items()): BIN_OP_IMPL[_KEY + '='] = _IMPL -@bases.yes_if_nothing_inferred +@decorators.yes_if_nothing_inferred def const_infer_binary_op(self, operator, other, context, _): not_implemented = nodes.Const(NotImplemented) if isinstance(other, nodes.Const): @@ -145,7 +146,7 @@ def _multiply_seq_by_int(self, other, context): return node -@bases.yes_if_nothing_inferred +@decorators.yes_if_nothing_inferred def tl_infer_binary_op(self, operator, other, context, method): not_implemented = nodes.Const(NotImplemented) if isinstance(other, self.__class__) and operator == '+': @@ -175,7 +176,7 @@ nodes.Tuple.infer_binary_op = tl_infer_binary_op nodes.List.infer_binary_op = tl_infer_binary_op -@bases.yes_if_nothing_inferred +@decorators.yes_if_nothing_inferred def instance_infer_binary_op(self, operator, other, context, method): return method.infer_call_result(self, context) @@ -233,7 +234,7 @@ def _resolve_looppart(parts, asspath, context): break -@bases.raise_if_nothing_inferred +@decorators.raise_if_nothing_inferred def for_assigned_stmts(self, node, context=None, asspath=None): if asspath is None: for lst in self.iter.infer(context): @@ -322,7 +323,7 @@ def arguments_assigned_stmts(self, node, context, asspath=None): nodes.Arguments.assigned_stmts = arguments_assigned_stmts -@bases.raise_if_nothing_inferred +@decorators.raise_if_nothing_inferred def assign_assigned_stmts(self, node, context=None, asspath=None): if not asspath: yield self.value @@ -363,7 +364,7 @@ def _resolve_asspart(parts, asspath, context): return -@bases.raise_if_nothing_inferred +@decorators.raise_if_nothing_inferred def excepthandler_assigned_stmts(self, node, context=None, asspath=None): for assigned in node_classes.unpack_infer(self.type): if isinstance(assigned, nodes.ClassDef): @@ -417,7 +418,7 @@ def _infer_context_manager(self, mgr, context): yield result -@bases.raise_if_nothing_inferred +@decorators.raise_if_nothing_inferred def with_assigned_stmts(self, node, context=None, asspath=None): """Infer names and other nodes from a *with* statement. @@ -458,7 +459,7 @@ def with_assigned_stmts(self, node, context=None, asspath=None): nodes.With.assigned_stmts = with_assigned_stmts -@bases.yes_if_nothing_inferred +@decorators.yes_if_nothing_inferred def starred_assigned_stmts(self, node=None, context=None, asspath=None): stmt = self.statement() if not isinstance(stmt, (nodes.Assign, nodes.For)): diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py index 9c80a92..6756838 100644 --- a/astroid/tests/unittest_inference.py +++ b/astroid/tests/unittest_inference.py @@ -29,8 +29,9 @@ from astroid import InferenceError, builder, nodes from astroid.builder import parse from astroid.inference import infer_end as inference_infer_end from astroid.bases import Instance, BoundMethod, UnboundMethod,\ - path_wrapper, BUILTINS + BUILTINS from astroid import arguments +from astroid import decorators as decoratorsmod from astroid import helpers from astroid import objects from astroid import test_utils @@ -56,8 +57,8 @@ class InferenceUtilsTest(unittest.TestCase): def test_path_wrapper(self): def infer_default(self, *args): raise InferenceError - infer_default = path_wrapper(infer_default) - infer_end = path_wrapper(inference_infer_end) + infer_default = decoratorsmod.path_wrapper(infer_default) + infer_end = decoratorsmod.path_wrapper(inference_infer_end) with self.assertRaises(InferenceError): next(infer_default(1)) self.assertEqual(next(infer_end(1)), 1) |