HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyError.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_PY_ERROR_H
25 #define PXR_BASE_TF_PY_ERROR_H
26 
27 /// \file tf/error.h
28 /// Provide facilities for error handling in script.
29 
30 #include "pxr/pxr.h"
31 
32 #include "pxr/base/tf/api.h"
33 #include "pxr/base/tf/errorMark.h"
34 
35 #include <hboost/python/default_call_policies.hpp>
36 
38 
39 /// Converts any \a TfError objects in \a m into python exceptions. User code
40 /// should generally not have to call this. User code should generally not
41 /// have to call this, unless it's manually bridging between C++ & Python.
42 TF_API
44 
45 /// Convert the current python exception to \a TfError objects and post them
46 /// to the error system. User code should generally not have to call this,
47 /// unless it's manually bridging between C++ & Python.
48 TF_API
50 
51 /// \class TfPyRaiseOnError
52 ///
53 /// A hboost.python call policy class which, when applied to a wrapped
54 /// function, will create an error mark before calling the function, and check
55 /// that error mark after the function has completed. If any TfErrors have
56 /// occurred, they will be raised as python exceptions.
57 ///
58 /// This facility does not need to be used by clients in general. It is only
59 /// required for wrapped functions and methods that do not appear directly in an
60 /// extension module. For instance, the map and sequence proxy objects use
61 /// this, since they are created on the fly.
62 template <typename Base = hboost::python::default_call_policies>
63 struct TfPyRaiseOnError : Base
64 {
65  public:
66 
67  // This call policy provides a customized argument_package. We need to do
68  // this to store the TfErrorMark that we use to collect TfErrors that
69  // occurred during the call and convert them to a python exception at the
70  // end. It doesn't work to do this in the precall() and postcall()
71  // because if the call itself throws a c++ exception, the postcall() isn't
72  // executed and we can't destroy the TfErrorMark, leaving it dangling.
73  // Using the argument_package solves this since it is a local variable it
74  // will be destroyed whether or not the call throws. This is not really a
75  // publicly documented hboost.python feature, however. :-/
76  template <class BaseArgs>
78  /* implicit */ErrorMarkAndArgs(BaseArgs base_) : base(base_) {}
79  operator const BaseArgs &() const { return base; }
80  operator BaseArgs &() { return base; }
81  BaseArgs base;
83  };
85 
86  /// Default constructor.
88 
89  // Only accept our argument_package type, since we must ensure that we're
90  // using it so we track a TfErrorMark.
91  bool precall(argument_package const &a) { return Base::precall(a); }
92 
93  // Only accept our argument_package type, since we must ensure that we're
94  // using it so we track a TfErrorMark.
95  PyObject *postcall(argument_package const &a, PyObject *result) {
96  result = Base::postcall(a, result);
98  Py_DECREF(result);
99  result = NULL;
100  }
101  return result;
102  }
103 };
104 
108  if (clearOnDestruction)
109  mark.Clear();
110  }
111  void Dismiss() { clearOnDestruction = false; }
114 };
115 
117 
118 #endif // PXR_BASE_TF_PY_ERROR_H
bool precall(argument_package const &a)
Definition: pyError.h:91
#define TF_API
Definition: api.h:40
ErrorMarkAndArgs< typename Base::argument_package > argument_package
Definition: pyError.h:84
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
**But if you need a result
Definition: thread.h:613
PXR_NAMESPACE_OPEN_SCOPE TF_API bool TfPyConvertTfErrorsToPythonException(TfErrorMark const &m)
bool clearOnDestruction
Definition: pyError.h:113
TfErrorMark mark
Definition: pyError.h:112
ErrorMarkAndArgs(BaseArgs base_)
Definition: pyError.h:78
TfPyRaiseOnError()
Default constructor.
Definition: pyError.h:87
TF_API void TfPyConvertPythonExceptionToTfErrors()
bool Clear() const
Definition: errorMark.h:109
void Dismiss()
Definition: pyError.h:111
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
PyObject * postcall(argument_package const &a, PyObject *result)
Definition: pyError.h:95