HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
makePyConstructor.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 
25 #if !HBOOST_PP_IS_ITERATING
26 
27 #ifndef PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
28 #define PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
29 
30 /// \file tf/makePyConstructor.h
31 /// An injected constructor mechanism that works with polymorphic wrapped
32 /// classes.
33 
34 #ifndef TF_MAX_ARITY
35 # define TF_MAX_ARITY 7
36 #endif // TF_MAX_ARITY
37 
38 
39 #include "pxr/pxr.h"
40 #include "pxr/base/tf/api.h"
41 #include "pxr/base/tf/refPtr.h"
42 #include "pxr/base/tf/weakPtr.h"
43 #include "pxr/base/tf/diagnostic.h"
44 #include "pxr/base/tf/pyError.h"
45 #include "pxr/base/tf/pyIdentity.h"
46 #include "pxr/base/tf/pyUtils.h"
48 
49 #include "pxr/base/arch/demangle.h"
50 
51 #include <hboost/preprocessor/iterate.hpp>
52 #include <hboost/preprocessor/punctuation/comma_if.hpp>
53 #include <hboost/preprocessor/repetition/enum.hpp>
54 #include <hboost/preprocessor/repetition/enum_binary_params.hpp>
55 #include <hboost/preprocessor/repetition/enum_params.hpp>
56 #include <hboost/preprocessor/repetition/enum_trailing_binary_params.hpp>
57 #include <hboost/preprocessor/repetition/enum_trailing_params.hpp>
58 #include <hboost/preprocessor/repetition/repeat.hpp>
59 #include <hboost/preprocessor/seq/for_each.hpp>
60 #include <hboost/python/def_visitor.hpp>
61 #include <hboost/python/dict.hpp>
62 #include <hboost/python/errors.hpp>
63 #include <hboost/python/list.hpp>
64 #include <hboost/python/object/iterator.hpp>
65 #include <hboost/python/raw_function.hpp>
66 #include <hboost/python/tuple.hpp>
67 #include <hboost/python/type_id.hpp>
68 
69 #include <string>
70 
72 
73 // Helper for wrapping objects that are held by weak pointers, but may also be
74 // constructed from script. This lets one construct an object from script and
75 // stores a ref pointer to the C++ object inside the python object. This way,
76 // objects created from script are owned by script, but objects obtained from
77 // the C++ API cannot be owned by script. When the owning python object is
78 // collected, its ref pointer will go away and the C++ object will be
79 // deallocated.
80 //
81 // Example usage:
82 //
83 // class_<MyClass, MyClassPtr>("MyClass", no_init)
84 // .def(TfPyRefAndWeakPtr())
85 // .def(TfMakePyConstructor(MyClass::New))
86 // .def(...)
87 // ...
88 //
89 // TfMakePyConstructorWithVarArgs may be used to wrap an object so that it
90 // may be constructed with a variable number of positional and keyword
91 // arguments. The last two arguments of the function being wrapped must
92 // be a hboost::python::tuple and dict. These will contain the remaining
93 // positional and keyword args after required arguments are parsed.
94 //
95 // Example usage:
96 //
97 // static MyObjectRefPtr MyObjectFactory(
98 // int formalArg1, const std::string& formalArg2,
99 // const hboost::python::tuple& args, const hboost::python::dict& kwargs);
100 //
101 // class_<MyClass, MyClassPtr>("MyClass", no_init)
102 // .def(TfPyRefAndWeakPtr())
103 // .def(TfMakePyConstructorWithVarArgs(MyObjectFactory))
104 // .def(...)
105 //
106 // NOTE: The current implementation does not handle hboost::python::arg for
107 // specifying keywords for required arguments.
108 
109 namespace Tf_MakePyConstructor {
110 
111 namespace bp = hboost::python;
112 
113 template <typename CTOR>
114 struct InitVisitor : bp::def_visitor<InitVisitor<CTOR> > {
117  InitVisitor(const std::string &doc = std::string()) : _doc(doc) {}
118 
119  template <typename CLS>
120  void visit(CLS &c) const {
121  c.def("__init__", CTOR::template init_callable<CLS>(), _doc.c_str());
122  }
123 
124  template <class CLS, class Options>
125  void visit(CLS &c, char const* name, Options& options) const {
126  // Note: we ignore options.doc() in favor of _doc
127  c.def(name, CTOR::template init_callable<CLS>(options), _doc.c_str());
128  }
129 
130 };
131 
132 TF_API
133 bp::object _DummyInit(bp::tuple const & /* args */,
134  bp::dict const & /* kw */);
135 
136 template <typename CTOR>
137 struct NewVisitor : bp::def_visitor<NewVisitor<CTOR> > {
140  NewVisitor(const std::string &doc = std::string()) : _doc(doc) {}
141 
142  template <typename CLS>
143  void visit(CLS &c) const {
144  // If there's already a __new__ method, look through the staticmethod to
145  // get the underlying function, replace __new__ with that, then add the
146  // overload, and recreate the staticmethod. This is required because
147  // hboost python needs to have all overloads exported before you say
148  // .staticmethod.
149 
150  // Note that it looks like this should do nothing, but it actually does
151  // something! Here's what it does: looking up __new__ on c doesn't
152  // actually produce the staticmethod object -- it does a "descriptor
153  // __get__" which produces the underlying function. Replacing __new__
154  // with that underlying thing has the effect of unwrapping the
155  // staticmethod, which is exactly what we want.
156  if (PyObject_HasAttrString(c.ptr(), "__new__"))
157  c.attr("__new__") = c.attr("__new__");
158  c.def("__new__", CTOR::template __new__<CLS>, _doc.c_str());
159  c.staticmethod("__new__");
160 
161  //c.def("__init__", CTOR::template __init__<CLS>, _doc.c_str());
162  c.def("__init__", bp::raw_function(_DummyInit));
163  }
164 
165  template <class CLS, class Options>
166  void visit(CLS &c, char const* name, Options& options) const {
167  // If there's already a __new__ method, look through the staticmethod to
168  // get the underlying function, replace __new__ with that, then add the
169  // overload, and recreate the staticmethod. This is required because
170  // hboost python needs to have all overloads exported before you say
171  // .staticmethod.
172 
173  // Note that it looks like this should do nothing, but it actually does
174  // something! Here's what it does: looking up __new__ on c doesn't
175  // actually produce the staticmethod object -- it does a "descriptor
176  // __get__" which produces the underlying function. Replacing __new__
177  // with that underlying thing has the effect of unwrapping the
178  // staticmethod, which is exactly what we want.
179  if (PyObject_HasAttrString(c.ptr(), "__new__"))
180  c.attr("__new__") = c.attr("__new__");
181  c.def("__new__", CTOR::template __new__<CLS>,
182  // Note: we ignore options.doc() in favor of _doc
183  _doc.c_str(),
184  options.keywords(),
185  options.policies()
186  );
187  c.staticmethod("__new__");
188 
189  //c.def("__init__", CTOR::template __init__<CLS>, _doc.c_str());
190  c.def("__init__", bp::raw_function(_DummyInit));
191  }
192 
193 };
194 
195 
197 
198 template <typename T>
200  static void PostInstall(object const &self, T const &t,
201  const void *) {}
202 };
203 
204 // Specialize install policy for refptrs.
205 template <typename T>
208  "Type T must support refcount unique changed notification.");
209  static void PostInstall(object const &self, TfRefPtr<T> const &ptr,
210  const void *uniqueId) {
211  // Stash a self-reference ref ptr into the python object that will
212  // keep the object alive. Need to get a ref ptr to the held type,
213  // since that's what's wrapped.
214  Tf_PyAddPythonOwnership(ptr, uniqueId, self.ptr());
215  }
216 };
217 
218 template <typename CLS, typename T>
219 void Install(object const &self, T const &t, TfErrorMark const &m) {
220  // Stick the weakptr into the python object self to complete
221  // construction.
222  typedef typename CLS::metadata::holder Holder;
223  typedef typename bp::objects::instance<Holder> instance_t;
224  typedef InstallPolicy<T> Policy;
225  typedef typename CLS::metadata::held_type HeldType;
226 
227  // CODE_COVERAGE_OFF
228  void *memory = Holder::
229  // CODE_COVERAGE_ON
230  allocate(self.ptr(), offsetof(instance_t, storage), sizeof(Holder));
231  try {
232  HeldType held(t);
233  Holder *holder = (new (memory) Holder(held));
234  // If there was a TfError, raise that back to python.
236  bp::throw_error_already_set();
237  // If no TfError, but object construction failed, raise a generic error
238  // back to python.
239  if (!held)
240  TfPyThrowRuntimeError("could not construct " +
241  ArchGetDemangled(typeid(HeldType)));
242  bp::detail::initialize_wrapper(self.ptr(), &(*(held.operator->())));
243  holder->install(self.ptr());
244 
245  // Set object identity
246  Tf_PySetPythonIdentity(held, self.ptr());
247 
248  Policy::PostInstall(self, t, held.GetUniqueIdentifier());
249 
250  } catch(...) {
251  Holder::deallocate(self.ptr(), memory); throw;
252  }
253 
254 }
255 
256 
257 template <typename WeakPtr, typename P>
259  typedef std::remove_reference_t<P> Ptr;
260  bool convertible() const {
261  // FIXME should actually check here... It's not really horrible because
262  // if the conversion will fail, we'll just get a runtime error down
263  // below when we try to create the resulting object. That's basically
264  // what we want anyway.
265  return true;
266  }
267  PyObject *operator()(Ptr const &p) const {
268  typedef InstallPolicy<Ptr> Policy;
269  WeakPtr ptr(static_cast<typename WeakPtr::DataType *>
270  (get_pointer(p)));
271 
272  // If resulting pointer is null, return None.
273  if (!ptr)
274  return bp::incref(Py_None);
275 
276  // The to-python converter will set identity here.
277  object result(ptr);
278 
279  Policy::PostInstall(result, p, ptr.GetUniqueIdentifier());
280  return bp::incref(result.ptr());
281  }
282  // Required for hboost.python signature generator, in play when
283  // HBOOST_PYTHON_NO_PY_SIGNATURES is undefined.
284  PyTypeObject const *get_pytype() const {
285  return hboost::python::objects::registered_class_object(
286  hboost::python::type_id<typename WeakPtr::DataType>()).get();
287  }
288 };
289 
290 template <typename WeakPtr = void>
292  template <typename FactoryResultPtr>
293  struct apply {
299  };
300 };
301 
302 template <typename SIG>
303 struct CtorBase {
304  typedef SIG Sig;
305  static Sig *_func;
306  static void SetFunc(Sig *func) {
307  if (!_func)
308  _func = func;
309  else {
310  // CODE_COVERAGE_OFF
311  TF_CODING_ERROR("Ctor with signature '%s' is already registered. "
312  "Duplicate will be ignored.",
313  ArchGetDemangled(typeid(Sig)).c_str());
314  // CODE_COVERAGE_ON
315  }
316  }
317 };
318 
319 template <typename SIG> SIG *CtorBase<SIG>::_func = 0;
320 
321 // The following preprocessor code repeatedly includes this file to generate
322 // specializations of Ctor taking 0 through TF_MAX_ARITY parameters.
323 template <typename SIG> struct InitCtor;
324 template <typename SIG> struct InitCtorWithBackReference;
325 template <typename SIG> struct InitCtorWithVarArgs;
326 template <typename SIG> struct NewCtor;
327 template <typename SIG> struct NewCtorWithClassReference;
328 #define HBOOST_PP_ITERATION_LIMITS (0, TF_MAX_ARITY)
329 #define HBOOST_PP_FILENAME_1 "pxr/base/tf/makePyConstructor.h"
330 #include HBOOST_PP_ITERATE()
331 /* comment needed for scons dependency scanner
332 #include "pxr/base/tf/makePyConstructor.h"
333 */
334 
335 }
336 
337 
338 template <typename T>
342  // Instantiate to set static constructor pointer, then return the visitor.
346 }
347 
348 template <typename T>
352  // Instantiate to set static constructor pointer, then return the visitor.
356 }
357 
358 template <typename T>
362  // Instantiate to set static constructor pointer, then return the visitor.
366 }
367 
368 template <typename T>
371 TfMakePyNew(T *func, const std::string &doc = std::string()) {
372  // Instantiate to set static constructor pointer, then return the visitor.
376 }
377 
378 template <typename T>
382  // Instantiate to set static constructor pointer, then return the visitor.
386 }
387 
388 
389 template <typename T = void>
391 
392 template <typename T> struct Tf_PySequenceToListConverterRefPtrFactory;
393 
394 /// A \c hboost::python result converter generator which converts standard
395 /// library sequences to lists of python owned objects.
397  template <typename T>
398  struct apply {
400  };
401 };
402 
403 // XXX: would be nicer to be able to compose converters with factory
404 template <typename T>
406  typedef std::remove_reference_t<T> SeqType;
407  bool convertible() const {
408  return true;
409  }
410  PyObject *operator()(T seq) const {
411  using namespace hboost::python;
412 
415 
416  hboost::python::list l;
417  for (typename SeqType::const_iterator i = seq.begin();
418  i != seq.end(); ++i) {
419  l.append(object(handle<>(RefPtrFactory()(*i))));
420  }
421  return hboost::python::incref(l.ptr());
422  }
423  // Required for hboost.python signature generator, in play when
424  // HBOOST_PYTHON_NO_PY_SIGNATURES is undefined.
425  PyTypeObject const *get_pytype() const {
426  return &PyList_Type;
427  }
428 };
429 
431 
432 #endif // PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
433 
434 #else // HBOOST_PP_IS_ITERATING
435 
436 #define N HBOOST_PP_ITERATION()
437 
438 #define SIGNATURE R (HBOOST_PP_ENUM_PARAMS(N, A))
439 #define PARAMLIST HBOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, a)
440 #define ARGLIST HBOOST_PP_ENUM_PARAMS(N, a)
441 
442 // This generates multi-argument specializations for Tf_MakePyConstructor::Ctor.
443 // One nice thing about this style of PP repetition is that the debugger will
444 // actually step you over these lines for any instantiation of Ctor.
445 
446 template <typename R HBOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
447 struct InitCtor<SIGNATURE> : CtorBase<SIGNATURE> {
448  typedef CtorBase<SIGNATURE> Base;
449  typedef typename Base::Sig Sig;
450  InitCtor(Sig *func) { Base::SetFunc(func); }
451 
452  template <typename CLS>
453  static bp::object init_callable() {
454  return bp::make_function(__init__<CLS>);
455  }
456 
457  template <typename CLS, typename Options>
458  static bp::object init_callable(Options& o) {
459  return bp::make_function(__init__<CLS>, o.policies(), o.keywords()) ;
460  }
461 
462  template <typename CLS>
463  static void __init__(object &self PARAMLIST) {
464  TfErrorMark m;
465  Install<CLS>(self, Base::_func(ARGLIST), m);
466  }
467 };
468 
469 template <typename R HBOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
470 struct NewCtor<SIGNATURE> : CtorBase<SIGNATURE> {
471  typedef CtorBase<SIGNATURE> Base;
472  typedef typename Base::Sig Sig;
473  NewCtor(Sig *func) { Base::SetFunc(func); }
474 
475  template <class CLS>
476  static bp::object __new__(object &cls PARAMLIST) {
477  typedef typename CLS::metadata::held_type HeldType;
478  TfErrorMark m;
479  R r((Base::_func(ARGLIST)));
480  HeldType h((r));
482  bp::throw_error_already_set();
483  bp::object ret = TfPyObject(h);
484  if (TfPyIsNone(ret))
485  TfPyThrowRuntimeError("could not construct " +
486  ArchGetDemangled(typeid(HeldType)));
487 
488  bp::detail::initialize_wrapper(ret.ptr(), get_pointer(h));
489  // make the object have the right class.
490  bp::setattr(ret, "__class__", cls);
491 
492  InstallPolicy<R>::PostInstall(ret, r, h.GetUniqueIdentifier());
493  return ret;
494  }
495 };
496 
497 #define VAR_SIGNATURE \
498  R (HBOOST_PP_ENUM_PARAMS(N, A) HBOOST_PP_COMMA_IF(N) \
499  const bp::tuple&, const bp::dict&)
500 
501 #define FORMAT_STR(z, n, data) "%s, "
502 #define ARG_TYPE_STR_A(z, n, data) bp::type_id<A##n>().name()
503 
504 #define EXTRACT_REQ_ARG_A(z, n, data) \
505  /* The n'th required arg is stored at n + 1 in the positional args */ \
506  /* tuple as the 0'th element is always the self object */ \
507  bp::extract<typename std::remove_reference_t<A##n>>(data[n + 1])
508 
509 template <typename R HBOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
510 struct InitCtorWithVarArgs<VAR_SIGNATURE> : CtorBase<VAR_SIGNATURE> {
511  typedef CtorBase<VAR_SIGNATURE> Base;
512  typedef typename Base::Sig Sig;
513  InitCtorWithVarArgs(Sig *func) { Base::SetFunc(func); }
514 
515  template <typename CLS>
516  static bp::object init_callable() {
517  // Specify min_args as 1 to account for just the 'self' argument.
518  // min_args really should be N + 1. However, we want to do this check
519  // ourselves later so we can emit a better error message.
520  return bp::raw_function(__init__<CLS>, /* min_args = */ 1);
521  }
522 
523  template <typename CLS, typename Options>
524  static bp::object init_callable(Options& options) {
525  // XXX: Note ignoring options.keywords(), current implementation can't
526  // handle that correctly.
527  return bp::raw_function(
528  bp::make_function(__init__<CLS>, options.policies()),
529  /* min_args = */ 1);
530  }
531 
532  template <typename CLS>
533  static bp::object __init__(const bp::tuple& args, const bp::dict& kwargs) {
534  TfErrorMark m;
535 
536  const unsigned int numArgs = bp::len(args);
537  if (numArgs - 1 < N) {
538  // User didn't provide enough positional arguments for the factory
539  // function. Complain.
542  "Arguments to __init__ did not match C++ signature:\n"
543  "\t__init__(" HBOOST_PP_REPEAT(N, FORMAT_STR, 0) "...)"
544  HBOOST_PP_COMMA_IF(N) HBOOST_PP_ENUM(N, ARG_TYPE_STR_A, 0)
545  )
546  );
547  return bp::object();
548  }
549 
550  Install<CLS>(
551  // self object for new instance is the first arg to __init__
552  args[0],
553 
554  // Slice the first N arguments from positional arguments as
555  // those are the required arguments for the factory function.
556  Base::_func(
557  HBOOST_PP_ENUM(N, EXTRACT_REQ_ARG_A, args) HBOOST_PP_COMMA_IF(N)
558  bp::tuple(args.slice(N + 1, numArgs)), kwargs),
559  m);
560 
561  return bp::object();
562  }
563 
564 };
565 
566 #if N > 0
567 #undef PARAMLIST
568 #define PARAMLIST HBOOST_PP_ENUM_BINARY_PARAMS(N, A, a)
569 
570 // This is a variant of Ctor which includes a back reference to self
571 // (the Python object being initialized) in the args passed to the
572 // constructor. This is used to expose the factory methods for classes
573 // which we expect to subclass in Python. When the constructor is called,
574 // it can examine self and initialize itself appropriately.
575 
576 template <typename R HBOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
577 struct InitCtorWithBackReference<SIGNATURE> : CtorBase<SIGNATURE> {
578  typedef CtorBase<SIGNATURE> Base;
579  typedef typename Base::Sig Sig;
580  InitCtorWithBackReference(Sig *func) { Base::SetFunc(func); }
581 
582  template <typename CLS>
583  static bp::object init_callable() {
584  return bp::make_function(__init__<CLS>);
585  }
586 
587  template <typename CLS, typename Options>
588  static bp::object init_callable(Options& o) {
589  return bp::make_function(__init__<CLS>, o.policies(), o.keywords());
590  }
591 
592  template <typename CLS>
593  static void __init__(PARAMLIST) {
594  TfErrorMark m;
595  Install<CLS>(a0, Base::_func(ARGLIST), m);
596  }
597 };
598 
599 template <typename R HBOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
600 struct NewCtorWithClassReference<SIGNATURE> : CtorBase<SIGNATURE> {
601  typedef CtorBase<SIGNATURE> Base;
602  typedef typename Base::Sig Sig;
603  NewCtorWithClassReference(Sig *func) { Base::SetFunc(func); }
604 
605  template <class CLS>
606  static bp::object __new__(PARAMLIST) {
607  typedef typename CLS::metadata::held_type HeldType;
608  TfErrorMark m;
609  R r(Base::_func(ARGLIST));
610  HeldType h(r);
612  bp::throw_error_already_set();
613  bp::object ret = TfPyObject(h);
614  if (TfPyIsNone(ret))
615  TfPyThrowRuntimeError("could not construct " +
616  ArchGetDemangled(typeid(HeldType)));
617 
618  bp::detail::initialize_wrapper(ret.ptr(), get_pointer(h));
619  // make the object have the right class.
620  bp::setattr(ret, "__class__", a0);
621 
622  InstallPolicy<R>::PostInstall(ret, r, h.GetUniqueIdentifier());
623  return ret;
624  }
625 };
626 
627 #endif
628 
629 #undef N
630 #undef SIGNATURE
631 #undef PARAMLIST
632 #undef ARGLIST
633 #undef VAR_SIGNATURE
634 #undef FORMAT_STR
635 #undef ARG_TYPE_STR_A
636 #undef EXTRACT_REQ_ARG_A
637 
638 #endif // HBOOST_PP_IS_ITERATING
GLsizei GLenum GLsizei GLsizei GLuint memory
Definition: RE_OGL.h:202
Tf_MakePyConstructor::NewVisitor< typename Tf_MakePyConstructor::NewCtor< T > > TfMakePyNew(T *func, const std::string &doc=std::string())
TF_API std::string TfStringPrintf(const char *fmt,...)
Tf_MakePyConstructor::InitVisitor< typename Tf_MakePyConstructor::InitCtor< T > > TfMakePyConstructor(T *func, const std::string &doc=std::string())
#define TF_API
Definition: api.h:40
_RefPtrFactoryConverter< WeakPtrType, FactoryResultPtr > type
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:322
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Tf_MakePyConstructor::InitVisitor< typename Tf_MakePyConstructor::InitCtorWithVarArgs< T > > TfMakePyConstructorWithVarArgs(T *func, const std::string &doc=std::string())
#define TF_CODING_ERROR
Tf_PySequenceToListConverterRefPtrFactory< T > type
PyObject * operator()(Ptr const &p) const
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
**But if you need a result
Definition: thread.h:613
PyTypeObject const * get_pytype() const
Tf_MakePyConstructor::InitVisitor< typename Tf_MakePyConstructor::InitCtorWithBackReference< T > > TfMakePyConstructorWithBackReference(T *func, const std::string &doc=std::string())
PXR_NAMESPACE_OPEN_SCOPE TF_API bool TfPyConvertTfErrorsToPythonException(TfErrorMark const &m)
Tf_MakePyConstructor::NewVisitor< typename Tf_MakePyConstructor::NewCtorWithClassReference< T > > TfMakePyNewWithClassReference(T *func, const std::string &doc=std::string())
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
Definition: weakPtrFacade.h:83
std::weak_ptr< T > WeakPtr
Definition: Types.h:115
NewVisitor(const std::string &doc=std::string())
InitVisitor(const std::string &doc=std::string())
TF_API void TfPyThrowTypeError(const char *msg)
hboost::python::object TfPyObject(T const &t, bool complainOnFailure=true)
Definition: pyUtils.h:144
GLuint const GLchar * name
Definition: glcorearb.h:786
GLdouble t
Definition: glad.h:2397
void visit(CLS &c, char const *name, Options &options) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
GLenum func
Definition: glcorearb.h:783
std::enable_if_t< Tf_PyIsRefPtr< Ptr >::value > Tf_PySetPythonIdentity(Ptr const &, PyObject *)
Definition: pyIdentity.h:231
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
void Tf_PyAddPythonOwnership(Ptr const &t, const void *uniqueId, PyObject *obj)
Definition: pyIdentity.h:261
auto ptr(T p) -> const void *
Definition: format.h:2448
TF_API bp::object _DummyInit(bp::tuple const &, bp::dict const &)
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
void Install(object const &self, T const &t, TfErrorMark const &m)
GA_API const UT_StringHolder N
**If you just want to fire and args
Definition: thread.h:609
std::conditional_t< std::is_same< WeakPtr, void >::value, TfWeakPtr< typename FactoryResultPtr::DataType >, WeakPtr > WeakPtrType
static void SetFunc(Sig *func)
GLboolean r
Definition: glcorearb.h:1222
static void PostInstall(object const &self, TfRefPtr< T > const &ptr, const void *uniqueId)
type
Definition: core.h:1059
static void PostInstall(object const &self, T const &t, const void *)
TF_API bool TfPyIsNone(hboost::python::object const &obj)
Return true iff obj is None.
TF_API void TfPyThrowRuntimeError(const char *msg)
void visit(CLS &c, char const *name, Options &options) const