diff options
-rw-r--r-- | astroid/__init__.py | 3 | ||||
-rw-r--r-- | astroid/bases.py | 38 | ||||
-rw-r--r-- | astroid/brain/builtin_inference.py | 39 | ||||
-rw-r--r-- | astroid/brain/py2stdlib.py | 5 | ||||
-rw-r--r-- | astroid/builder.py | 3 | ||||
-rw-r--r-- | astroid/helpers.py | 9 | ||||
-rw-r--r-- | astroid/inference.py | 81 | ||||
-rw-r--r-- | astroid/node_classes.py | 7 | ||||
-rw-r--r-- | astroid/protocols.py | 33 | ||||
-rw-r--r-- | astroid/scoped_nodes.py | 29 | ||||
-rw-r--r-- | astroid/tests/unittest_brain.py | 3 | ||||
-rw-r--r-- | astroid/tests/unittest_builder.py | 3 | ||||
-rw-r--r-- | astroid/tests/unittest_helpers.py | 9 | ||||
-rw-r--r-- | astroid/tests/unittest_inference.py | 101 | ||||
-rw-r--r-- | astroid/tests/unittest_lookup.py | 3 | ||||
-rw-r--r-- | astroid/tests/unittest_nodes.py | 3 | ||||
-rw-r--r-- | astroid/tests/unittest_protocols.py | 12 | ||||
-rw-r--r-- | astroid/tests/unittest_scoped_nodes.py | 9 | ||||
-rw-r--r-- | astroid/util.py | 38 |
19 files changed, 233 insertions, 195 deletions
diff --git a/astroid/__init__.py b/astroid/__init__.py index c00c678c..aecee7f4 100644 --- a/astroid/__init__.py +++ b/astroid/__init__.py @@ -60,10 +60,11 @@ from astroid import inference # more stuff available from astroid import raw_building -from astroid.bases import YES, Instance, BoundMethod, UnboundMethod +from astroid.bases import Instance, BoundMethod, UnboundMethod from astroid.node_classes import are_exclusive, unpack_infer from astroid.scoped_nodes import builtin_lookup from astroid.builder import parse +from astroid.util import YES # make a manager instance (borg) accessible from astroid package from astroid.manager import AstroidManager diff --git a/astroid/bases.py b/astroid/bases.py index fc17fd57..e30ae156 100644 --- a/astroid/bases.py +++ b/astroid/bases.py @@ -25,6 +25,7 @@ from contextlib import contextmanager from astroid.exceptions import (InferenceError, AstroidError, NotFoundError, UnresolvableName, UseInferenceDefault) from astroid.decorators import cachedproperty +from astroid import util if sys.version_info >= (3, 0): @@ -53,7 +54,7 @@ def _is_property(meth): if PROPERTIES.intersection(meth.decoratornames()): return True stripped = {name.split(".")[-1] for name in meth.decoratornames() - if name is not YES} + if name is not util.YES} return any(name in stripped for name in POSSIBLE_PROPERTIES) @@ -134,7 +135,7 @@ def _infer_stmts(stmts, context, frame=None): context = InferenceContext() for stmt in stmts: - if stmt is YES: + if stmt is util.YES: yield stmt infered = True continue @@ -146,43 +147,24 @@ def _infer_stmts(stmts, context, frame=None): except UnresolvableName: continue except InferenceError: - yield YES + yield util.YES infered = True if not infered: raise InferenceError(str(stmt)) -class _Yes(object): - """Special inference object, which is returned when inference fails.""" - def __repr__(self): - return 'YES' - - def __getattribute__(self, name): - if name == 'next': - raise AttributeError('next method should not be called') - if name.startswith('__') and name.endswith('__'): - return super(_Yes, self).__getattribute__(name) - return self - - def __call__(self, *args, **kwargs): - return self - - -YES = _Yes() - - def _infer_method_result_truth(instance, method_name, context): # Get the method from the instance and try to infer # its return's truth value. meth = next(instance.igetattr(method_name, context=context), None) if meth and hasattr(meth, 'infer_call_result'): for value in meth.infer_call_result(instance, context=context): - if value is YES: + if value is util.YES: return value inferred = next(value.infer(context=context)) return inferred.bool_value() - return YES + return util.YES class Instance(Proxy): @@ -262,7 +244,7 @@ class Instance(Proxy): """infer what a class instance is returning when called""" infered = False for node in self._proxied.igetattr('__call__', context): - if node is YES: + if node is util.YES: continue for res in node.infer_call_result(caller, context): infered = True @@ -350,7 +332,7 @@ class UnboundMethod(Proxy): if (self._proxied.name == '__new__' and self._proxied.parent.frame().qname() == '%s.object' % BUILTINS): infer = caller.args[0].infer() if caller.args else [] - return ((x is YES and x or Instance(x)) for x in infer) + return ((x is util.YES and x or Instance(x)) for x in infer) return self._proxied.infer_call_result(caller, context) def bool_value(self): @@ -427,7 +409,7 @@ def yes_if_nothing_infered(func): infered = True yield node if not infered: - yield YES + yield util.YES return wrapper def raise_if_nothing_infered(func): @@ -730,7 +712,7 @@ class NodeNG(object): * YES: the inference engine is uncertain of the node's value. """ - return YES + return util.YES class Statement(NodeNG): diff --git a/astroid/brain/builtin_inference.py b/astroid/brain/builtin_inference.py index 451d662e..0fede7ea 100644 --- a/astroid/brain/builtin_inference.py +++ b/astroid/brain/builtin_inference.py @@ -6,12 +6,13 @@ from textwrap import dedent import six from astroid import (MANAGER, UseInferenceDefault, NotFoundError, - inference_tip, YES, InferenceError, UnresolvableName) + inference_tip, InferenceError, UnresolvableName) from astroid.builder import AstroidBuilder from astroid import helpers from astroid import nodes from astroid import objects from astroid import scoped_nodes +from astroid import util def _extend_str(class_node, rvalue): @@ -119,10 +120,10 @@ def _generic_inference(node, context, node_type, transform): infered = next(arg.infer(context=context)) except (InferenceError, StopIteration): raise UseInferenceDefault() - if infered is YES: + if infered is util.YES: raise UseInferenceDefault() transformed = transform(infered) - if not transformed or transformed is YES: + if not transformed or transformed is util.YES: raise UseInferenceDefault() return transformed @@ -295,7 +296,7 @@ def infer_super(node, context=None): except InferenceError: raise UseInferenceDefault - if mro_pointer is YES or mro_type is YES: + if mro_pointer is util.YES or mro_type is util.YES: # No way we could understand this. raise UseInferenceDefault @@ -319,11 +320,11 @@ def _infer_getattr_args(node, context): except InferenceError: raise UseInferenceDefault - if obj is YES or attr is YES: + if obj is util.YES or attr is util.YES: # If one of the arguments is something we can't infer, # then also make the result of the getattr call something # which is unknown. - return YES, YES + return util.YES, util.YES is_string = (isinstance(attr, nodes.Const) and isinstance(attr.value, six.string_types)) @@ -341,8 +342,8 @@ def infer_getattr(node, context=None): lookup will be done. """ obj, attr = _infer_getattr_args(node, context) - if obj is YES or attr is YES: - return YES + if obj is util.YES or attr is util.YES: + return util.YES try: return next(obj.igetattr(attr, context=context)) @@ -368,12 +369,12 @@ def infer_hasattr(node, context=None): """ try: obj, attr = _infer_getattr_args(node, context) - if obj is YES or attr is YES: - return YES + if obj is util.YES or attr is util.YES: + return util.YES obj.getattr(attr, context=context) except UseInferenceDefault: # Can't infer something from this function call. - return YES + return util.YES except NotFoundError: # Doesn't have it. return nodes.Const(False) @@ -396,9 +397,9 @@ def infer_callable(node, context=None): try: inferred = next(argument.infer(context=context)) except InferenceError: - return YES - if inferred is YES: - return YES + return util.YES + if inferred is util.YES: + return util.YES return nodes.Const(inferred.callable()) @@ -415,13 +416,13 @@ def infer_bool(node, context=None): try: inferred = next(argument.infer(context=context)) except InferenceError: - return YES - if inferred is YES: - return YES + return util.YES + if inferred is util.YES: + return util.YES bool_value = inferred.bool_value() - if bool_value is YES: - return YES + if bool_value is util.YES: + return util.YES return nodes.Const(bool_value) diff --git a/astroid/brain/py2stdlib.py b/astroid/brain/py2stdlib.py index 206bd8c4..a7e013a9 100644 --- a/astroid/brain/py2stdlib.py +++ b/astroid/brain/py2stdlib.py @@ -12,10 +12,11 @@ from textwrap import dedent from astroid import ( MANAGER, AsStringRegexpPredicate, UseInferenceDefault, inference_tip, BoundMethod, - YES, InferenceError, register_module_extender) + InferenceError, register_module_extender) from astroid import exceptions from astroid import nodes from astroid.builder import AstroidBuilder +from astroid import util PY3K = sys.version_info > (3, 0) PY33 = sys.version_info >= (3, 3) @@ -28,7 +29,7 @@ def infer_func_form(node, base_type, context=None, enum=False): def infer_first(node): try: value = next(node.infer(context=context)) - if value is YES: + if value is util.YES: raise UseInferenceDefault() else: return value diff --git a/astroid/builder.py b/astroid/builder.py index 28246479..5d907c8e 100644 --- a/astroid/builder.py +++ b/astroid/builder.py @@ -33,6 +33,7 @@ from astroid import manager from astroid import modutils from astroid import raw_building from astroid import rebuilder +from astroid import util def _parse(string): @@ -216,7 +217,7 @@ class AstroidBuilder(raw_building.InspectBuilder): try: frame = node.frame() for infered in node.expr.infer(): - if infered is bases.YES: + if infered is util.YES: continue try: if infered.__class__ is bases.Instance: diff --git a/astroid/helpers.py b/astroid/helpers.py index 1148ada3..21dd76c4 100644 --- a/astroid/helpers.py +++ b/astroid/helpers.py @@ -27,6 +27,7 @@ from astroid import exceptions from astroid import manager
from astroid import raw_building
from astroid import scoped_nodes
+from astroid import util
BUILTINS = six.moves.builtins.__name__
@@ -89,9 +90,9 @@ def object_type(node, context=None): try:
types = set(_object_type(node, context))
except exceptions.InferenceError:
- return bases.YES
+ return util.YES
if len(types) > 1 or not types:
- return bases.YES
+ return util.YES
return list(types)[0]
@@ -135,7 +136,7 @@ def has_known_bases(klass, context=None): def _type_check(type1, type2):
if not all(map(has_known_bases, (type1, type2))):
- return bases.YES
+ return util.YES
if not all([type1.newstyle, type2.newstyle]):
return False
@@ -143,7 +144,7 @@ def _type_check(type1, type2): return type1 in type2.mro()[:-1]
except exceptions.MroError:
# The MRO is invalid.
- return bases.YES
+ return util.YES
def is_subtype(type1, type2):
diff --git a/astroid/inference.py b/astroid/inference.py index f05b163c..ae8a5d2f 100644 --- a/astroid/inference.py +++ b/astroid/inference.py @@ -25,6 +25,7 @@ import operator from astroid import helpers from astroid import nodes from astroid import protocols +from astroid import util from astroid.manager import AstroidManager from astroid.exceptions import ( AstroidError, InferenceError, NoDefault, @@ -32,7 +33,7 @@ from astroid.exceptions import ( UnaryOperationError, BinaryOperationError, ) -from astroid.bases import (YES, Instance, InferenceContext, BoundMethod, +from astroid.bases import (Instance, InferenceContext, BoundMethod, _infer_stmts, copy_context, path_wrapper, raise_if_nothing_infered, yes_if_nothing_infered) @@ -88,13 +89,13 @@ class CallContext(object): if self.starargs is not None: its = [] for infered in self.starargs.infer(context): - if infered is YES: - its.append((YES,)) + if infered is util.YES: + its.append((util.YES,)) continue try: its.append(infered.getitem(argindex, context).infer(context)) except (InferenceError, AttributeError): - its.append((YES,)) + its.append((util.YES,)) except (IndexError, TypeError): continue if its: @@ -103,13 +104,13 @@ class CallContext(object): if self.kwargs is not None: its = [] for infered in self.kwargs.infer(context=context): - if infered is YES: - its.append((YES,)) + if infered is util.YES: + its.append((util.YES,)) continue try: its.append(infered.getitem(name, context).infer(context=context)) except (InferenceError, AttributeError): - its.append((YES,)) + its.append((util.YES,)) except (IndexError, TypeError): continue if its: @@ -190,7 +191,7 @@ def infer_callfunc(self, context=None): kwargs=self.kwargs) callcontext.boundnode = None for callee in self.func.infer(context): - if callee is YES: + if callee is util.YES: yield callee continue try: @@ -241,7 +242,7 @@ nodes.From._infer = path_wrapper(infer_from) def infer_getattr(self, context=None): """infer a Getattr node by using getattr on the associated object""" for owner in self.expr.infer(context): - if owner is YES: + if owner is util.YES: yield owner continue try: @@ -271,13 +272,13 @@ nodes.Global._infer = path_wrapper(infer_global) def infer_subscript(self, context=None): """infer simple subscription such as [1,2,3][0] or (1,2,3)[-1]""" value = next(self.value.infer(context)) - if value is YES: - yield YES + if value is util.YES: + yield util.YES return index = next(self.slice.infer(context)) - if index is YES: - yield YES + if index is util.YES: + yield util.YES return if isinstance(index, nodes.Const): @@ -286,13 +287,13 @@ def infer_subscript(self, context=None): except AttributeError: raise InferenceError() except (IndexError, TypeError): - yield YES + yield util.YES return # Prevent inferring if the infered subscript # is the same as the original subscripted object. - if self is assigned or assigned is YES: - yield YES + if self is assigned or assigned is util.YES: + yield util.YES return for infered in assigned.infer(context): yield infered @@ -320,19 +321,19 @@ def _infer_boolop(self, context=None): try: values = [value.infer(context=context) for value in values] except InferenceError: - yield YES + yield util.YES return for pair in itertools.product(*values): - if any(item is YES for item in pair): + if any(item is util.YES for item in pair): # Can't infer the final result, just yield YES. - yield YES + yield util.YES continue bool_values = [item.bool_value() for item in pair] - if any(item is YES for item in bool_values): + if any(item is util.YES for item in bool_values): # Can't infer the final result, just yield YES. - yield YES + yield util.YES continue # Since the boolean operations are short circuited operations, @@ -344,7 +345,7 @@ def _infer_boolop(self, context=None): # 0 and 1 -> 0 # 1 or 0 -> 1 # 0 or 1 -> 1 - value = YES + value = util.YES for value, bool_value in zip(pair, bool_values): if predicate(bool_value): yield value @@ -363,7 +364,7 @@ def _filter_operation_errors(self, infer_callable, context, error): # For the sake of .infer(), we don't care about operation # errors, which is the job of pylint. So return something # which shows that we can't infer the result. - yield YES + yield util.YES else: yield result @@ -383,10 +384,10 @@ def _infer_unaryop(self, context=None): # value and negate its result, unless it is # YES, which will be returned as is. bool_value = operand.bool_value() - if bool_value is not YES: + if bool_value is not util.YES: yield nodes.const_factory(not bool_value) else: - yield YES + yield util.YES else: if not isinstance(operand, Instance): # The operation was used on something which @@ -408,7 +409,7 @@ def _infer_unaryop(self, context=None): # The unary operation special method was not found. yield UnaryOperationError(operand, self.op, exc) except InferenceError: - yield YES + yield util.YES @path_wrapper @@ -561,11 +562,11 @@ def _infer_binary_operation(left, right, op, context, flow_factory): except NotFoundError: continue except InferenceError: - yield YES + yield util.YES return else: - if any(result is YES for result in results): - yield YES + if any(result is util.YES for result in results): + yield util.YES return # TODO(cpopa): since the inferrence engine might return @@ -577,7 +578,7 @@ def _infer_binary_operation(left, right, op, context, flow_factory): if _is_not_implemented(result)) if not_implemented and not_implemented != len(results): # Can't decide yet what this is, not yet though. - yield YES + yield util.YES return for result in results: @@ -597,9 +598,9 @@ def _infer_binop(self, context): op = self.op for lhs in left.infer(context=context): - if lhs is YES: + if lhs is util.YES: # Don't know how to process this. - yield YES + yield util.YES return # TODO(cpopa): if we have A() * A(), trying to infer @@ -609,9 +610,9 @@ def _infer_binop(self, context): rhs_context = context.clone() rhs_context.path = set() for rhs in right.infer(context=rhs_context): - if rhs is YES: + if rhs is util.YES: # Don't know how to process this. - yield YES + yield util.YES return results = _infer_binary_operation(lhs, rhs, op, @@ -636,9 +637,9 @@ def _infer_augassign(self, context=None): op = self.op for lhs in self.target.infer_lhs(context=context): - if lhs is YES: + if lhs is util.YES: # Don't know how to process this. - yield YES + yield util.YES return # TODO(cpopa): if we have A() * A(), trying to infer @@ -648,9 +649,9 @@ def _infer_augassign(self, context=None): rhs_context = context.clone() rhs_context.path = set() for rhs in self.value.infer(context=rhs_context): - if rhs is YES: + if rhs is util.YES: # Don't know how to process this. - yield YES + yield util.YES return results = _infer_binary_operation(lhs, rhs, op, @@ -696,14 +697,14 @@ nodes.AssAttr._infer = path_wrapper(infer_ass) def infer_empty_node(self, context=None): if not self.has_underlying_object(): - yield YES + yield util.YES else: try: for infered in MANAGER.infer_ast_from_something(self.object, context=context): yield infered except AstroidError: - yield YES + yield util.YES nodes.EmptyNode._infer = path_wrapper(infer_empty_node) diff --git a/astroid/node_classes.py b/astroid/node_classes.py index 5f107bad..3b085df8 100644 --- a/astroid/node_classes.py +++ b/astroid/node_classes.py @@ -25,10 +25,11 @@ from astroid.exceptions import ( InferenceError, BinaryOperationError ) from astroid.bases import (NodeNG, Statement, Instance, InferenceContext, - _infer_stmts, YES, BUILTINS) + _infer_stmts, BUILTINS) from astroid.mixins import (BlockRangeMixIn, AssignTypeMixin, ParentAssignTypeMixin, FromImportMixIn) from astroid.decorators import cachedproperty +from astroid import util def unpack_infer(stmt, context=None): @@ -47,7 +48,7 @@ def unpack_infer(stmt, context=None): return # else, infer recursivly, except YES object that should be returned as is for infered in stmt.infer(context): - if infered is YES: + if infered is util.YES: yield infered else: for inf_inf in unpack_infer(infered, context): @@ -623,7 +624,7 @@ class Dict(NodeNG, Instance): def getitem(self, lookup_key, context=None): for key, value in self.items: for inferedkey in key.infer(context): - if inferedkey is YES: + if inferedkey is util.YES: continue if isinstance(inferedkey, Const) \ and inferedkey.value == lookup_key: diff --git a/astroid/protocols.py b/astroid/protocols.py index 46a03bea..9cbb555d 100644 --- a/astroid/protocols.py +++ b/astroid/protocols.py @@ -30,11 +30,12 @@ from astroid.node_classes import unpack_infer from astroid.bases import ( InferenceContext, copy_context, raise_if_nothing_infered, yes_if_nothing_infered, - Instance, YES, BoundMethod, + Instance, BoundMethod, Generator, ) from astroid.nodes import const_factory from astroid import nodes +from astroid import util def _reflected_name(name): @@ -126,12 +127,12 @@ def const_infer_binary_op(self, operator, other, context, _): # ArithmeticError is not enough: float >> float is a TypeError yield not_implemented except Exception: # pylint: disable=broad-except - yield YES + yield util.YES except TypeError: yield not_implemented elif isinstance(self.value, six.string_types) and operator == '%': # TODO(cpopa): implement string interpolation later on. - yield YES + yield util.YES else: yield not_implemented @@ -141,7 +142,7 @@ nodes.Const.infer_binary_op = yes_if_nothing_infered(const_infer_binary_op) def _multiply_seq_by_int(self, other, context): node = self.__class__() elts = [n for elt in self.elts for n in elt.infer(context) - if not n is YES] * other.value + if not n is util.YES] * other.value node.elts = elts return node @@ -151,9 +152,9 @@ def tl_infer_binary_op(self, operator, other, context, method): if isinstance(other, self.__class__) and operator == '+': node = self.__class__() elts = [n for elt in self.elts for n in elt.infer(context) - if not n is YES] + if not n is util.YES] elts += [n for elt in other.elts for n in elt.infer(context) - if not n is YES] + if not n is util.YES] node.elts = elts yield node elif isinstance(other, nodes.Const) and operator == '*': @@ -165,7 +166,7 @@ def tl_infer_binary_op(self, operator, other, context, method): # Verify if the instance supports __index__. as_index = class_as_index(other, context) if not as_index: - yield YES + yield util.YES else: yield _multiply_seq_by_int(self, as_index, context) else: @@ -199,7 +200,7 @@ def _resolve_looppart(parts, asspath, context): asspath = asspath[:] index = asspath.pop(0) for part in parts: - if part is YES: + if part is util.YES: continue # XXX handle __iter__ and log potentially detected errors if not hasattr(part, 'itered'): @@ -219,7 +220,7 @@ def _resolve_looppart(parts, asspath, context): # we achieved to resolved the assignment path, # don't infer the last part yield assigned - elif assigned is YES: + elif assigned is util.YES: break else: # we are not yet on the last part of the path @@ -266,7 +267,7 @@ def _arguments_infer_argname(self, name, context): # arguments information may be missing, in which case we can't do anything # more if not (self.args or self.vararg or self.kwarg): - yield YES + yield util.YES return # first argument of instance/class method if self.args and getattr(self.args[0], 'name', None) == name: @@ -293,9 +294,9 @@ def _arguments_infer_argname(self, name, context): context = copy_context(context) for infered in self.default_value(name).infer(context): yield infered - yield YES + yield util.YES except NoDefault: - yield YES + yield util.YES def arguments_assigned_stmts(self, node, context, asspath=None): @@ -335,7 +336,7 @@ def _resolve_asspart(parts, asspath, context): # we achieved to resolved the assignment path, don't infer the # last part yield assigned - elif assigned is YES: + elif assigned is util.YES: return else: # we are not yet on the last part of the path search on each @@ -458,11 +459,11 @@ def starred_assigned_stmts(self, node=None, context=None, asspath=None): try: rhs = next(value.infer(context)) except InferenceError: - yield YES + yield util.YES return - if rhs is YES or not hasattr(rhs, 'elts'): + if rhs is util.YES or not hasattr(rhs, 'elts'): # Not interested in inferred values without elts. - yield YES + yield util.YES return elts = collections.deque(rhs.elts[:]) diff --git a/astroid/scoped_nodes.py b/astroid/scoped_nodes.py index e428f03f..348278ab 100644 --- a/astroid/scoped_nodes.py +++ b/astroid/scoped_nodes.py @@ -36,6 +36,7 @@ from astroid import manager from astroid import mixins from astroid import node_classes from astroid import decorators as decorators_mod +from astroid import util BUILTINS = six.moves.builtins.__name__ @@ -537,7 +538,7 @@ class DictComp(ComprehensionScope): self.generators = [] def bool_value(self): - return bases.YES + return util.YES class SetComp(ComprehensionScope): @@ -549,7 +550,7 @@ class SetComp(ComprehensionScope): self.generators = [] def bool_value(self): - return bases.YES + return util.YES class _ListComp(bases.NodeNG): @@ -559,7 +560,7 @@ class _ListComp(bases.NodeNG): generators = None def bool_value(self): - return bases.YES + return util.YES if six.PY3: @@ -885,7 +886,7 @@ class Function(bases.Statement, Lambda): c.hide = True c.parent = self class_bases = [next(b.infer(context)) for b in caller.args[1:]] - c.bases = [base for base in class_bases if base != bases.YES] + c.bases = [base for base in class_bases if base != util.YES] c._metaclass = metaclass yield c return @@ -898,7 +899,7 @@ class Function(bases.Statement, Lambda): for infered in returnnode.value.infer(context): yield infered except exceptions.InferenceError: - yield bases.YES + yield util.YES def bool_value(self): return True @@ -935,7 +936,7 @@ def _is_metaclass(klass, seen=None): if isinstance(baseobj, bases.Instance): # not abstract return False - if baseobj is bases.YES: + if baseobj is util.YES: continue if baseobj is klass: continue @@ -1089,7 +1090,7 @@ class Class(bases.Statement, LocalsDictNodeNG, mixins.FilterStmtsMixin): isinstance(name_node.value, six.string_types)): name = name_node.value else: - return bases.YES + return util.YES result = Class(name, None) @@ -1101,7 +1102,7 @@ class Class(bases.Statement, LocalsDictNodeNG, mixins.FilterStmtsMixin): # There is currently no AST node that can represent an 'unknown' # node (YES is not an AST node), therefore we simply return YES here # although we know at least the name of the class. - return bases.YES + return util.YES # Get the members of the class try: @@ -1368,13 +1369,13 @@ class Class(bases.Statement, LocalsDictNodeNG, mixins.FilterStmtsMixin): except exceptions.NotFoundError: yield infered else: - yield bases.YES + yield util.YES else: yield function_to_method(infered, self) except exceptions.NotFoundError: if not name.startswith('__') and self.has_dynamic_getattr(context): # class handle some dynamic attributes, return a YES object - yield bases.YES + yield util.YES else: raise exceptions.InferenceError(name) @@ -1455,7 +1456,7 @@ class Class(bases.Statement, LocalsDictNodeNG, mixins.FilterStmtsMixin): # Expects this from Py3k TreeRebuilder try: return next(node for node in self._metaclass.infer() - if node is not bases.YES) + if node is not util.YES) except (exceptions.InferenceError, StopIteration): return None if six.PY3: @@ -1478,7 +1479,7 @@ class Class(bases.Statement, LocalsDictNodeNG, mixins.FilterStmtsMixin): infered = next(assignment.infer()) except exceptions.InferenceError: return - if infered is bases.YES: # don't expose this + if infered is util.YES: # don't expose this return None return infered @@ -1529,7 +1530,7 @@ class Class(bases.Statement, LocalsDictNodeNG, mixins.FilterStmtsMixin): values = [item[0] for item in slots.items] else: values = slots.itered() - if values is bases.YES: + if values is util.YES: continue if not values: # Stop the iteration, because the class @@ -1539,7 +1540,7 @@ class Class(bases.Statement, LocalsDictNodeNG, mixins.FilterStmtsMixin): for elt in values: try: for infered in elt.infer(): - if infered is bases.YES: + if infered is util.YES: continue if (not isinstance(infered, node_classes.Const) or not isinstance(infered.value, diff --git a/astroid/tests/unittest_brain.py b/astroid/tests/unittest_brain.py index 8dfa300d..44758192 100644 --- a/astroid/tests/unittest_brain.py +++ b/astroid/tests/unittest_brain.py @@ -25,6 +25,7 @@ from astroid import bases from astroid import builder from astroid import nodes from astroid import test_utils +from astroid import util import astroid @@ -105,7 +106,7 @@ class NamedTupleTest(unittest.TestCase): def foo(fields): return __(namedtuple("foo", fields)) """) - self.assertIs(bases.YES, next(klass.infer())) + self.assertIs(util.YES, next(klass.infer())) @unittest.skipIf(sys.version_info[0] > 2, 'namedtuple inference is broken on Python 3') diff --git a/astroid/tests/unittest_builder.py b/astroid/tests/unittest_builder.py index e4d58666..87e90e76 100644 --- a/astroid/tests/unittest_builder.py +++ b/astroid/tests/unittest_builder.py @@ -29,6 +29,7 @@ from astroid import exceptions from astroid import manager from astroid import nodes from astroid import test_utils +from astroid import util from astroid.tests import resources MANAGER = manager.AstroidManager() @@ -482,7 +483,7 @@ class BuilderTest(unittest.TestCase): n = test_utils.get_name_node(astroid, 'n') self.assertIsNot(n.scope(), astroid) self.assertEqual([i.__class__ for i in n.infer()], - [bases.YES.__class__]) + [util.YES.__class__]) def test_no_future_imports(self): mod = builder.parse("import sys") diff --git a/astroid/tests/unittest_helpers.py b/astroid/tests/unittest_helpers.py index a69c1361..dfe5b60c 100644 --- a/astroid/tests/unittest_helpers.py +++ b/astroid/tests/unittest_helpers.py @@ -27,6 +27,7 @@ from astroid import helpers from astroid import manager
from astroid import raw_building
from astroid import test_utils
+from astroid import util
class TestHelpers(unittest.TestCase):
@@ -154,7 +155,7 @@ class TestHelpers(unittest.TestCase): from unknown import Unknown
u = Unknown #@
''')
- self.assertEqual(helpers.object_type(node), bases.YES)
+ self.assertEqual(helpers.object_type(node), util.YES)
def test_object_type_too_many_types(self):
node = test_utils.extract_node('''
@@ -166,7 +167,7 @@ class TestHelpers(unittest.TestCase): return 1
test(Unknown) #@
''')
- self.assertEqual(helpers.object_type(node), bases.YES)
+ self.assertEqual(helpers.object_type(node), util.YES)
def test_is_subtype(self):
ast_nodes = test_utils.extract_node('''
@@ -216,8 +217,8 @@ class TestHelpers(unittest.TestCase): class F(D, E): pass #@
''')
self.assertFalse(helpers.is_subtype(cls_e, cls_f))
- self.assertEqual(helpers.is_subtype(cls_f, cls_e), bases.YES)
- self.assertEqual(helpers.is_supertype(cls_e, cls_f), bases.YES)
+ self.assertEqual(helpers.is_subtype(cls_f, cls_e), util.YES)
+ self.assertEqual(helpers.is_supertype(cls_e, cls_f), util.YES)
self.assertFalse(helpers.is_supertype(cls_f, cls_e))
def test_is_subtype_supertype_unknown_bases(self):
diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py index b091a2be..20666f58 100644 --- a/astroid/tests/unittest_inference.py +++ b/astroid/tests/unittest_inference.py @@ -27,10 +27,11 @@ import six 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 YES, Instance, BoundMethod, UnboundMethod,\ +from astroid.bases import Instance, BoundMethod, UnboundMethod,\ path_wrapper, BUILTINS from astroid import objects from astroid import test_utils +from astroid import util from astroid.tests import resources @@ -307,7 +308,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): self.assertIsInstance(obj1, nodes.Const) self.assertEqual(obj1.value, 0) obj1 = next(infered) - self.assertIs(obj1, YES, obj1) + self.assertIs(obj1, util.YES, obj1) self.assertRaises(StopIteration, partial(next, infered)) def test_args_default_inference2(self): @@ -316,13 +317,13 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): self.assertIsInstance(obj1, nodes.Const) self.assertEqual(obj1.value, 4) obj1 = next(infered) - self.assertIs(obj1, YES, obj1) + self.assertIs(obj1, util.YES, obj1) self.assertRaises(StopIteration, partial(next, infered)) def test_inference_restrictions(self): infered = test_utils.get_name_node(self.ast['C']['meth1'], 'arg1').infer() obj1 = next(infered) - self.assertIs(obj1, YES, obj1) + self.assertIs(obj1, util.YES, obj1) self.assertRaises(StopIteration, partial(next, infered)) def test_ancestors_inference(self): @@ -544,7 +545,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): ast = parse(code, __name__) xxx = ast['xxx'] self.assertSetEqual({n.__class__ for n in xxx.infered()}, - {nodes.Const, YES.__class__}) + {nodes.Const, util.YES.__class__}) def test_method_argument(self): code = ''' @@ -560,13 +561,13 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): ast = parse(code, __name__) arg = test_utils.get_name_node(ast['ErudiEntitySchema']['__init__'], 'e_type') self.assertEqual([n.__class__ for n in arg.infer()], - [YES.__class__]) + [util.YES.__class__]) arg = test_utils.get_name_node(ast['ErudiEntitySchema']['__init__'], 'kwargs') self.assertEqual([n.__class__ for n in arg.infer()], [nodes.Dict]) arg = test_utils.get_name_node(ast['ErudiEntitySchema']['meth'], 'e_type') self.assertEqual([n.__class__ for n in arg.infer()], - [YES.__class__]) + [util.YES.__class__]) arg = test_utils.get_name_node(ast['ErudiEntitySchema']['meth'], 'args') self.assertEqual([n.__class__ for n in arg.infer()], [nodes.Tuple]) @@ -704,7 +705,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): for node in ast_nodes[:3]: self.assertRaises(InferenceError, next, node.infer()) for node in ast_nodes[3:]: - self.assertEqual(next(node.infer()), YES) + self.assertEqual(next(node.infer()), util.YES) def test_bytes_subscript(self): node = test_utils.extract_node('''b'a'[0]''') @@ -947,7 +948,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): self.assertEqual(first.value, 43) second = next(ast_nodes[1].infer()) - self.assertEqual(second, YES) + self.assertEqual(second, util.YES) def test_binary_op_other_type_using_reflected_operands(self): ast_nodes = test_utils.extract_node(''' @@ -958,7 +959,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): 1 + A() #@ ''') first = next(ast_nodes[0].infer()) - self.assertEqual(first, YES) + self.assertEqual(first, util.YES) second = next(ast_nodes[1].infer()) self.assertIsInstance(second, nodes.Const) @@ -972,7 +973,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): 1 + A() #@ ''') first = next(ast_node.infer()) - self.assertEqual(first, YES) + self.assertEqual(first, util.YES) def test_binary_op_list_mul(self): for code in ('a = [[]] * 2', 'a = 2 * [[]]'): @@ -989,10 +990,10 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): ast = builder.string_build('a = [1] * None\nb = [1] * "r"') infered = ast['a'].infered() self.assertEqual(len(infered), 1) - self.assertEqual(infered[0], YES) + self.assertEqual(infered[0], util.YES) infered = ast['b'].infered() self.assertEqual(len(infered), 1) - self.assertEqual(infered[0], YES) + self.assertEqual(infered[0], util.YES) def test_binary_op_tuple_add(self): ast = builder.string_build('a = (1,) + (2,)', __name__, __file__) @@ -1039,7 +1040,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): callfuncnode = test_utils.extract_node(code) infered = list(callfuncnode.infer()) self.assertEqual(len(infered), 2, infered) - infered.remove(YES) + infered.remove(util.YES) self.assertIsInstance(infered[0], nodes.Const) self.assertIsNone(infered[0].value) @@ -1051,7 +1052,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): ast = parse(code, __name__) infered = list(ast['f'].ilookup('a')) self.assertEqual(len(infered), 1) - self.assertEqual(infered[0], YES) + self.assertEqual(infered[0], util.YES) def test_nonregr_instance_attrs(self): """non regression for instance_attrs infinite loop : pylint / #4""" @@ -1103,7 +1104,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): self.assertTrue(ast.absolute_import_activated(), True) infered = next(test_utils.get_name_node(ast, 'import_package_subpackage_module').infer()) # failed to import since absolute_import is activated - self.assertIs(infered, YES) + self.assertIs(infered, util.YES) def test_nonregr_absolute_import(self): ast = resources.build_file('data/absimp/string.py', 'data.absimp.string') @@ -1221,7 +1222,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): ast = parse(code, __name__) infered = list(test_utils.get_name_node(ast['foo'], 'spam').infer()) self.assertEqual(len(infered), 1) - self.assertIs(infered[0], YES) + self.assertIs(infered[0], util.YES) def test_nonregr_func_global(self): code = ''' @@ -1412,7 +1413,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): ast = parse(code, __name__) sub = ast['sub'].infered()[0] mul = ast['mul'].infered()[0] - self.assertIs(sub, YES) + self.assertIs(sub, util.YES) self.assertIsInstance(mul, nodes.Const) self.assertEqual(mul.value, 42) @@ -1431,7 +1432,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): ast = parse(code, __name__) sub = ast['sub'].infered()[0] mul = ast['mul'].infered()[0] - self.assertIs(sub, YES) + self.assertIs(sub, util.YES) self.assertIsInstance(mul, nodes.Const) self.assertEqual(mul.value, 42) @@ -1451,7 +1452,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): ast = parse(code, __name__) sub = ast['sub'].infered()[0] mul = ast['mul'].infered()[0] - self.assertIs(sub, YES) + self.assertIs(sub, util.YES) self.assertIsInstance(mul, nodes.List) self.assertIsInstance(mul.elts[0], nodes.Const) self.assertEqual(mul.elts[0].value, 42) @@ -1468,12 +1469,12 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): """ ast = parse(code, __name__) node = ast['c'] - self.assertEqual(node.infered(), [YES]) + self.assertEqual(node.infered(), [util.YES]) def test_infer_empty_nodes(self): # Should not crash when trying to infer EmptyNodes. node = nodes.EmptyNode() - self.assertEqual(node.infered(), [YES]) + self.assertEqual(node.infered(), [util.YES]) def test_infinite_loop_for_decorators(self): # Issue https://bitbucket.org/logilab/astroid/issue/50 @@ -1941,7 +1942,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): def test_unary_op_leaks_stop_iteration(self): node = test_utils.extract_node('+[] #@') - self.assertEqual(YES, next(node.infer())) + self.assertEqual(util.YES, next(node.infer())) def test_unary_operands(self): ast_nodes = test_utils.extract_node(''' @@ -1992,7 +1993,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): for bad_node in ast_nodes[4:]: inferred = next(bad_node.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_binary_op_type_errors(self): ast_nodes = test_utils.extract_node(''' @@ -2181,11 +2182,11 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): genexpr = next(module['genexpr'].infer()) self.assertTrue(genexpr.bool_value()) dict_comp = next(module['dict_comp'].infer()) - self.assertEqual(dict_comp, YES) + self.assertEqual(dict_comp, util.YES) set_comp = next(module['set_comp'].infer()) - self.assertEqual(set_comp, YES) + self.assertEqual(set_comp, util.YES) list_comp = next(module['list_comp'].infer()) - self.assertEqual(list_comp, YES) + self.assertEqual(list_comp, util.YES) lambda_func = next(module['lambda_func'].infer()) self.assertTrue(lambda_func) unbound_method = next(module['unbound_method'].infer()) @@ -2199,13 +2200,13 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): bin_op = module['bin_op'].parent.value self.assertTrue(bin_op.bool_value()) bool_op = module['bool_op'].parent.value - self.assertEqual(bool_op.bool_value(), YES) + self.assertEqual(bool_op.bool_value(), util.YES) callfunc = module['callfunc'].parent.value - self.assertEqual(callfunc.bool_value(), YES) + self.assertEqual(callfunc.bool_value(), util.YES) good_callfunc = next(module['good_callfunc'].infer()) self.assertTrue(good_callfunc.bool_value()) compare = module['compare'].parent.value - self.assertEqual(compare.bool_value(), YES) + self.assertEqual(compare.bool_value(), util.YES) def test_bool_value_instances(self): instances = test_utils.extract_node(''' @@ -2238,7 +2239,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): AlwaysTrueInstance() #@ ErrorInstance() #@ '''.format(bool=BOOL_SPECIAL_METHOD)) - expected = (False, True, False, True, True, YES, YES) + expected = (False, True, False, True, True, util.YES, util.YES) for node, expected_value in zip(instances, expected): inferred = next(node.infer()) self.assertEqual(inferred.bool_value(), expected_value) @@ -2310,7 +2311,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): A() + B() #@ ''') inferred = next(node.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_binop_different_types_reflected_and_normal_not_implemented(self): node = test_utils.extract_node(''' @@ -2321,7 +2322,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): A() + B() #@ ''') inferred = next(node.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_binop_subtype(self): node = test_utils.extract_node(''' @@ -2354,7 +2355,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): B() + A() #@ ''') inferred = next(node.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_binop_supertype(self): node = test_utils.extract_node(''' @@ -2393,7 +2394,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): A() + B() #@ ''') inferred = next(node.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_binop_inferrence_errors(self): ast_nodes = test_utils.extract_node(''' @@ -2408,7 +2409,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): A() + B() #@ ''') for node in ast_nodes: - self.assertEqual(next(node.infer()), YES) + self.assertEqual(next(node.infer()), util.YES) def test_binop_ambiguity(self): ast_nodes = test_utils.extract_node(''' @@ -2431,7 +2432,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): C() + A() #@ ''') for node in ast_nodes: - self.assertEqual(next(node.infer()), YES) + self.assertEqual(next(node.infer()), util.YES) def test_bin_op_supertype_more_complicated_example(self): ast_node = test_utils.extract_node(''' @@ -2460,7 +2461,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): def __add__(self, other): return NotImplemented A() + A() #@ ''') - self.assertEqual(next(ast_node.infer()), YES) + self.assertEqual(next(ast_node.infer()), util.YES) def test_aug_op_same_type_aug_implemented(self): ast_node = test_utils.extract_node(''' @@ -2495,7 +2496,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): b = B() b+=A() #@ ''') - self.assertEqual(next(ast_node.infer()), YES) + self.assertEqual(next(ast_node.infer()), util.YES) def test_aug_op_subtype_aug_op_is_implemented(self): ast_node = test_utils.extract_node(''' @@ -2530,7 +2531,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): f = A() f += B() #@ ''') - self.assertEqual(next(ast_node.infer()), YES) + self.assertEqual(next(ast_node.infer()), util.YES) def test_aug_different_types_augop_implemented(self): ast_node = test_utils.extract_node(''' @@ -2578,7 +2579,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): a = A() a += B() #@ ''') - self.assertEqual(next(ast_node.infer()), YES) + self.assertEqual(next(ast_node.infer()), util.YES) def test_augop_supertypes_not_implemented_returned_for_all(self): ast_node = test_utils.extract_node(''' @@ -2590,7 +2591,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): a = A() a += B() #@ ''') - self.assertEqual(next(ast_node.infer()), YES) + self.assertEqual(next(ast_node.infer()), util.YES) def test_augop_supertypes_augop_implemented(self): ast_node = test_utils.extract_node(''' @@ -2662,7 +2663,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): [1, 2, 1, 2]) for rest in ast_nodes[1:]: inferred = next(rest.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_special_method_masquerading_as_another(self): ast_node = test_utils.extract_node(''' @@ -2694,7 +2695,7 @@ class InferenceTest(resources.SysPathSetup, unittest.TestCase): class GetattrTest(unittest.TestCase): - def test_yes(self): + def test_yes_when_unknown(self): ast_nodes = test_utils.extract_node(''' from missing import Missing getattr(1, Unknown) #@ @@ -2712,7 +2713,7 @@ class GetattrTest(unittest.TestCase): for node in ast_nodes[4:]: inferred = next(node.infer()) - self.assertEqual(inferred, YES, node) + self.assertEqual(inferred, util.YES, node) def test_attrname_not_string(self): ast_nodes = test_utils.extract_node(''' @@ -2809,7 +2810,7 @@ class HasattrTest(unittest.TestCase): ''') for node in ast_nodes: inferred = next(node.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_attribute_is_missing(self): ast_nodes = test_utils.extract_node(''' @@ -2882,7 +2883,7 @@ class BoolOpTest(unittest.TestCase): ''') for node in ast_nodes: inferred = next(node.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_other_nodes(self): ast_nodes = test_utils.extract_node(''' @@ -2962,7 +2963,7 @@ class TestCallable(unittest.TestCase): ''') for node in ast_nodes: inferred = next(node.infer()) - self.assertEqual(inferred, YES) + self.assertEqual(inferred, util.YES) def test_not_callable(self): ast_nodes = test_utils.extract_node(''' @@ -2988,12 +2989,12 @@ class TestBool(unittest.TestCase): ('bool(True)', True), ('bool(False)', False), ('bool(None)', False), - ('from unknown import Unknown; __(bool(Unknown))', YES), + ('from unknown import Unknown; __(bool(Unknown))', util.YES), ] for code, expected in pairs: node = test_utils.extract_node(code) inferred = next(node.infer()) - if expected is YES: + if expected is util.YES: self.assertEqual(expected, inferred) else: self.assertEqual(inferred.value, expected) diff --git a/astroid/tests/unittest_lookup.py b/astroid/tests/unittest_lookup.py index 491ae78d..17c8ba45 100644 --- a/astroid/tests/unittest_lookup.py +++ b/astroid/tests/unittest_lookup.py @@ -27,6 +27,7 @@ from astroid import exceptions from astroid import nodes from astroid import scoped_nodes from astroid import test_utils +from astroid import util from astroid.tests import resources @@ -172,7 +173,7 @@ class LookupTest(resources.SysPathSetup, unittest.TestCase): """) var = astroid.body[1].value if sys.version_info < (3, 0): - self.assertEqual(var.infered(), [bases.YES]) + self.assertEqual(var.infered(), [util.YES]) else: self.assertRaises(exceptions.UnresolvableName, var.infered) diff --git a/astroid/tests/unittest_nodes.py b/astroid/tests/unittest_nodes.py index 2a08843b..ff2468b0 100644 --- a/astroid/tests/unittest_nodes.py +++ b/astroid/tests/unittest_nodes.py @@ -29,6 +29,7 @@ from astroid import builder from astroid import exceptions from astroid import node_classes from astroid import nodes +from astroid import util from astroid import test_utils from astroid.tests import resources @@ -369,7 +370,7 @@ from ..cave import wine\n\n""" # present in the other version. self.assertIsInstance(excs[0], nodes.Class) self.assertEqual(excs[0].name, 'PickleError') - self.assertIs(excs[-1], bases.YES) + self.assertIs(excs[-1], util.YES) def test_absolute_import(self): astroid = resources.build_file('data/absimport.py') diff --git a/astroid/tests/unittest_protocols.py b/astroid/tests/unittest_protocols.py index 1d2e380d..30b5f94b 100644 --- a/astroid/tests/unittest_protocols.py +++ b/astroid/tests/unittest_protocols.py @@ -18,10 +18,10 @@ import unittest -from astroid import YES from astroid.test_utils import extract_node, require_version from astroid import InferenceError from astroid import nodes +from astroid import util from astroid.node_classes import AssName, Const, Name, Starred @@ -67,7 +67,7 @@ class ProtocolTests(unittest.TestCase): for1_starred = next(assign_stmts.nodes_of_class(Starred)) assigned = next(for1_starred.assigned_stmts()) - self.assertEqual(assigned, YES) + self.assertEqual(assigned, util.YES) def _get_starred_stmts(self, code): assign_stmt = extract_node("{} #@".format(code)) @@ -108,16 +108,16 @@ class ProtocolTests(unittest.TestCase): @require_version(minver='3.0') def test_assigned_stmts_starred_yes(self): # Not something iterable and known - self._helper_starred_expected("a, *b = range(3) #@", YES) + self._helper_starred_expected("a, *b = range(3) #@", util.YES) # Not something inferrable - self._helper_starred_expected("a, *b = balou() #@", YES) + self._helper_starred_expected("a, *b = balou() #@", util.YES) # In function, unknown. self._helper_starred_expected(""" def test(arg): - head, *tail = arg #@""", YES) + head, *tail = arg #@""", util.YES) # These cases aren't worth supporting. self._helper_starred_expected( - "a, (*b, c), d = (1, (2, 3, 4), 5) #@", YES) + "a, (*b, c), d = (1, (2, 3, 4), 5) #@", util.YES) @require_version(minver='3.0') def test_assign_stmts_starred_fails(self): diff --git a/astroid/tests/unittest_scoped_nodes.py b/astroid/tests/unittest_scoped_nodes.py index 05425b26..17bb70e7 100644 --- a/astroid/tests/unittest_scoped_nodes.py +++ b/astroid/tests/unittest_scoped_nodes.py @@ -24,7 +24,10 @@ from functools import partial import unittest import warnings -from astroid import YES, builder, nodes, scoped_nodes +from astroid import builder +from astroid import nodes +from astroid import scoped_nodes +from astroid import util from astroid.exceptions import ( InferenceError, NotFoundError, NoDefault, ResolveError, MroError, @@ -1088,7 +1091,7 @@ class ClassNodeTest(ModuleLoader, unittest.TestCase): instance = astroid['tgts'] # used to raise "'_Yes' object is not iterable", see # https://bitbucket.org/logilab/astroid/issue/17 - self.assertEqual(list(instance.infer()), [YES]) + self.assertEqual(list(instance.infer()), [util.YES]) def test_slots(self): astroid = builder.parse(""" @@ -1352,7 +1355,7 @@ class ClassNodeTest(ModuleLoader, unittest.TestCase): class B(object): pass ''') cls = module['B'] - self.assertEqual(YES, next(cls.igetattr('foo'))) + self.assertEqual(util.YES, next(cls.igetattr('foo'))) def test_metaclass_lookup(self): module = builder.parse(''' diff --git a/astroid/util.py b/astroid/util.py new file mode 100644 index 00000000..8dde9b97 --- /dev/null +++ b/astroid/util.py @@ -0,0 +1,38 @@ +# copyright 2003-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr +# +# This file is part of astroid. +# +# astroid is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 2.1 of the License, or (at your +# option) any later version. +# +# astroid is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License along +# with astroid. If not, see <http://www.gnu.org/licenses/>. +# +# The code in this file was originally part of logilab-common, licensed under +# the same license. + +class _Yes(object): + """Special inference object, which is returned when inference fails.""" + def __repr__(self): + return 'YES' + + def __getattribute__(self, name): + if name == 'next': + raise AttributeError('next method should not be called') + if name.startswith('__') and name.endswith('__'): + return super(_Yes, self).__getattribute__(name) + return self + + def __call__(self, *args, **kwargs): + return self + + +YES = _Yes() |