| 241 | } |
| 242 | |
| 243 | PyTypeObject *make_class (const gsi::ClassBase *cls, bool as_static) |
| 244 | { |
| 245 | // drop non-standard names |
| 246 | if (tl::verbosity () >= 40) { |
| 247 | tl::info << tl::sprintf (tl::to_string (tr ("Creating class %s.%s")), PyModule_GetName (mp_module->module ()), cls->name ()); |
| 248 | } |
| 249 | |
| 250 | // NOTE: with as_static = true, this method produces a mixin. This is a class entirely consisting |
| 251 | // of static constants and child classes only. It can be mixed into an existing class for emulation |
| 252 | // additional base classes. |
| 253 | // Everything else, like properties and methods will not work as the method enumeration scheme is |
| 254 | // not capable of handling more than a single base class. |
| 255 | |
| 256 | PyTypeObject *pt = PythonClassClientData::py_type (*cls, as_static); |
| 257 | if (pt != 0) { |
| 258 | |
| 259 | if (! mp_module->is_class_of_module (cls)) { |
| 260 | |
| 261 | // class is already built, but not member of the module yet (e.g. |
| 262 | // on duplicate import into a new module object): add now without building again |
| 263 | |
| 264 | mp_module->register_class (cls); |
| 265 | tl_assert (mp_module->cls_for_type (pt) == cls); |
| 266 | |
| 267 | // add to the parent class as child class or add to module |
| 268 | |
| 269 | if (! cls->parent ()) { |
| 270 | PyList_Append (m_all_list, c2python (cls->name ())); |
| 271 | Py_INCREF ((PyObject *) pt); |
| 272 | PyModule_AddObject (mp_module->module (), cls->name ().c_str (), (PyObject *) pt); |
| 273 | } |
| 274 | |
| 275 | } |
| 276 | |
| 277 | return pt; |
| 278 | |
| 279 | } |
| 280 | |
| 281 | PythonRef bases; |
| 282 | |
| 283 | // mix-in unnamed extensions and get the base classes |
| 284 | |
| 285 | int n_bases = (cls->base () != 0 ? 1 : 0); |
| 286 | auto exts = m_extensions_for.find (cls); |
| 287 | if (exts != m_extensions_for.end ()) { |
| 288 | n_bases += int (exts->second.size ()); |
| 289 | } |
| 290 | |
| 291 | bases = PythonRef (PyTuple_New (n_bases)); |
| 292 | |
| 293 | int ibase = 0; |
| 294 | if (cls->base () != 0) { |
| 295 | PyTypeObject *pt = make_class (cls->base (), as_static); |
| 296 | PyObject *base = (PyObject *) pt; |
| 297 | Py_INCREF (base); |
| 298 | PyTuple_SetItem (bases.get (), ibase++, base); |
| 299 | } |
| 300 |
no test coverage detected