Loading...
Searching...
No Matches
pyOverride.h
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_OVERRIDE_H
8#define PXR_BASE_TF_PY_OVERRIDE_H
9
10#include "pxr/pxr.h"
11
12#include "pxr/base/tf/pyLock.h"
13#include "pxr/base/tf/pyObjWrapper.h"
14
15#include <boost/python/override.hpp>
16
17PXR_NAMESPACE_OPEN_SCOPE
18
29{
30private:
32 friend class TfPyOverride;
33 explicit TfPyMethodResult(PyObject* x)
34 : m_obj(x)
35 {}
36
37public:
40
43
46
47 template <class T>
48 operator T()
49 {
50 TfPyLock lock;
51 boost::python::converter::return_from_python<T> converter;
52 return converter(m_obj.release());
53 }
54
55 template <class T>
56 operator T&() const
57 {
58 TfPyLock lock;
59 boost::python::converter::return_from_python<T&> converter;
60 return converter(
61 const_cast<boost::python::handle<>&>(m_obj).release());
62 }
63
64 template <class T>
65 T as(boost::type<T>* = 0)
66 {
67 TfPyLock lock;
68 boost::python::converter::return_from_python<T> converter;
69 return converter(m_obj.release());
70 }
71
72 template <class T>
73 T unchecked(boost::type<T>* = 0)
74 {
75 TfPyLock lock;
76 return boost::python::extract<T>(m_obj)();
77 }
78
79private:
80 mutable boost::python::handle<> m_obj;
81};
82
98{
99 // Helper to generate Py_BuildValue-style format strings at compile time.
100 template <typename Arg>
101 constexpr static char _PyObjArg()
102 {
103 return 'O';
104 }
105
106public:
108 TfPyOverride(boost::python::handle<> callable)
109 : TfPyObjWrapper(boost::python::object(callable))
110 {}
111
114 template <typename... Args>
116 operator()(Args const&... args) const
117 {
118 TfPyLock lock;
119 // Use the Args parameter pack together with the _PyObjArg helper to
120 // unpack the right number of 'O' elements into the format string.
121 static const char pyCallFormat[] =
122 { '(', _PyObjArg<Args>()..., ')', '\0' };
123
125 PyEval_CallFunction(
126 this->ptr(),
127 const_cast<char*>(pyCallFormat),
128 boost::python::converter::arg_to_python<Args>(args).get()...));
129 return x;
130 }
131};
132
133PXR_NAMESPACE_CLOSE_SCOPE
134
135#endif // PXR_BASE_TF_PY_OVERRIDE_H
Convenience class for accessing the Python Global Interpreter Lock.
Definition: pyLock.h:105
A reimplementation of boost::python::detail::method_result.
Definition: pyOverride.h:29
TfPyMethodResult & operator=(TfPyMethodResult const &other)
Implement assign to do python refcounting while holding the GIL.
TfPyMethodResult(TfPyMethodResult const &other)
Implement copy to do python refcounting while holding the GIL.
~TfPyMethodResult()
Implement dtor to do python refcounting while holding the GIL.
Boost Python object wrapper.
Definition: pyObjWrapper.h:80
TF_API PyObject * ptr() const
Underlying PyObject* access.
A reimplementation of boost::python::override.
Definition: pyOverride.h:98
TfPyOverride(boost::python::handle<> callable)
Clients must hold the GIL to construct.
Definition: pyOverride.h:108
TfPyMethodResult operator()(Args const &... args) const
Call the override.
Definition: pyOverride.h:116