lsst.pex.exceptions  16.0
wrappers.py
Go to the documentation of this file.
1 # This file is part of pex_exceptions.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (https://www.lsst.org).
6 # See the COPYRIGHT file at the top-level directory of this distribution
7 # for details of code ownership.
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 
22 from __future__ import absolute_import
23 
24 __all__ = ["register", "ExceptionMeta", "Exception", "LogicError",
25  "DomainError", "InvalidParameterError", "LengthError",
26  "OutOfRangeError", "RuntimeError", "RangeError", "OverflowError",
27  "UnderflowError", "NotFoundError", "IoError", "TypeError",
28  "translate", "declare"]
29 
30 import warnings
31 import builtins
32 
33 from future.utils import with_metaclass
34 from . import exceptions
35 
36 registry = {}
37 
38 
39 def register(cls):
40  """A Python decorator that adds a Python exception wrapper to the registry that maps C++ Exceptions
41  to their Python wrapper classes.
42  """
43  registry[cls.WrappedClass] = cls
44  return cls
45 
46 
47 class ExceptionMeta(type):
48  """A metaclass for custom exception wrappers, which adds lookup of class attributes
49  by delegating to the Swig-generated wrapper.
50  """
51 
52  def __getattr__(self, name):
53  return getattr(self.WrappedClass, name)
54 
55 
56 @register
57 class Exception(with_metaclass(ExceptionMeta, builtins.Exception)):
58  """The base class for Python-wrapped LSST C++ exceptions.
59  """
60 
61  # wrappers.py is an implementation detail, not a public namespace, so we pretend this is defined
62  # in the package for pretty-printing purposes
63  __module__ = "lsst.pex.exceptions"
64 
65  WrappedClass = exceptions.Exception
66 
67  def __init__(self, arg, *args, **kwds):
68  if isinstance(arg, exceptions.Exception):
69  cpp = arg
70  message = cpp.what()
71  else:
72  message = arg
73  cpp = self.WrappedClass(message, *args, **kwds)
74  super(Exception, self).__init__(message)
75  self.cpp = cpp
76 
77  def __getattr__(self, name):
78  return getattr(self.cpp, name)
79 
80  def __repr__(self):
81  return "%s('%s')" % (type(self).__name__, self.cpp.what())
82 
83  def __str__(self):
84  return self.cpp.asString()
85 
86 
87 @register
89  WrappedClass = exceptions.LogicError
90 
91 
92 @register
94  WrappedClass = exceptions.DomainError
95 
96 
97 @register
100 
101 
102 @register
104  WrappedClass = exceptions.LengthError
105 
106 
107 @register
110 
111 
112 @register
113 class RuntimeError(Exception, builtins.RuntimeError):
114  WrappedClass = exceptions.RuntimeError
115 
116 
117 @register
119  WrappedClass = exceptions.RangeError
120 
121 
122 @register
123 class OverflowError(RuntimeError, builtins.OverflowError):
125 
126 
127 @register
128 class UnderflowError(RuntimeError, builtins.ArithmeticError):
130 
131 
132 @register
133 class NotFoundError(Exception, builtins.LookupError):
135 
136 
137 @register
138 class IoError(RuntimeError, builtins.IOError):
139  WrappedClass = exceptions.IoError
140 
141 
142 @register
143 class TypeError(RuntimeError, builtins.TypeError):
144  WrappedClass = exceptions.TypeError
145 
146 
147 def translate(cpp):
148  """Translate a C++ Exception instance to Python and return it."""
149  PyType = registry.get(type(cpp), None)
150  if PyType is None:
151  warnings.warn("Could not find appropriate Python type for C++ Exception")
152  PyType = Exception
153  return PyType(cpp)
154 
155 
156 def declare(module, exception_name, base, wrapped_class):
157  """Declare a new exception."""
158  setattr(module, exception_name, register(ExceptionMeta(exception_name, (base, ),
159  dict(WrappedClass=wrapped_class))))
Reports attempts to exceed implementation-defined length limits for some classes. ...
Definition: Runtime.h:76
Reports arguments outside the domain of an operation.
Definition: Runtime.h:57
Provides consistent interface for LSST exceptions.
Definition: Exception.h:106
Reports errors in external input/output operations.
Definition: Runtime.h:160
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
Reports when the result of an arithmetic operation is too large for the destination type...
Definition: Runtime.h:124
Reports when the result of an arithmetic operation is too small for the destination type...
Definition: Runtime.h:133
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
Reports attempts to access elements outside a valid range of indices.
Definition: Runtime.h:89
def __init__(self, arg, args, kwds)
Definition: wrappers.py:67
def declare(module, exception_name, base, wrapped_class)
Definition: wrappers.py:156
Reports invalid arguments.
Definition: Runtime.h:66
Reports errors from accepting an object of an unexpected or inappropriate type.
Definition: Runtime.h:167
Reports when the result of an operation cannot be represented by the destination type.
Definition: Runtime.h:115
Reports errors that are due to events beyond the control of the program.
Definition: Runtime.h:104