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