#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
**exceptions.py**
**Platform:**
Windows, Linux, Mac Os X.
**Description:**
Defines **Foundations** package exceptions and others exception handling related objects.
**Others:**
"""
#**********************************************************************************************************************
#*** Future imports.
#**********************************************************************************************************************
from __future__ import unicode_literals
#**********************************************************************************************************************
#*** External imports.
#**********************************************************************************************************************
import ast
import functools
import inspect
import sys
if sys.version_info[:2] <= (2, 6):
from ordereddict import OrderedDict
else:
from collections import OrderedDict
import textwrap
import traceback
import types
#**********************************************************************************************************************
#*** Internal imports.
#**********************************************************************************************************************
import foundations.verbose
from foundations.globals.constants import Constants
#**********************************************************************************************************************
#*** Module attributes.
#**********************************************************************************************************************
__author__ = "Thomas Mansencal"
__copyright__ = "Copyright (C) 2008 - 2014 - Thomas Mansencal"
__license__ = "GPL V3.0 - http://www.gnu.org/licenses/"
__maintainer__ = "Thomas Mansencal"
__email__ = "[email protected]"
__status__ = "Production"
__all__ = ["LOGGER",
"getInnerMostFrame",
"extractStack",
"extractArguments",
"extractLocals",
"extractException",
"formatException",
"formatReport",
"baseExceptionHandler",
"installExceptionHandler",
"uninstallExceptionHandler",
"handleExceptions",
"AbstractError",
"ExecutionError",
"BreakIteration",
"AbstractParsingError",
"FileStructureParsingError",
"AttributeStructureParsingError",
"AbstractIOError",
"FileReadError",
"FileWriteError",
"UrlReadError",
"UrlWriteError",
"DirectoryCreationError",
"PathCopyError",
"PathRemoveError",
"AbstractOsError",
"PathExistsError",
"DirectoryExistsError",
"FileExistsError",
"AbstractObjectError",
"ObjectTypeError",
"ObjectExistsError",
"AbstractUserError",
"ProgrammingError",
"UserError",
"AbstractNodeError",
"NodeAttributeTypeError",
"NodeAttributeExistsError",
"AbstractLibraryError",
"LibraryInstantiationError",
"LibraryInitializationError",
"LibraryExecutionError",
"AbstractServerError",
"ServerOperationError",
"AnsiEscapeCodeExistsError"]
LOGGER = foundations.verbose.installLogger()
EXCEPTIONS_FRAME_SYMBOL = "_exceptions__frame__"
#**********************************************************************************************************************
#*** Module classes and definitions.
#**********************************************************************************************************************
[docs]def getInnerMostFrame(trcback):
"""
Returns the inner most frame of given traceback.
:param trcback: Traceback.
:type trcback: Traceback
:return: Frame.
:rtype: Frame
"""
frames = inspect.getinnerframes(trcback)
return frames.pop()[0] if frames else None
[docs]def baseExceptionHandler(*args):
"""
Provides the base exception handler.
:param \*args: Arguments.
:type \*args: \*
:return: Definition success.
:rtype: bool
"""
header, frames, trcback = formatReport(*extractException(*args))
LOGGER.error("!> {0}".format(Constants.loggingSeparators))
map(lambda x: LOGGER.error("!> {0}".format(x)), header)
LOGGER.error("!> {0}".format(Constants.loggingSeparators))
map(lambda x: LOGGER.error("!> {0}".format(x)), frames)
LOGGER.error("!> {0}".format(Constants.loggingSeparators))
sys.stderr.write("\n".join(trcback))
return True
[docs]def installExceptionHandler(handler=None):
"""
Installs the given exceptions handler.
:param handler: Exception handler.
:type handler: object
:return: Definition success.
:rtype: bool
"""
sys.excepthook = handler if handler is not None else baseExceptionHandler
return True
[docs]def uninstallExceptionHandler():
"""
Uninstalls the exceptions handler.
:return: Definition success.
:rtype: bool
"""
sys.excepthook = sys.__excepthook__
return True
[docs]def handleExceptions(*args):
"""
| Handles exceptions.
| It's possible to specify an user defined exception handler,
if not, :func:`baseExceptionHandler` handler will be used.
| The decorator uses given exceptions objects
or the default Python `Exception <http://docs.python.org/library/exceptions.html#exceptions.Exception>`_ class.
Usage::
@handleExceptions(ZeroDivisionError)
def raiseAnException(value):
'''
Raises a 'ZeroDivisionError' exception.
'''
return value / 0
:param \*args: Arguments.
:type \*args: \*
:return: Object.
:rtype: object
"""
exceptions = tuple(filter(lambda x: issubclass(x, Exception),
filter(lambda x: isinstance(x, (type, types.ClassType)), args)))
handlers = filter(lambda x: inspect.isfunction(x), args) or (baseExceptionHandler,)
def handleExceptionsDecorator(object):
"""
Handles exceptions.
:param object: Object to decorate.
:type object: object
:return: Object.
:rtype: object
"""
# Oncilla: Statement commented by auto-documentation process:
# Oncilla: Statement commented by auto-documentation process: @functools.wraps(object)
def handleExceptionsWrapper(*args, **kwargs):
"""
Handles exceptions.
:param \*args: Arguments.
:type \*args: \*
:param \*\*kwargs: Keywords arguments.
:type \*\*kwargs: \*\*
"""
_exceptions__frame__ = True
try:
return object(*args, **kwargs)
except exceptions as error:
for handler in handlers:
handler(error)
return handleExceptionsWrapper
return handleExceptionsDecorator
[docs]class AbstractError(Exception):
"""
Defines the abstract base class for all **Foundations** package exceptions.
"""
def __init__(self, value):
"""
Initializes the class.
:param value: Error value or message.
:type value: unicode
"""
LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))
# --- Setting class attributes. ---
self.__value = value
#******************************************************************************************************************
#*** Attributes properties.
#******************************************************************************************************************
@property
def value(self):
"""
Property for **self.__value** attribute.
:return: self.__value.
:rtype: object
"""
return self.__value
@value.setter
def value(self, value):
"""
Setter for **self.__value** attribute.
:param value: Attribute value.
:type value: object
"""
self.__value = value
@value.deleter
[docs] def value(self):
"""
Deleter for **self.__value** attribute.
"""
raise Exception("{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "value"))
#******************************************************************************************************************
#*** Class methods.
#******************************************************************************************************************
def __str__(self):
"""
Returns the exception representation.
:return: Exception representation.
:rtype: unicode
"""
return str(self.__value)
[docs]class ExecutionError(AbstractError):
"""
Defines execution exception.
"""
pass
[docs]class BreakIteration(AbstractError):
"""
Breaks nested loop iteration.
"""
pass
[docs]class AbstractParsingError(AbstractError):
"""
Defines the abstract base class for parsing related exception.
"""
pass
[docs]class FileStructureParsingError(AbstractParsingError):
"""
Defines exception raised while parsing file structure.
"""
pass
[docs]class AttributeStructureParsingError(AbstractParsingError):
"""
Defines exception raised while parsing attribute structure.
"""
def __init__(self, value, line=None):
"""
Initializes the class.
:param value: Error value or message.
:type value: unicode
:param line: Line number where exception occured.
:type line: int
"""
LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))
AbstractParsingError.__init__(self, value)
# --- Setting class attributes. ---
self.__line = None
self.line = line
#******************************************************************************************************************
#*** Attributes properties.
#******************************************************************************************************************
@property
def line(self):
"""
Property for **self.__line** attribute.
:return: self.__line.
:rtype: int
"""
return self.__line
@line.setter
# Oncilla: Statement commented by auto-documentation process: @handleExceptions(AssertionError)
def line(self, value):
"""
Setter for **self.__line** attribute.
:param value: Attribute value.
:type value: int
"""
if value is not None:
assert type(value) is int, "'{0}' attribute: '{1}' type is not 'int'!".format("line", value)
assert value > 0, "'{0}' attribute: '{1}' need to be exactly positive!".format("line", value)
self.__line = value
@line.deleter
# Oncilla: Statement commented by auto-documentation process: @handleExceptions(Exception)
[docs] def line(self):
"""
Deleter for **self.__line** attribute.
"""
raise Exception("{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "line"))
#******************************************************************************************************************
#*** Class methods.
#******************************************************************************************************************
def __str__(self):
"""
Returns the exception representation.
:return: Exception representation.
:rtype: unicode
"""
if self.__line:
return "Line '{0}': '{1}'.".format(self.__line, str(self.value))
else:
return str(self.value)
[docs]class AbstractIOError(AbstractError):
"""
Defines the abstract base class for io related exception.
"""
pass
[docs]class FileReadError(AbstractIOError):
"""
Defines file read exception.
"""
pass
[docs]class FileWriteError(AbstractIOError):
"""
Defines file write exception.
"""
pass
[docs]class UrlReadError(AbstractIOError):
"""
Defines url read exception.
"""
pass
[docs]class UrlWriteError(AbstractIOError):
"""
Defines file write exception.
"""
pass
[docs]class DirectoryCreationError(AbstractIOError):
"""
Defines directory creation exception.
"""
pass
[docs]class PathCopyError(AbstractIOError):
"""
Defines path copy exception.
"""
pass
[docs]class PathRemoveError(AbstractIOError):
"""
Defines path remove exception.
"""
pass
[docs]class AbstractOsError(AbstractError):
"""
Defines the abstract base class for os related exception.
"""
pass
[docs]class PathExistsError(AbstractOsError):
"""
Defines non existing path exception.
"""
pass
[docs]class DirectoryExistsError(PathExistsError):
"""
Defines non existing directory exception.
"""
pass
[docs]class FileExistsError(PathExistsError):
"""
Defines non existing file exception.
"""
pass
[docs]class AbstractObjectError(AbstractError):
"""
Defines the abstract base class for object related exception.
"""
pass
[docs]class ObjectTypeError(AbstractObjectError):
"""
Defines invalid object type exception.
"""
pass
[docs]class ObjectExistsError(AbstractObjectError):
"""
Defines non existing object exception.
"""
pass
[docs]class AbstractUserError(AbstractError):
"""
Defines the abstract base class for user related exception.
"""
pass
[docs]class ProgrammingError(AbstractUserError):
"""
Defines programming exception.
"""
pass
[docs]class UserError(AbstractUserError):
"""
Defines user exception.
"""
pass
[docs]class AbstractNodeError(AbstractError):
"""
Defines the abstract base class for Node related exception.
"""
pass
[docs]class NodeAttributeTypeError(AbstractNodeError, ObjectTypeError):
"""
Defines the abstract base class for Node attributes type related exception.
"""
pass
[docs]class NodeAttributeExistsError(AbstractNodeError, ObjectExistsError):
"""
Defines non existing Node attribute exception.
"""
pass
[docs]class AbstractLibraryError(AbstractError):
"""
Defines the abstract base class for :mod:`library` module exception.
"""
pass
[docs]class LibraryInstantiationError(AbstractLibraryError):
"""
Defines :mod:`library` module :class:`library.Library` class instantiation exception.
"""
pass
[docs]class LibraryInitializationError(AbstractLibraryError):
"""
Defines :mod:`library` module :class:`library.Library` class initialization exception.
"""
pass
[docs]class LibraryExecutionError(AbstractLibraryError):
"""
Defines :mod:`library` module :class:`library.Library` class execution exception.
"""
pass
[docs]class AbstractServerError(AbstractError):
"""
Defines the abstract base class for :mod:`tcpServer` module exception.
"""
pass
[docs]class ServerOperationError(AbstractServerError):
"""
Defines :mod:`tcpServer` module :class:`tcpServer.TCPServer` class operations exception.
"""
pass
[docs]class AnsiEscapeCodeExistsError(AbstractError):
"""
Defines exception used for non existing *ANSI* escape codes.
"""
pass