summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2015-10-11 19:14:45 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2015-10-11 19:14:45 +0300
commit5e926cc63701a54f8982fa1adb4ccb70f2067133 (patch)
tree33c0d1880129cb48db86029543db5140aabe5c1a
parentfe16fb4d0ef01db3eb1411a8a278cb5839b078f6 (diff)
downloadastroid-5e926cc63701a54f8982fa1adb4ccb70f2067133.tar.gz
Move decorators from bases to decorators module.
-rw-r--r--astroid/bases.py46
-rw-r--r--astroid/decorators.py48
-rw-r--r--astroid/inference.py39
-rw-r--r--astroid/protocols.py17
-rw-r--r--astroid/tests/unittest_inference.py7
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)