lsst.pex.exceptions  15.0-2-ge3d7f4b+1
wrappers.py
Go to the documentation of this file.
1 from __future__ import absolute_import
2 
3 __all__ = ["register", "ExceptionMeta", "Exception", "LogicError",
4  "DomainError", "InvalidParameterError", "LengthError",
5  "OutOfRangeError", "RuntimeError", "RangeError", "OverflowError",
6  "UnderflowError", "NotFoundError", "IoError", "TypeError",
7  "translate", "declare"]
8 
9 import warnings
10 import builtins
11 
12 from future.utils import with_metaclass
13 from . import exceptions
14 
15 registry = {}
16 
17 
18 def register(cls):
19  """A Python decorator that adds a Python exception wrapper to the registry that maps C++ Exceptions
20  to their Python wrapper classes.
21  """
22  registry[cls.WrappedClass] = cls
23  return cls
24 
25 
26 class ExceptionMeta(type):
27  """A metaclass for custom exception wrappers, which adds lookup of class attributes
28  by delegating to the Swig-generated wrapper.
29  """
30 
31  def __getattr__(self, name):
32  return getattr(self.WrappedClass, name)
33 
34 
35 @register
36 class Exception(with_metaclass(ExceptionMeta, builtins.Exception)):
37  """The base class for Python-wrapped LSST C++ exceptions.
38  """
39 
40  # wrappers.py is an implementation detail, not a public namespace, so we pretend this is defined
41  # in the package for pretty-printing purposes
42  __module__ = "lsst.pex.exceptions"
43 
44  WrappedClass = exceptions.Exception
45 
46  def __init__(self, arg, *args, **kwds):
47  if isinstance(arg, exceptions.Exception):
48  cpp = arg
49  message = cpp.what()
50  else:
51  message = arg
52  cpp = self.WrappedClass(message, *args, **kwds)
53  super(Exception, self).__init__(message)
54  self.cpp = cpp
55 
56  def __getattr__(self, name):
57  return getattr(self.cpp, name)
58 
59  def __repr__(self):
60  return "%s('%s')" % (type(self).__name__, self.cpp.what())
61 
62  def __str__(self):
63  return self.cpp.asString()
64 
65 
66 @register
68  WrappedClass = exceptions.LogicError
69 
70 
71 @register
73  WrappedClass = exceptions.DomainError
74 
75 
76 @register
79 
80 
81 @register
83  WrappedClass = exceptions.LengthError
84 
85 
86 @register
89 
90 
91 @register
92 class RuntimeError(Exception, builtins.RuntimeError):
93  WrappedClass = exceptions.RuntimeError
94 
95 
96 @register
98  WrappedClass = exceptions.RangeError
99 
100 
101 @register
102 class OverflowError(RuntimeError, builtins.OverflowError):
104 
105 
106 @register
107 class UnderflowError(RuntimeError, builtins.ArithmeticError):
109 
110 
111 @register
112 class NotFoundError(Exception, builtins.LookupError):
114 
115 
116 @register
117 class IoError(RuntimeError, builtins.IOError):
118  WrappedClass = exceptions.IoError
119 
120 
121 @register
122 class TypeError(RuntimeError, builtins.TypeError):
123  WrappedClass = exceptions.TypeError
124 
125 
126 def translate(cpp):
127  """Translate a C++ Exception instance to Python and return it."""
128  PyType = registry.get(type(cpp), None)
129  if PyType is None:
130  warnings.warn("Could not find appropriate Python type for C++ Exception")
131  PyType = Exception
132  return PyType(cpp)
133 
134 
135 def declare(module, exception_name, base, wrapped_class):
136  """Declare a new exception."""
137  setattr(module, exception_name, register(ExceptionMeta(exception_name, (base, ),
138  dict(WrappedClass=wrapped_class))))
def __init__(self, arg, args, kwds)
Definition: wrappers.py:46
def declare(module, exception_name, base, wrapped_class)
Definition: wrappers.py:135