diff options
Diffstat (limited to 'astroid/exceptions.py')
-rw-r--r-- | astroid/exceptions.py | 178 |
1 files changed, 133 insertions, 45 deletions
diff --git a/astroid/exceptions.py b/astroid/exceptions.py index b308258..9f49753 100644 --- a/astroid/exceptions.py +++ b/astroid/exceptions.py @@ -16,88 +16,176 @@ # You should have received a copy of the GNU Lesser General Public License along # with astroid. If not, see <http://www.gnu.org/licenses/>. """this module contains exceptions used in the astroid library - """ +from astroid import util + class AstroidError(Exception): - """base exception class for all astroid related exceptions""" + """base exception class for all astroid related exceptions + + AstroidError and its subclasses are structured, intended to hold + objects representing state when the exception is thrown. Field + values are passed to the constructor as keyword-only arguments. + Each subclass has its own set of standard fields, but use your + best judgment to decide whether a specific exception instance + needs more or fewer fields for debugging. Field values may be + used to lazily generate the error message: self.message.format() + will be called with the field names and values supplied as keyword + arguments. + """ + def __init__(self, message='', **kws): + self.message = message + for key, value in kws.items(): + setattr(self, key, value) + + def __str__(self): + return self.message.format(**vars(self)) + class AstroidBuildingException(AstroidError): - """exception class when we are unable to build an astroid representation""" + """exception class when we are unable to build an astroid representation + + Standard attributes: + modname: Name of the module that AST construction failed for. + error: Exception raised during construction. + """ + + def __init__(self, message='Failed to import module {modname}.', **kws): + super(AstroidBuildingException, self).__init__(message, **kws) + + +class NoDefault(AstroidError): + """raised by function's `default_value` method when an argument has + no default value + + Standard attributes: + func: Function node. + name: Name of argument without a default. + """ + func = None + name = None + + def __init__(self, message='{func!r} has no default for {name!r}.', **kws): + super(NoDefault, self).__init__(message, **kws) + + +class DefaultStop(AstroidError): + '''This is a special error that's only meant to be raised in + generators wrapped with raise_if_nothing_inferred and + yes_if_nothing_inferred. It does nothing other than carry a set + of attributes to be used in raising in InferenceError. + + ''' + + # def __init__(self, message='{func!r} has no default for {name!r}.', **kws): + # super(NoDefault, self).__init__(message, **kws) + class ResolveError(AstroidError): - """base class of astroid resolution/inference error""" + """Base class of astroid resolution/inference error. + + ResolveError is not intended to be raised. + + Standard attributes: + context: InferenceContext object. + """ + context = None + class MroError(ResolveError): - """Error raised when there is a problem with method resolution of a class.""" + """Error raised when there is a problem with method resolution of a class. + Standard attributes: + mros: A sequence of sequences containing ClassDef nodes. + cls: ClassDef node whose MRO resolution failed. + context: InferenceContext object. + """ + mros = () + cls = None + + def __str__(self): + mro_names = ", ".join("({})".format(", ".join(b.name for b in m)) + for m in self.mros) + return self.message.format(mros=mro_names, cls=self.cls) class DuplicateBasesError(MroError): """Error raised when there are duplicate bases in the same class bases.""" - class InconsistentMroError(MroError): """Error raised when a class's MRO is inconsistent.""" class SuperError(ResolveError): - """Error raised when there is a problem with a super call.""" + """Error raised when there is a problem with a super call. -class SuperArgumentTypeError(SuperError): - """Error raised when the super arguments are invalid.""" + Standard attributes: + super_: The Super instance that raised the exception. + context: InferenceContext object. + """ + super_ = None + def __str__(self): + return self.message.format(**vars(self.super_)) -class NotFoundError(ResolveError): - """raised when we are unable to resolve a name""" class InferenceError(ResolveError): - """raised when we are unable to infer a node""" + """raised when we are unable to infer a node -class UseInferenceDefault(Exception): - """exception to be raised in custom inference function to indicate that it - should go back to the default behaviour + Standard attributes: + node: The node inference was called on. + context: InferenceContext object. """ + node = None + context= None -class UnresolvableName(InferenceError): - """raised when we are unable to resolve a name""" - -class NoDefault(AstroidError): - """raised by function's `default_value` method when an argument has - no default value - """ + def __init__(self, message='Inference failed for {node!r}.', **kws): + super(InferenceError, self).__init__(message, **kws) -class OperationError(object): - """Object which describes a TypeError occurred somewhere in the inference chain +# Why does this inherit from InferenceError rather than ResolveError? +# Changing it causes some inference tests to fail. +class NameInferenceError(InferenceError): + """Raised when a name lookup fails, corresponds to NameError. - This is not an exception, but a container object which holds the types and - the error which occurred. + Standard attributes: + name: The name for which lookup failed, as a string. + scope: The node representing the scope in which the lookup occurred. + context: InferenceContext object. """ + name = None + scope = None + def __init__(self, message='{name!r} not found in {scope!r}.', **kws): + super(NameInferenceError, self).__init__(message, **kws) -class UnaryOperationError(OperationError): - """Object which describes operational failures on UnaryOps.""" - def __init__(self, operand, op, error): - self.operand = operand - self.op = op - self.error = error +class AttributeInferenceError(ResolveError): + """Raised when an attribute lookup fails, corresponds to AttributeError. - def __str__(self): - operand_type = self.operand.name - msg = "bad operand type for unary {}: {}" - return msg.format(self.op, operand_type) + Standard attributes: + target: The node for which lookup failed. + attribute: The attribute for which lookup failed, as a string. + context: InferenceContext object. + """ + target = None + attribute = None + def __init__(self, message='{attribute!r} not found on {target!r}.', **kws): + super(AttributeInferenceError, self).__init__(message, **kws) -class BinaryOperationError(OperationError): - """Object which describes type errors for BinOps.""" - def __init__(self, left_type, op, right_type): - self.left_type = left_type - self.right_type = right_type - self.op = op +class UseInferenceDefault(Exception): + """exception to be raised in custom inference function to indicate that it + should go back to the default behaviour + """ - def __str__(self): - msg = "unsupported operand type(s) for {}: {!r} and {!r}" - return msg.format(self.op, self.left_type.name, self.right_type.name) + +# Backwards-compatibility aliases +OperationError = util.BadOperationMessage +UnaryOperationError = util.BadUnaryOperationMessage +BinaryOperationError = util.BadBinaryOperationMessage + +SuperArgumentTypeError = SuperError +UnresolvableName = NameInferenceError +NotFoundError = AttributeInferenceError |