#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
**exceptions.py**
**Platform:**
Windows, Linux, Mac Os X.
**Description:**
This module 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 - 2013 - Thomas Mansencal"
__license__ = "GPL V3.0 - http://www.gnu.org/licenses/"
__maintainer__ = "Thomas Mansencal"
__email__ = "thomas.mansencal@gmail.com"
__status__ = "Production"
__all__ = ["LOGGER",
"getInnerMostFrame",
"extractStack",
"extractArguments",
"extractLocals",
"extractException",
"formatException",
"formatReport",
"baseExceptionHandler",
"installExceptionHandler",
"uninstallExceptionHandler",
"handleExceptions",
"AbstractError",
"ExecutionError",
"BreakIteration",
"AbstractParsingError",
"FileStructureParsingError",
"AttributeStructureParsingError",
"AbstractOsError",
"PathExistsError",
"DirectoryExistsError",
"FileExistsError",
"AbstractObjectError",
"ObjectTypeError",
"ObjectExistsError",
"AbstractUserError",
"ProgrammingError",
"UserError",
"AbstractNodeError",
"NodeAttributeTypeError",
"NodeAttributeExistsError",
"AbstractLibraryError",
"LibraryInstantiationError",
"LibraryInitializationError",
"LibraryExecutionError",
"AbstractServerError",
"ServerOperationError"]
LOGGER = foundations.verbose.installLogger()
EXCEPTIONS_FRAME_SYMBOL = "_exceptions__frame__"
#**********************************************************************************************************************
#*** Module classes and definitions.
#**********************************************************************************************************************
[docs]def getInnerMostFrame(trcback):
"""
This definition returns the inner most frame of given traceback.
:param trcback: Traceback. ( Traceback )
:return: Frame. ( Frame )
"""
frames = inspect.getinnerframes(trcback)
return frames.pop()[0] if frames else None
[docs]def baseExceptionHandler(*args):
"""
This definition provides the base exception handler.
:param \*args: Arguments. ( \* )
:return: Definition success. ( Boolean )
"""
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):
"""
This definition installs the given exceptions handler.
:param handler: Exception handler. ( Object )
:return: Definition success. ( Boolean )
"""
sys.excepthook = handler if handler is not None else baseExceptionHandler
return True
[docs]def uninstallExceptionHandler():
"""
This definition uninstalls the exceptions handler.
:return: Definition success. ( Boolean )
"""
sys.excepthook = sys.__excepthook__
return True
[docs]def handleExceptions(*args):
"""
| This decorator is used for exceptions handling.
| 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):
'''
This definition raises a 'ZeroDivisionError' exception.
'''
return value / 0
:param \*args: Arguments. ( \* )
:return: Object. ( 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):
"""
This decorator is used for exceptions handling.
:param object: Object to decorate. ( Object )
:return: Object. ( Object )
"""
#*** Sphinx: Decorator commented for auto-documentation purpose. @functools.wraps(object)
def handleExceptionsWrapper(*args, **kwargs):
"""
This decorator is used for exceptions handling.
:param \*args: Arguments. ( \* )
:param \*\*kwargs: Keywords arguments. ( \*\* )
"""
_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):
"""
This class is the abstract base class for all **Foundations** package exceptions.
"""
def __init__(self, value):
"""
.. Sphinx: Statements updated for auto-documentation purpose.
:param value: Error value or message. ( String )
"""
LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))
# --- Setting class attributes. ---
self.__value = value
#******************************************************************************************************************
#*** Attributes properties.
#******************************************************************************************************************
@property
def value(self):
"""
This method is the property for **self.__value** attribute.
:return: self.__value. ( Object )
"""
return self.__value
@value.setter
def value(self, value):
"""
This method is the setter method for **self.__value** attribute.
:param value: Attribute value. ( Object )
"""
self.__value = value
@value.deleter
[docs] def value(self):
"""
This method is the deleter method for **self.__value** attribute.
"""
raise Exception("{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "value"))
#******************************************************************************************************************
#*** Class methods.
#******************************************************************************************************************
def __str__(self):
"""
This method returns the exception representation.
:return: Exception representation. ( String )
"""
return str(self.__value)
[docs]class ExecutionError(AbstractError):
"""
This class is used for execution exceptions.
"""
pass
[docs]class BreakIteration(AbstractError):
"""
This class is used to break nested loop iterations.
"""
pass
[docs]class AbstractParsingError(AbstractError):
"""
This class is the abstract base class for parsing related exceptions.
"""
pass
[docs]class FileStructureParsingError(AbstractParsingError):
"""
This class is used for exceptions raised while parsing file structure.
"""
pass
[docs]class AttributeStructureParsingError(AbstractParsingError):
"""
This class is used for exceptions raised while parsing attribute structure.
"""
def __init__(self, value, line=None):
"""
.. Sphinx: Statements updated for auto-documentation purpose.
:param value: Error value or message. ( String )
:param line: Line number where exception occured. ( Integer )
"""
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):
"""
This method is the property for **self.__line** attribute.
:return: self.__line. ( Integer )
"""
return self.__line
@line.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @handleExceptions(AssertionError)
def line(self, value):
"""
This method is the setter method for **self.__line** attribute.
:param value: Attribute value. ( Integer )
"""
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
#*** Sphinx: Decorator commented for auto-documentation purpose. @handleExceptions(Exception)
[docs] def line(self):
"""
This method is the deleter method for **self.__line** attribute.
"""
raise Exception("{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "line"))
#******************************************************************************************************************
#*** Class methods.
#******************************************************************************************************************
def __str__(self):
"""
This method returns the exception representation.
:return: Exception representation. ( String )
"""
if self.__line:
return "Line '{0}': '{1}'.".format(self.__line, str(self.value))
else:
return str(self.value)
[docs]class AbstractOsError(AbstractError):
"""
This class is the abstract base class for os related exceptions.
"""
pass
[docs]class PathExistsError(AbstractOsError):
"""
This class is used for non existing path exceptions.
"""
pass
[docs]class DirectoryExistsError(PathExistsError):
"""
This class is used for non existing directory exceptions.
"""
pass
[docs]class FileExistsError(PathExistsError):
"""
This class is used for non existing file exceptions.
"""
pass
[docs]class AbstractObjectError(AbstractError):
"""
This class is the abstract base class for object related exceptions.
"""
pass
[docs]class ObjectTypeError(AbstractObjectError):
"""
This class is used for invalid object type exceptions.
"""
pass
[docs]class ObjectExistsError(AbstractObjectError):
"""
This class is used for non existing object exceptions.
"""
pass
[docs]class AbstractUserError(AbstractError):
"""
This class is the abstract base class for user related exceptions.
"""
pass
[docs]class ProgrammingError(AbstractUserError):
"""
This class is used for programming exceptions.
"""
pass
[docs]class UserError(AbstractUserError):
"""
This class is used for user exceptions.
"""
pass
[docs]class AbstractNodeError(AbstractError):
"""
This class is the abstract base class for Node related exceptions.
"""
pass
[docs]class NodeAttributeTypeError(AbstractNodeError, ObjectTypeError):
"""
This class is the abstract base class for Node attributes type related exceptions.
"""
pass
[docs]class NodeAttributeExistsError(AbstractNodeError, ObjectExistsError):
"""
This class is used for non existing Node attribute exceptions.
"""
pass
[docs]class AbstractLibraryError(AbstractError):
"""
This class is the abstract base class for :mod:`library` module exceptions.
"""
pass
[docs]class LibraryInstantiationError(AbstractLibraryError):
"""
This class is used for :mod:`library` module :class:`library.Library` class instantiation exceptions.
"""
pass
[docs]class LibraryInitializationError(AbstractLibraryError):
"""
This class is used for :mod:`library` module :class:`library.Library` class initialization exceptions.
"""
pass
[docs]class LibraryExecutionError(AbstractLibraryError):
"""
This class is used for :mod:`library` module :class:`library.Library` class execution exceptions.
"""
pass
[docs]class AbstractServerError(AbstractError):
"""
This class is the abstract base class for :mod:`tcpServer` module exceptions.
"""
pass
[docs]class ServerOperationError(AbstractServerError):
"""
This class is used for :mod:`tcpServer` module :class:`tcpServer.TCPServer` class operations exceptions.
"""
pass