7#ifndef PXR_BASE_TF_PY_CLASS_METHOD_H
8#define PXR_BASE_TF_PY_CLASS_METHOD_H
12#include "pxr/external/boost/python/class.hpp"
13#include "pxr/external/boost/python/dict.hpp"
14#include "pxr/external/boost/python/object.hpp"
15#include "pxr/external/boost/python/def_visitor.hpp"
17PXR_NAMESPACE_OPEN_SCOPE
19namespace Tf_PyClassMethod {
21using namespace pxr_boost::python;
27struct _TfPyClassMethod : def_visitor<_TfPyClassMethod>
29 friend class def_visitor_access;
31 _TfPyClassMethod(
const std::string &methodName) :
32 _methodName(methodName) {}
33 explicit _TfPyClassMethod(
const char *methodName) :
34 _methodName(methodName) {}
36 template <
typename CLS>
37 void visit(CLS &c)
const
39 PyTypeObject* self = downcast<PyTypeObject>( c.ptr() );
40 dict d((handle<>(borrowed(self->tp_dict))));
42 object method(d[_methodName]);
44 c.attr(_methodName.c_str()) = object(
45 handle<>( PyClassMethod_New((_CallableCheck)(method.ptr()) )));
50 PyObject* _CallableCheck(PyObject* callable)
const
52 if (PyCallable_Check(expect_non_null(callable)))
55 PyErr_Format( PyExc_TypeError,
56 "classmethod expects callable object; got an object of type %s, "
57 "which is not callable",
58 callable->ob_type->tp_name);
60 throw_error_already_set();
64 const std::string _methodName;
81typedef Tf_PyClassMethod::_TfPyClassMethod TfPyClassMethod;
83PXR_NAMESPACE_CLOSE_SCOPE