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 terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_TF_PY_ERROR_H
8 #define PXR_BASE_TF_PY_ERROR_H
9 
10 /// \file tf/error.h
11 /// Provide facilities for error handling in script.
12 
13 #include "pxr/pxr.h"
14 
15 #include "pxr/base/tf/api.h"
16 #include "pxr/base/tf/errorMark.h"
17 
18 #include "pxr/external/boost/python/default_call_policies.hpp"
19 
21 
22 /// Converts any \a TfError objects in \a m into python exceptions. User code
23 /// should generally not have to call this. User code should generally not
24 /// have to call this, unless it's manually bridging between C++ & Python.
25 TF_API
27 
28 /// Convert the current python exception to \a TfError objects and post them
29 /// to the error system. User code should generally not have to call this,
30 /// unless it's manually bridging between C++ & Python.
31 TF_API
33 
34 /// \class TfPyRaiseOnError
35 ///
36 /// A boost.python call policy class which, when applied to a wrapped
37 /// function, will create an error mark before calling the function, and check
38 /// that error mark after the function has completed. If any TfErrors have
39 /// occurred, they will be raised as python exceptions.
40 ///
41 /// This facility does not need to be used by clients in general. It is only
42 /// required for wrapped functions and methods that do not appear directly in an
43 /// extension module. For instance, the map and sequence proxy objects use
44 /// this, since they are created on the fly.
45 template <typename Base = pxr_boost::python::default_call_policies>
46 struct TfPyRaiseOnError : Base
47 {
48  public:
49 
50  // This call policy provides a customized argument_package. We need to do
51  // this to store the TfErrorMark that we use to collect TfErrors that
52  // occurred during the call and convert them to a python exception at the
53  // end. It doesn't work to do this in the precall() and postcall()
54  // because if the call itself throws a c++ exception, the postcall() isn't
55  // executed and we can't destroy the TfErrorMark, leaving it dangling.
56  // Using the argument_package solves this since it is a local variable it
57  // will be destroyed whether or not the call throws. This is not really a
58  // publicly documented boost.python feature, however. :-/
59  template <class BaseArgs>
61  /* implicit */ErrorMarkAndArgs(BaseArgs base_) : base(base_) {}
62  operator const BaseArgs &() const { return base; }
63  operator BaseArgs &() { return base; }
64  BaseArgs base;
66  };
68 
69  /// Default constructor.
71 
72  // Only accept our argument_package type, since we must ensure that we're
73  // using it so we track a TfErrorMark.
74  bool precall(argument_package const &a) { return Base::precall(a); }
75 
76  // Only accept our argument_package type, since we must ensure that we're
77  // using it so we track a TfErrorMark.
78  PyObject *postcall(argument_package const &a, PyObject *result) {
79  result = Base::postcall(a, result);
81  Py_DECREF(result);
82  result = NULL;
83  }
84  return result;
85  }
86 };
87 
89 
90 #endif // PXR_BASE_TF_PY_ERROR_H
bool precall(argument_package const &a)
Definition: pyError.h:74
#define TF_API
Definition: api.h:23
ErrorMarkAndArgs< typename Base::argument_package > argument_package
Definition: pyError.h:67
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
**But if you need a result
Definition: thread.h:622
PXR_NAMESPACE_OPEN_SCOPE TF_API bool TfPyConvertTfErrorsToPythonException(TfErrorMark const &m)
ErrorMarkAndArgs(BaseArgs base_)
Definition: pyError.h:61
TfPyRaiseOnError()
Default constructor.
Definition: pyError.h:70
TF_API void TfPyConvertPythonExceptionToTfErrors()
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
PyObject * postcall(argument_package const &a, PyObject *result)
Definition: pyError.h:78