48#if PY_VERSION_HEX < 0x030a0000
53int PyModule_AddObjectRef(PyObject* module,
const char* name, PyObject* value)
56 if (PyModule_AddObject(module, name, value) != 0)
78 PyModuleDef_HEAD_INIT,
96 typedef std::unique_ptr<char[]> TScopedCString;
97 void assignScopedCString(TScopedCString& out,
const char* in)
101 const size_t n = strlen(in) + 1;
102 TScopedCString temp(
new char[n]);
103 memcpy(temp.get(), in, n);
115 experimental::assignScopedCString(name_,
name);
120 experimental::assignScopedCString(doc_,
doc);
127 preInject_ = callback;
134 postInject_ = callback;
143 LASS_ASSERT(!isInjected_);
144 classes_.push_back(&classDef);
149 LASS_ASSERT(!isInjected_);
150 enums_.push_back(enumDef);
155 LASS_ASSERT(!isInjected_);
156 NamedObject *tempObject =
new NamedObject;
157 experimental::assignScopedCString(tempObject->name,
name);
158 tempObject->object = object;
159 objects_.push_back(tempObject);
164 LASS_ASSERT(!isInjected_);
165 LongObject *tempObject =
new LongObject;
166 experimental::assignScopedCString(tempObject->name,
name);
167 tempObject->object = object;
168 longObjects_.push_back(tempObject);
173 LASS_ASSERT(!isInjected_);
174 StringObject* tempObject =
new StringObject;
175 experimental::assignScopedCString(tempObject->name,
name);
176 experimental::assignScopedCString(tempObject->object,
object);
177 stringObjects_.push_back(tempObject);
182 PyCFunction dispatcher,
const char*
name,
const char*
doc, PyCFunction& overloadChain)
184 TMethods::iterator i = ::std::find_if(methods_.begin(), methods_.end(), impl::NamePredicate(
name));
185 if (i == methods_.end())
187 methods_.push_back(impl::createPyMethodDef(
name, dispatcher, METH_VARARGS ,
doc));
192 overloadChain = i->ml_meth;
193 i->ml_meth = dispatcher;
200 LASS_ENFORCE_POINTER(module_);
201 PyModule_AddIntConstant(module_,
name, value);
207 LASS_ENFORCE_POINTER(module_);
208 PyModule_AddStringConstant(module_,
name, value);
219 LASS_ENFORCE_POINTER(module_);
220 const char* shortName = classDef.
name();
222 return PyModule_AddObjectRef(module_,
const_cast<char*
>(shortName), type) == 0;
229 PyObject* mod = doInject();
232 chainErrFormat(PyExc_ImportError,
"Failed to import '%s'", name_.get());
239PyObject* ModuleDefinition::doInject()
252 LASS_ASSERT(name_.get());
254 methods_.push_back(impl::createPyMethodDef(0, 0, 0, 0));
256 def_.m_name = name_.get();
257 def_.m_doc = doc_.get();
258 def_.m_methods = &methods_[0];
259 module_ = PyModule_Create(&def_);
265 for (
auto def: classes_)
272 for (
auto def: enums_)
274 PyObject* enumType = def->freezeDefinition(name_.get(),
nullptr);
275 if (PyModule_AddObjectRef(module_, def->name(), enumType) != 0)
280 for (TObjects::const_iterator obj = objects_.begin(); obj != objects_.end(); ++obj)
282 PyModule_AddObject(module_, (*obj)->name.get(), (*obj)->object);
284 for (TLongObjects::const_iterator obj = longObjects_.begin(); obj != longObjects_.end(); ++obj)
286 if (PyModule_AddIntConstant(module_, (*obj)->name.get(), (*obj)->object) != 0)
291 for (TStringObjects::const_iterator obj = stringObjects_.begin(); obj != stringObjects_.end(); ++obj)
293 if (PyModule_AddStringConstant(module_, (*obj)->name.get(), (*obj)->object.get()) != 0)
298 postInject_(module_);
Base class of all enum definitions.
void injectLong(const char *name, long value)
Inject a long integer directly into an already created module.
bool injectClass(impl::ClassDefinition &classDef)
Inject a class definition directly into an already created module.
const char * doc() const
Get the module documentation string.
const char * name() const
Get the module name.
void setPreInject(const TPreInject &callback)
Set callback to be executed before module injection.
void setDoc(const char *doc)
Set the module documentation string.
void addObject(PyObject *object, const char *name)
Add an arbitrary Python object to the module.
void injectString(const char *name, const char *value)
Inject a string directly into an already created module.
void addLong(long object, const char *name)
Add a long integer constant to the module.
ModuleDefinition(const char *name, const char *doc=0)
Construct module definition with name and optional documentation.
void setName(const char *name)
Set the module name.
void addEnum(EnumDefinitionBase *enumDef)
Add an enum definition to the module.
util::Callback1< PyObject * > TPostInject
Callback type for post-injection hooks (called after module creation with module object).
void addFunctionDispatcher(PyCFunction dispatcher, const char *name, const char *doc, PyCFunction &overloadChain)
Add a function dispatcher to the module.
util::Callback0 TPreInject
Callback type for pre-injection hooks (called before module creation).
void setPostInject(const TPostInject &callback)
Set callback to be executed after module injection.
void addString(const char *object, const char *name)
Add a string constant to the module.
PyObject * inject()
Create and inject the Python module with all accumulated definitions.
void addClass(impl::ClassDefinition &classDef)
Add a class definition to the module.
Definition of a Python class.
const char * name() const
Get the class name.
PyObject * freezeDefinition(PyObject *module=nullptr)
Finalize the definition and create the Python type.
PyObject * chainErrFormat(PyObject *exception, const char *format,...)
Raise an explicitly chained Python exception.
Comprehensive C++ to Python binding library.
Library for Assembled Shared Sources.