58 PyModuleDef_HEAD_INIT,
76 typedef std::unique_ptr<char[]> TScopedCString;
77 void assignScopedCString(TScopedCString& out,
const char* in)
81 const size_t n = strlen(in) + 1;
82 TScopedCString temp(
new char[n]);
83 memcpy(temp.get(), in, n);
95 experimental::assignScopedCString(name_,
name);
100 experimental::assignScopedCString(doc_,
doc);
107 preInject_ = callback;
114 postInject_ = callback;
123 LASS_ASSERT(!isInjected_);
124 classes_.push_back(&classDef);
129 LASS_ASSERT(!isInjected_);
130 enums_.push_back(enumDef);
135 LASS_ASSERT(!isInjected_);
136 NamedObject *tempObject =
new NamedObject;
137 experimental::assignScopedCString(tempObject->name,
name);
138 tempObject->object = object;
139 objects_.push_back(tempObject);
144 LASS_ASSERT(!isInjected_);
145 LongObject *tempObject =
new LongObject;
146 experimental::assignScopedCString(tempObject->name,
name);
147 tempObject->object = object;
148 longObjects_.push_back(tempObject);
153 LASS_ASSERT(!isInjected_);
154 StringObject* tempObject =
new StringObject;
155 experimental::assignScopedCString(tempObject->name,
name);
156 experimental::assignScopedCString(tempObject->object,
object);
157 stringObjects_.push_back(tempObject);
162 PyCFunction dispatcher,
const char*
name,
const char*
doc, PyCFunction& overloadChain)
164 TMethods::iterator i = ::std::find_if(methods_.begin(), methods_.end(), impl::NamePredicate(
name));
165 if (i == methods_.end())
167 methods_.push_back(impl::createPyMethodDef(
name, dispatcher, METH_VARARGS ,
doc));
172 overloadChain = i->ml_meth;
173 i->ml_meth = dispatcher;
180 LASS_ENFORCE_POINTER(module_);
181 PyModule_AddIntConstant(module_,
name, value);
187 LASS_ENFORCE_POINTER(module_);
188 PyModule_AddStringConstant(module_,
name, value);
199 LASS_ENFORCE_POINTER(module_);
200 const char* shortName = classDef.
name();
202 return PyModule_AddObjectRef(module_,
const_cast<char*
>(shortName), type) == 0;
209 PyObject* mod = doInject();
212 chainErrFormat(PyExc_ImportError,
"Failed to import '%s'", name_.get());
219PyObject* ModuleDefinition::doInject()
232 LASS_ASSERT(name_.get());
234 methods_.push_back(impl::createPyMethodDef(0, 0, 0, 0));
236 def_.m_name = name_.get();
237 def_.m_doc = doc_.get();
238 def_.m_methods = &methods_[0];
239 module_ = PyModule_Create(&def_);
245 for (
auto def: classes_)
252 for (
auto def: enums_)
254 PyObject* enumType = def->freezeDefinition(name_.get(),
nullptr);
255 if (PyModule_AddObjectRef(module_, def->name(), enumType) != 0)
260 for (TObjects::const_iterator obj = objects_.begin(); obj != objects_.end(); ++obj)
262 PyModule_AddObject(module_, (*obj)->name.get(), (*obj)->object);
264 for (TLongObjects::const_iterator obj = longObjects_.begin(); obj != longObjects_.end(); ++obj)
266 if (PyModule_AddIntConstant(module_, (*obj)->name.get(), (*obj)->object) != 0)
271 for (TStringObjects::const_iterator obj = stringObjects_.begin(); obj != stringObjects_.end(); ++obj)
273 if (PyModule_AddStringConstant(module_, (*obj)->name.get(), (*obj)->object.get()) != 0)
278 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.