From 49b72fb1985a40515eab9a1783d2a9d1bb7d8a47 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 14:22:08 +0100 Subject: [PATCH] Move Python support code from libp3interrogatedb to generated module This prevents libp3interrogatedb from having a dependency on the Python library. See #387 --- dtool/src/dtoolbase/typeHandle_ext.cxx | 3 +- .../interfaceMakerPythonNative.cxx | 2 +- dtool/src/interrogate/interrogate_module.cxx | 7 +- dtool/src/interrogatedb/dtool_super_base.cxx | 194 +-- .../p3interrogatedb_composite1.cxx | 1 - .../p3interrogatedb_composite2.cxx | 3 - dtool/src/interrogatedb/py_compat.cxx | 7 - dtool/src/interrogatedb/py_compat.h | 9 +- dtool/src/interrogatedb/py_panda.I | 19 +- dtool/src/interrogatedb/py_panda.cxx | 93 +- dtool/src/interrogatedb/py_panda.h | 81 +- dtool/src/interrogatedb/py_wrappers.cxx | 1439 +++++++++-------- dtool/src/interrogatedb/py_wrappers.h | 29 +- makepanda/makepanda.py | 11 +- makepanda/makepandacore.py | 42 + panda/src/event/asyncFuture_ext.cxx | 9 +- 16 files changed, 977 insertions(+), 972 deletions(-) diff --git a/dtool/src/dtoolbase/typeHandle_ext.cxx b/dtool/src/dtoolbase/typeHandle_ext.cxx index 2064e42844..c52b04aabd 100644 --- a/dtool/src/dtoolbase/typeHandle_ext.cxx +++ b/dtool/src/dtoolbase/typeHandle_ext.cxx @@ -22,7 +22,8 @@ */ TypeHandle Extension:: make(PyTypeObject *tp) { - if (!PyType_IsSubtype(tp, &Dtool_DTOOL_SUPER_BASE._PyType)) { + Dtool_PyTypedObject *super_base = Dtool_GetSuperBase(); + if (!PyType_IsSubtype(tp, (PyTypeObject *)super_base)) { PyErr_SetString(PyExc_TypeError, "a Panda type is required"); return TypeHandle::none(); } diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 60d2dd6466..c0316ee5c4 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -3097,7 +3097,7 @@ write_module_class(ostream &out, Object *obj) { out << " Dtool_" << ClassName << "._PyType.tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n"; } else { - out << " Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)&Dtool_DTOOL_SUPER_BASE;\n"; + out << " Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)Dtool_GetSuperBase();\n"; } int num_nested = obj->_itype.number_of_nested_types(); diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index 986033fd3c..586889ed77 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -30,6 +30,9 @@ using std::cerr; using std::string; +// This contains a big source string determined at compile time. +extern const char interrogate_preamble_python_native[]; + Filename output_code_filename; string module_name; string library_name; @@ -635,8 +638,10 @@ int main(int argc, char *argv[]) { if (build_python_native_wrappers) { write_python_table_native(output_code); - } + // Output the support code. + output_code << interrogate_preamble_python_native << "\n"; + } } } diff --git a/dtool/src/interrogatedb/dtool_super_base.cxx b/dtool/src/interrogatedb/dtool_super_base.cxx index 9170af9d4f..01dcdef077 100644 --- a/dtool/src/interrogatedb/dtool_super_base.cxx +++ b/dtool/src/interrogatedb/dtool_super_base.cxx @@ -15,120 +15,132 @@ #ifdef HAVE_PYTHON -class EmptyClass { -}; -Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111); - static PyObject *GetSuperBase(PyObject *self) { - Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); // order is important .. this is used for static functions - return (PyObject *) &Dtool_DTOOL_SUPER_BASE; + Dtool_PyTypedObject *super_base = Dtool_GetSuperBase(); + Py_XINCREF((PyTypeObject *)super_base); // order is important .. this is used for static functions + return (PyObject *)super_base; }; -PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = { - { "DtoolGetSuperBase", (PyCFunction) &GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"}, - { nullptr, nullptr, 0, nullptr } -}; - -EXPCL_INTERROGATEDB void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) { - static bool initdone = false; - if (!initdone) { - - initdone = true; - Dtool_DTOOL_SUPER_BASE._PyType.tp_dict = PyDict_New(); - PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE._PyType.tp_dict); - - if (PyType_Ready((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE) < 0) { - PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)"); - return; - } - Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); - - PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], (PyObject *)&Dtool_DTOOL_SUPER_BASE)); - } - +static void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) { if (module != nullptr) { - Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); - PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE); + Dtool_PyTypedObject *super_base = Dtool_GetSuperBase(); + Py_INCREF((PyTypeObject *)&super_base); + PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&super_base); } } -inline void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) { +static void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) { return nullptr; } -inline void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) { +static void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) { return nullptr; } -int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) { +static int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) { assert(self != nullptr); PyErr_Format(PyExc_TypeError, "cannot init constant class %s", Py_TYPE(self)->tp_name); return -1; } -EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = { - { - PyVarObject_HEAD_INIT(nullptr, 0) - "dtoolconfig.DTOOL_SUPER_BASE", - sizeof(Dtool_PyInstDef), - 0, // tp_itemsize - &Dtool_FreeInstance_DTOOL_SUPER_BASE, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr +static void Dtool_FreeInstance_DTOOL_SUPER_BASE(PyObject *self) { + Py_TYPE(self)->tp_free(self); +} + +/** + * Returns a pointer to the DTOOL_SUPER_BASE class that is the base class of + * all Panda types. This pointer is shared by all modules. + */ +Dtool_PyTypedObject *Dtool_GetSuperBase() { + Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap(); + auto it = type_map->find("DTOOL_SUPER_BASE"); + if (it != type_map->end()) { + return it->second; + } + + static PyMethodDef methods[] = { + { "DtoolGetSuperBase", (PyCFunction)&GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"}, + { nullptr, nullptr, 0, nullptr } + }; + + static Dtool_PyTypedObject super_base_type = { + { + PyVarObject_HEAD_INIT(nullptr, 0) + "dtoolconfig.DTOOL_SUPER_BASE", + sizeof(Dtool_PyInstDef), + 0, // tp_itemsize + &Dtool_FreeInstance_DTOOL_SUPER_BASE, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr #if PY_MAJOR_VERSION >= 3 - nullptr, // tp_compare + nullptr, // tp_compare #else - &DtoolInstance_ComparePointers, + &DtoolInstance_ComparePointers, #endif - nullptr, // tp_repr - nullptr, // tp_as_number - nullptr, // tp_as_sequence - nullptr, // tp_as_mapping - &DtoolInstance_HashPointer, - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + &DtoolInstance_HashPointer, + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear #if PY_MAJOR_VERSION >= 3 - &DtoolInstance_RichComparePointers, + &DtoolInstance_RichComparePointers, #else - nullptr, // tp_richcompare + nullptr, // tp_richcompare #endif - 0, // tp_weaklistoffset - nullptr, // tp_iter - nullptr, // tp_iternext - Dtool_Methods_DTOOL_SUPER_BASE, - standard_type_members, - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - Dtool_Init_DTOOL_SUPER_BASE, - PyType_GenericAlloc, - Dtool_new_DTOOL_SUPER_BASE, - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del - }, - TypeHandle::none(), - Dtool_PyModuleClassInit_DTOOL_SUPER_BASE, - Dtool_UpcastInterface_DTOOL_SUPER_BASE, - Dtool_DowncastInterface_DTOOL_SUPER_BASE, - nullptr, - nullptr, -}; + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + methods, + standard_type_members, + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + Dtool_Init_DTOOL_SUPER_BASE, + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }, + TypeHandle::none(), + Dtool_PyModuleClassInit_DTOOL_SUPER_BASE, + Dtool_UpcastInterface_DTOOL_SUPER_BASE, + Dtool_DowncastInterface_DTOOL_SUPER_BASE, + nullptr, + nullptr, + }; + + super_base_type._PyType.tp_dict = PyDict_New(); + PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolClassDict", super_base_type._PyType.tp_dict); + + if (PyType_Ready((PyTypeObject *)&super_base_type) < 0) { + PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)"); + return nullptr; + } + Py_INCREF((PyTypeObject *)&super_base_type); + + PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&methods[0], (PyObject *)&super_base_type)); + + (*type_map)["DTOOL_SUPER_BASE"] = &super_base_type; + return &super_base_type; +} #endif // HAVE_PYTHON diff --git a/dtool/src/interrogatedb/p3interrogatedb_composite1.cxx b/dtool/src/interrogatedb/p3interrogatedb_composite1.cxx index d663e9e0e5..4e54cee5a9 100644 --- a/dtool/src/interrogatedb/p3interrogatedb_composite1.cxx +++ b/dtool/src/interrogatedb/p3interrogatedb_composite1.cxx @@ -1,5 +1,4 @@ #include "config_interrogatedb.cxx" -#include "dtool_super_base.cxx" #include "indexRemapper.cxx" #include "interrogateComponent.cxx" #include "interrogateDatabase.cxx" diff --git a/dtool/src/interrogatedb/p3interrogatedb_composite2.cxx b/dtool/src/interrogatedb/p3interrogatedb_composite2.cxx index fda72f2ce8..41453e5f3e 100644 --- a/dtool/src/interrogatedb/p3interrogatedb_composite2.cxx +++ b/dtool/src/interrogatedb/p3interrogatedb_composite2.cxx @@ -4,6 +4,3 @@ #include "interrogate_datafile.cxx" #include "interrogate_interface.cxx" #include "interrogate_request.cxx" -#include "py_panda.cxx" -#include "py_compat.cxx" -#include "py_wrappers.cxx" diff --git a/dtool/src/interrogatedb/py_compat.cxx b/dtool/src/interrogatedb/py_compat.cxx index 0c1383f983..722bc8300b 100644 --- a/dtool/src/interrogatedb/py_compat.cxx +++ b/dtool/src/interrogatedb/py_compat.cxx @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_compat.cxx * @author rdb * @date 2017-12-03 diff --git a/dtool/src/interrogatedb/py_compat.h b/dtool/src/interrogatedb/py_compat.h index f87c73cf3d..fbe49a5287 100644 --- a/dtool/src/interrogatedb/py_compat.h +++ b/dtool/src/interrogatedb/py_compat.h @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_compat.h * @author rdb * @date 2017-12-02 @@ -106,7 +99,7 @@ typedef int Py_ssize_t; // PyInt_FromSize_t automatically picks the right type. # define PyLongOrInt_AS_LONG PyInt_AsLong -EXPCL_INTERROGATEDB size_t PyLongOrInt_AsSize_t(PyObject *); +size_t PyLongOrInt_AsSize_t(PyObject *); #endif // Which character to use in PyArg_ParseTuple et al for a byte string. diff --git a/dtool/src/interrogatedb/py_panda.I b/dtool/src/interrogatedb/py_panda.I index f5f504ca97..12f20f1f1e 100644 --- a/dtool/src/interrogatedb/py_panda.I +++ b/dtool/src/interrogatedb/py_panda.I @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_panda.I * @author rdb * @date 2016-06-06 @@ -142,6 +135,18 @@ DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) { return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index()); } +/** + * Finishes initializing the Dtool_PyInstDef. + */ +INLINE int +DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) { + ((Dtool_PyInstDef *)self)->_My_Type = type; + ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this; + ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules; + ((Dtool_PyInstDef *)self)->_is_const = is_const; + return 0; +} + /** * Checks that the tuple is empty. */ diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 68264daf0b..bb7b5717f4 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_panda.cxx * @author drose * @date 2005-07-04 @@ -480,49 +473,22 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class return (PyObject *)self; } -// Th Finalizer for simple instances.. -int DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) { - // lets put some code in here that checks to see the memory is properly - // configured.. prior to my call .. - - ((Dtool_PyInstDef *)self)->_My_Type = type; - ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this; - ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules; - ((Dtool_PyInstDef *)self)->_is_const = is_const; - return 0; -} - -// A helper function to glue method definition together .. that can not be -// done at code generation time because of multiple generation passes in -// interrogate.. -void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) { - for (; in->ml_name != nullptr; in++) { - if (themap.find(in->ml_name) == themap.end()) { - themap[in->ml_name] = in; - } - } -} - /** * Returns a borrowed reference to the global type dictionary. */ Dtool_TypeMap *Dtool_GetGlobalTypeMap() { - PyObject *capsule = PySys_GetObject("_interrogate_types"); + PyObject *capsule = PySys_GetObject((char *)"_interrogate_types"); if (capsule != nullptr) { return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr); } else { Dtool_TypeMap *type_map = new Dtool_TypeMap; capsule = PyCapsule_New((void *)type_map, nullptr, nullptr); - PySys_SetObject("_interrogate_types", capsule); + PySys_SetObject((char *)"_interrogate_types", capsule); Py_DECREF(capsule); return type_map; } } -Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) { - return (Dtool_PyTypedObject *)TypeHandle::from_index(type).get_python_type(); -} - #if PY_MAJOR_VERSION >= 3 PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) { #else @@ -544,58 +510,19 @@ PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulen return nullptr; } - // Initialize the types we define in py_panda. - static bool dtool_inited = false; - if (!dtool_inited) { - dtool_inited = true; - - if (PyType_Ready(&Dtool_SequenceWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_SequenceWrapper)"); - } - - if (PyType_Ready(&Dtool_MutableSequenceWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableSequenceWrapper)"); - } - - if (PyType_Ready(&Dtool_MappingWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper)"); - } - - if (PyType_Ready(&Dtool_MutableMappingWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableMappingWrapper)"); - } - - if (PyType_Ready(&Dtool_MappingWrapper_Keys_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Keys)"); - } - - if (PyType_Ready(&Dtool_MappingWrapper_Values_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Values)"); - } - - if (PyType_Ready(&Dtool_MappingWrapper_Items_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Items)"); - } - - if (PyType_Ready(&Dtool_GeneratorWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_GeneratorWrapper)"); - } - - if (PyType_Ready(&Dtool_StaticProperty_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)"); - } - - // Initialize the base class of everything. - Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(nullptr); - } - Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap(); // the module level function inits.... MethodDefmap functions; for (size_t i = 0; defs[i] != nullptr; i++) { const LibraryDef &def = *defs[i]; - Dtool_Accum_MethDefs(def._methods, functions); + + // Accumulate method definitions. + for (PyMethodDef *meth = def._methods; meth->ml_name != nullptr; meth++) { + if (functions.find(meth->ml_name) == functions.end()) { + functions[meth->ml_name] = meth; + } + } // Define exported types. const Dtool_TypeDef *types = def._types; @@ -746,7 +673,7 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) { // We do expose a dictionay for dtool classes .. this should be removed at // some point.. -EXPCL_INTERROGATEDB PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) { +PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) { PyObject *self; PyObject *subject; PyObject *key; diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index f850f0c859..34693e8b90 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_panda.h */ @@ -43,9 +36,6 @@ using namespace std; #endif struct Dtool_PyTypedObject; -typedef std::map RuntimeTypeMap; -typedef std::set RuntimeTypeSet; -typedef std::map NamedTypeMap; // used to stamp dtool instance.. #define PY_PANDA_SIGNATURE 0xbeaf @@ -78,7 +68,7 @@ struct Dtool_PyInstDef { }; // A Offset Dictionary Defining How to read the Above Object.. -extern EXPCL_INTERROGATEDB PyMemberDef standard_type_members[]; +extern PyMemberDef standard_type_members[]; // The Class Definition Structor For a Dtool python type. struct Dtool_PyTypedObject { @@ -192,21 +182,19 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ typedef std::map Dtool_TypeMap; -EXPCL_INTERROGATEDB Dtool_TypeMap *Dtool_GetGlobalTypeMap(); - -EXPCL_INTERROGATEDB Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type); +Dtool_TypeMap *Dtool_GetGlobalTypeMap(); /** */ -EXPCL_INTERROGATEDB void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer); +void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer); -EXPCL_INTERROGATEDB void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors); +void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors); -EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer); +bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer); -EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef, - void **answer, const char *method_name); +bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef, + void **answer, const char *method_name); template INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into); template INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &classdef); @@ -216,7 +204,7 @@ INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2); INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op); // Functions related to error reporting. -EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred(); +bool _Dtool_CheckErrorOccurred(); #ifdef NDEBUG #define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != nullptr)) @@ -224,12 +212,12 @@ EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred(); #define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred())) #endif -EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AssertionError(); -EXPCL_INTERROGATEDB PyObject *Dtool_Raise_TypeError(const char *message); -EXPCL_INTERROGATEDB PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name); -EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute); +PyObject *Dtool_Raise_AssertionError(); +PyObject *Dtool_Raise_TypeError(const char *message); +PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name); +PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute); -EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError(); +PyObject *_Dtool_Raise_BadArgumentsError(); #ifdef NDEBUG // Define it to a function that just prints a generic message. #define Dtool_Raise_BadArgumentsError(x) _Dtool_Raise_BadArgumentsError() @@ -241,9 +229,9 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError(); // These functions are similar to Dtool_WrapValue, except that they also // contain code for checking assertions and exceptions when compiling with // NDEBUG mode on. -EXPCL_INTERROGATEDB PyObject *_Dtool_Return_None(); -EXPCL_INTERROGATEDB PyObject *Dtool_Return_Bool(bool value); -EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value); +PyObject *_Dtool_Return_None(); +PyObject *Dtool_Return_Bool(bool value); +PyObject *_Dtool_Return(PyObject *value); #ifdef NDEBUG #define Dtool_Return_None() (LIKELY(_PyErr_OCCURRED() == nullptr) ? (Py_INCREF(Py_None), Py_None) : nullptr) @@ -256,19 +244,19 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value); /** * Wrapper around Python 3.4's enum library, which does not have a C API. */ -EXPCL_INTERROGATEDB PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, +PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module = nullptr); -EXPCL_INTERROGATEDB INLINE long Dtool_EnumValue_AsLong(PyObject *value); +INLINE long Dtool_EnumValue_AsLong(PyObject *value); /** */ -EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType); +PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType); // DTool_CreatePyInstance .. wrapper function to finalize the existance of a // general dtool py instance.. -EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const); +PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const); // These template methods allow use when the Dtool_PyTypedObject is not known. // They require a get_class_type() to be defined for the class. @@ -312,15 +300,13 @@ Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\ Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) // The finalizer for simple instances. -EXPCL_INTERROGATEDB int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const); +INLINE int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const); // A heler function to glu methed definition together .. that can not be done // at code generation time becouse of multiple generation passes in // interigate.. typedef std::map MethodDefmap; -EXPCL_INTERROGATEDB void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap); - // We need a way to runtime merge compile units into a python "Module" .. this // is done with the fallowing structors and code.. along with the support of // interigate_module @@ -337,26 +323,26 @@ struct LibraryDef { }; #if PY_MAJOR_VERSION >= 3 -EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def); +PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def); #else -EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename); +PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename); #endif // HACK.... Be carefull Dtool_BorrowThisReference This function can be used to // grab the "THIS" pointer from an object and use it Required to support fom // historical inharatence in the for of "is this instance of".. -EXPCL_INTERROGATEDB PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args); +PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args); #define DTOOL_PyObject_HashPointer DtoolInstance_HashPointer #define DTOOL_PyObject_ComparePointers DtoolInstance_ComparePointers -EXPCL_INTERROGATEDB PyObject * +PyObject * copy_from_make_copy(PyObject *self, PyObject *noargs); -EXPCL_INTERROGATEDB PyObject * +PyObject * copy_from_copy_constructor(PyObject *self, PyObject *noargs); -EXPCL_INTERROGATEDB PyObject * +PyObject * map_deepcopy_to_copy(PyObject *self, PyObject *args); /** @@ -365,13 +351,13 @@ map_deepcopy_to_copy(PyObject *self, PyObject *args); */ ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args); ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args, PyObject *kwds); -EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args, +bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds, const char *keyword); -EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args, +bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds); -EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, +bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds, const char *keyword); -EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, +bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds); /** @@ -407,10 +393,7 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value); template ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::pair &value); -EXPCL_INTERROGATEDB extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE; -EXPCL_INTERROGATEDB extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module); - -#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE) +Dtool_PyTypedObject *Dtool_GetSuperBase(); #include "py_panda.I" diff --git a/dtool/src/interrogatedb/py_wrappers.cxx b/dtool/src/interrogatedb/py_wrappers.cxx index 71a5a38ffd..0b8a751cad 100644 --- a/dtool/src/interrogatedb/py_wrappers.cxx +++ b/dtool/src/interrogatedb/py_wrappers.cxx @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_wrappers.cxx * @author rdb * @date 2017-11-26 @@ -494,6 +487,24 @@ static PyObject *Dtool_MappingWrapper_get(PyObject *self, PyObject *args) { } } +/** + * This is returned by mapping.keys(). + */ +static PyObject *Dtool_MappingWrapper_Keys_repr(PyObject *self) { + Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; + nassertr(wrap, nullptr); + + PyObject *repr = PyObject_Repr(wrap->_self); + PyObject *result; +#if PY_MAJOR_VERSION >= 3 + result = PyUnicode_FromFormat("<%s.keys() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); +#else + result = PyString_FromFormat("<%s.keys() of %s>", wrap->_name, PyString_AS_STRING(repr)); +#endif + Py_DECREF(repr); + return result; +} + /** * Implementation of property.keys(...) that returns a view of all the keys. */ @@ -510,14 +521,81 @@ static PyObject *Dtool_MappingWrapper_keys(PyObject *self, PyObject *) { return PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_SequenceWrapper_getitem, + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_SequenceWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_SequenceWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_MappingWrapper_Keys_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MappingWrapper_Keys_Type, "MappingView"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "MappingView"); } - (void)PyObject_INIT(keys, &Dtool_MappingWrapper_Keys_Type); + (void)PyObject_INIT(keys, &wrapper_type); Py_XINCREF(wrap->_base._self); keys->_base._self = wrap->_base._self; keys->_base._name = wrap->_base._name; @@ -528,6 +606,38 @@ static PyObject *Dtool_MappingWrapper_keys(PyObject *self, PyObject *) { return (PyObject *)keys; } +/** + * This is returned by mapping.values(). + */ +static PyObject *Dtool_MappingWrapper_Values_repr(PyObject *self) { + Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; + nassertr(wrap, nullptr); + + PyObject *repr = PyObject_Repr(wrap->_self); + PyObject *result; +#if PY_MAJOR_VERSION >= 3 + result = PyUnicode_FromFormat("<%s.values() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); +#else + result = PyString_FromFormat("<%s.values() of %s>", wrap->_name, PyString_AS_STRING(repr)); +#endif + Py_DECREF(repr); + return result; +} + +static PyObject *Dtool_MappingWrapper_Values_getitem(PyObject *self, Py_ssize_t index) { + Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self; + nassertr(wrap, nullptr); + nassertr(wrap->_keys._getitem_func, nullptr); + + PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index); + if (key != nullptr) { + PyObject *value = wrap->_getitem_func(wrap->_base._self, key); + Py_DECREF(key); + return value; + } + return nullptr; +} + /** * Implementation of property.values(...) that returns a view of the values. */ @@ -545,14 +655,81 @@ static PyObject *Dtool_MappingWrapper_values(PyObject *self, PyObject *) { return PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_MappingWrapper_Values_getitem, + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_MappingWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_MappingWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_MappingWrapper_Values_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MappingWrapper_Values_Type, "ValuesView"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "ValuesView"); } - (void)PyObject_INIT(values, &Dtool_MappingWrapper_Values_Type); + (void)PyObject_INIT(values, &wrapper_type); Py_XINCREF(wrap->_base._self); values->_base._self = wrap->_base._self; values->_base._name = wrap->_base._name; @@ -563,6 +740,45 @@ static PyObject *Dtool_MappingWrapper_values(PyObject *self, PyObject *) { return (PyObject *)values; } +/** + * This is returned by mapping.items(). + */ +static PyObject *Dtool_MappingWrapper_Items_repr(PyObject *self) { + Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; + nassertr(wrap, nullptr); + + PyObject *repr = PyObject_Repr(wrap->_self); + PyObject *result; +#if PY_MAJOR_VERSION >= 3 + result = PyUnicode_FromFormat("<%s.items() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); +#else + result = PyString_FromFormat("<%s.items() of %s>", wrap->_name, PyString_AS_STRING(repr)); +#endif + Py_DECREF(repr); + return result; +} + +static PyObject *Dtool_MappingWrapper_Items_getitem(PyObject *self, Py_ssize_t index) { + Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self; + nassertr(wrap, nullptr); + nassertr(wrap->_keys._getitem_func, nullptr); + + PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index); + if (key != nullptr) { + PyObject *value = wrap->_getitem_func(wrap->_base._self, key); + if (value != nullptr) { + // PyTuple_SET_ITEM steals the reference. + PyObject *item = PyTuple_New(2); + PyTuple_SET_ITEM(item, 0, key); + PyTuple_SET_ITEM(item, 1, value); + return item; + } else { + Py_DECREF(key); + } + } + return nullptr; +} + /** * Implementation of property.items(...) that returns an iterable yielding a * `(key, value)` tuple for every item. @@ -581,14 +797,81 @@ static PyObject *Dtool_MappingWrapper_items(PyObject *self, PyObject *) { return PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_MappingWrapper_Items_getitem, + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_MappingWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_MappingWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_MappingWrapper_Items_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MappingWrapper_Items_Type, "MappingView"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "MappingView"); } - (void)PyObject_INIT(items, &Dtool_MappingWrapper_Items_Type); + (void)PyObject_INIT(items, &wrapper_type); Py_XINCREF(wrap->_base._self); items->_base._self = wrap->_base._self; items->_base._name = wrap->_base._name; @@ -792,566 +1075,6 @@ static PyObject *Dtool_MutableMappingWrapper_update(PyObject *self, PyObject *ar return Py_None; } -/** - * This variant defines only a sequence interface. - */ -static PySequenceMethods Dtool_SequenceWrapper_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - Dtool_SequenceWrapper_getitem, - nullptr, // sq_slice - nullptr, // sq_ass_item - nullptr, // sq_ass_slice - Dtool_SequenceWrapper_contains, - nullptr, // sq_inplace_concat - nullptr, // sq_inplace_repeat -}; - -static PyMethodDef Dtool_SequenceWrapper_Methods[] = { - {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr}, - {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr}, - {nullptr, nullptr, 0, nullptr} -}; - -PyTypeObject Dtool_SequenceWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_SequenceWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_SequenceWrapper_repr, - nullptr, // tp_as_number - &Dtool_SequenceWrapper_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - Dtool_SequenceWrapper_Methods, - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This is a variant on SequenceWrapper that also has an insert() method. - */ -static PySequenceMethods Dtool_MutableSequenceWrapper_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - Dtool_SequenceWrapper_getitem, - nullptr, // sq_slice - Dtool_MutableSequenceWrapper_setitem, - nullptr, // sq_ass_slice - Dtool_SequenceWrapper_contains, - Dtool_MutableSequenceWrapper_extend, - nullptr, // sq_inplace_repeat -}; - -static PyMethodDef Dtool_MutableSequenceWrapper_Methods[] = { - {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr}, - {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr}, - {"clear", &Dtool_MutableSequenceWrapper_clear, METH_NOARGS, nullptr}, - {"pop", &Dtool_MutableSequenceWrapper_pop, METH_VARARGS, nullptr}, - {"remove", &Dtool_MutableSequenceWrapper_remove, METH_O, nullptr}, - {"append", &Dtool_MutableSequenceWrapper_append, METH_O, nullptr}, - {"insert", &Dtool_MutableSequenceWrapper_insert, METH_VARARGS, nullptr}, - {"extend", &Dtool_MutableSequenceWrapper_extend, METH_O, nullptr}, - {nullptr, nullptr, 0, nullptr} -}; - -PyTypeObject Dtool_MutableSequenceWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_MutableSequenceWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_SequenceWrapper_repr, - nullptr, // tp_as_number - &Dtool_MutableSequenceWrapper_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - Dtool_MutableSequenceWrapper_Methods, - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This variant defines only a mapping interface. - */ -static PySequenceMethods Dtool_MappingWrapper_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - nullptr, // sq_item - nullptr, // sq_slice - nullptr, // sq_ass_item - nullptr, // sq_ass_slice - Dtool_MappingWrapper_contains, - nullptr, // sq_inplace_concat - nullptr, // sq_inplace_repeat -}; - -static PyMappingMethods Dtool_MappingWrapper_MappingMethods = { - Dtool_SequenceWrapper_length, - Dtool_MappingWrapper_getitem, - nullptr, // mp_ass_subscript -}; - -static PyMethodDef Dtool_MappingWrapper_Methods[] = { - {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr}, - {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr}, - {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr}, - {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr}, - {nullptr, nullptr, 0, nullptr} -}; - -PyTypeObject Dtool_MappingWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "mapping wrapper", - sizeof(Dtool_MappingWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_WrapperBase_repr, - nullptr, // tp_as_number - &Dtool_MappingWrapper_SequenceMethods, - &Dtool_MappingWrapper_MappingMethods, - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - Dtool_MappingWrapper_iter, - nullptr, // tp_iternext - Dtool_MappingWrapper_Methods, - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This variant defines only a mutable mapping interface. - */ -static PyMappingMethods Dtool_MutableMappingWrapper_MappingMethods = { - Dtool_SequenceWrapper_length, - Dtool_MappingWrapper_getitem, - Dtool_MutableMappingWrapper_setitem, -}; - -static PyMethodDef Dtool_MutableMappingWrapper_Methods[] = { - {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr}, - {"pop", &Dtool_MutableMappingWrapper_pop, METH_VARARGS, nullptr}, - {"popitem", &Dtool_MutableMappingWrapper_popitem, METH_NOARGS, nullptr}, - {"clear", &Dtool_MutableMappingWrapper_clear, METH_VARARGS, nullptr}, - {"setdefault", &Dtool_MutableMappingWrapper_setdefault, METH_VARARGS, nullptr}, - {"update", (PyCFunction) &Dtool_MutableMappingWrapper_update, METH_VARARGS | METH_KEYWORDS, nullptr}, - {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr}, - {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr}, - {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr}, - {nullptr, nullptr, 0, nullptr} -}; - -PyTypeObject Dtool_MutableMappingWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "mapping wrapper", - sizeof(Dtool_MappingWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_WrapperBase_repr, - nullptr, // tp_as_number - &Dtool_MappingWrapper_SequenceMethods, - &Dtool_MutableMappingWrapper_MappingMethods, - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - Dtool_MappingWrapper_iter, - nullptr, // tp_iternext - Dtool_MutableMappingWrapper_Methods, - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This is returned by mapping.items(). - */ -static PyObject *Dtool_MappingWrapper_Items_repr(PyObject *self) { - Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; - nassertr(wrap, nullptr); - - PyObject *repr = PyObject_Repr(wrap->_self); - PyObject *result; -#if PY_MAJOR_VERSION >= 3 - result = PyUnicode_FromFormat("<%s.items() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); -#else - result = PyString_FromFormat("<%s.items() of %s>", wrap->_name, PyString_AS_STRING(repr)); -#endif - Py_DECREF(repr); - return result; -} - -static PyObject *Dtool_MappingWrapper_Items_getitem(PyObject *self, Py_ssize_t index) { - Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self; - nassertr(wrap, nullptr); - nassertr(wrap->_keys._getitem_func, nullptr); - - PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index); - if (key != nullptr) { - PyObject *value = wrap->_getitem_func(wrap->_base._self, key); - if (value != nullptr) { - // PyTuple_SET_ITEM steals the reference. - PyObject *item = PyTuple_New(2); - PyTuple_SET_ITEM(item, 0, key); - PyTuple_SET_ITEM(item, 1, value); - return item; - } else { - Py_DECREF(key); - } - } - return nullptr; -} - -static PySequenceMethods Dtool_MappingWrapper_Items_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - Dtool_MappingWrapper_Items_getitem, - nullptr, // sq_slice - nullptr, // sq_ass_item - nullptr, // sq_ass_slice - Dtool_MappingWrapper_contains, - nullptr, // sq_inplace_concat - nullptr, // sq_inplace_repeat -}; - -PyTypeObject Dtool_MappingWrapper_Items_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_MappingWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_MappingWrapper_Items_repr, - nullptr, // tp_as_number - &Dtool_MappingWrapper_Items_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This is returned by mapping.keys(). - */ -static PyObject *Dtool_MappingWrapper_Keys_repr(PyObject *self) { - Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; - nassertr(wrap, nullptr); - - PyObject *repr = PyObject_Repr(wrap->_self); - PyObject *result; -#if PY_MAJOR_VERSION >= 3 - result = PyUnicode_FromFormat("<%s.keys() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); -#else - result = PyString_FromFormat("<%s.keys() of %s>", wrap->_name, PyString_AS_STRING(repr)); -#endif - Py_DECREF(repr); - return result; -} - -PyTypeObject Dtool_MappingWrapper_Keys_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_SequenceWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_MappingWrapper_Keys_repr, - nullptr, // tp_as_number - &Dtool_SequenceWrapper_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This is returned by mapping.values(). - */ -static PyObject *Dtool_MappingWrapper_Values_repr(PyObject *self) { - Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; - nassertr(wrap, nullptr); - - PyObject *repr = PyObject_Repr(wrap->_self); - PyObject *result; -#if PY_MAJOR_VERSION >= 3 - result = PyUnicode_FromFormat("<%s.values() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); -#else - result = PyString_FromFormat("<%s.values() of %s>", wrap->_name, PyString_AS_STRING(repr)); -#endif - Py_DECREF(repr); - return result; -} - -static PyObject *Dtool_MappingWrapper_Values_getitem(PyObject *self, Py_ssize_t index) { - Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self; - nassertr(wrap, nullptr); - nassertr(wrap->_keys._getitem_func, nullptr); - - PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index); - if (key != nullptr) { - PyObject *value = wrap->_getitem_func(wrap->_base._self, key); - Py_DECREF(key); - return value; - } - return nullptr; -} - -static PySequenceMethods Dtool_MappingWrapper_Values_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - Dtool_MappingWrapper_Values_getitem, - nullptr, // sq_slice - nullptr, // sq_ass_item - nullptr, // sq_ass_slice - Dtool_MappingWrapper_contains, - nullptr, // sq_inplace_concat - nullptr, // sq_inplace_repeat -}; - -PyTypeObject Dtool_MappingWrapper_Values_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_MappingWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_MappingWrapper_Values_repr, - nullptr, // tp_as_number - &Dtool_MappingWrapper_Values_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - /** * This variant defines only a generator interface. */ @@ -1362,55 +1085,6 @@ static PyObject *Dtool_GeneratorWrapper_iternext(PyObject *self) { return wrap->_iternext_func(wrap->_base._self); } -PyTypeObject Dtool_GeneratorWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "generator wrapper", - sizeof(Dtool_GeneratorWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - nullptr, // tp_repr - nullptr, // tp_as_number - nullptr, // tp_as_sequence - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PyObject_SelfIter, - Dtool_GeneratorWrapper_iternext, - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - /** * This is a variant of the Python getset mechanism that permits static * properties. @@ -1479,55 +1153,6 @@ Dtool_StaticProperty_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *va } } -PyTypeObject Dtool_StaticProperty_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "getset_descriptor", - sizeof(PyGetSetDescrObject), - 0, // tp_itemsize - (destructor)Dtool_StaticProperty_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_reserved - (reprfunc)Dtool_StaticProperty_repr, - nullptr, // tp_as_number - nullptr, // tp_as_sequence - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - nullptr, // tp_setattro - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT, - nullptr, // tp_doc - Dtool_StaticProperty_traverse, - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - nullptr, // tp_iter - nullptr, // tp_iternext - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - (descrgetfunc)Dtool_StaticProperty_get, - (descrsetfunc)Dtool_StaticProperty_set, - 0, // tp_dictoffset - nullptr, // tp_init - nullptr, // tp_alloc - nullptr, // tp_new - nullptr, // tp_del - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - /** * This wraps around a property that exposes a sequence interface. */ @@ -1537,14 +1162,87 @@ Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name return (Dtool_SequenceWrapper *)PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_SequenceWrapper_getitem, + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_SequenceWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyMethodDef methods[] = { + {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr}, + {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr}, + {nullptr, nullptr, 0, nullptr} + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_SequenceWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_SequenceWrapper_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + methods, + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MutableSequenceWrapper_Type, "Sequence"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "Sequence"); } - (void)PyObject_INIT(wrap, &Dtool_SequenceWrapper_Type); + (void)PyObject_INIT(wrap, &wrapper_type); Py_XINCREF(self); wrap->_base._self = self; wrap->_base._name = name; @@ -1562,14 +1260,93 @@ Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, co return (Dtool_MutableSequenceWrapper *)PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_SequenceWrapper_getitem, + nullptr, // sq_slice + Dtool_MutableSequenceWrapper_setitem, + nullptr, // sq_ass_slice + Dtool_SequenceWrapper_contains, + Dtool_MutableSequenceWrapper_extend, + nullptr, // sq_inplace_repeat + }; + + static PyMethodDef methods[] = { + {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr}, + {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr}, + {"clear", &Dtool_MutableSequenceWrapper_clear, METH_NOARGS, nullptr}, + {"pop", &Dtool_MutableSequenceWrapper_pop, METH_VARARGS, nullptr}, + {"remove", &Dtool_MutableSequenceWrapper_remove, METH_O, nullptr}, + {"append", &Dtool_MutableSequenceWrapper_append, METH_O, nullptr}, + {"insert", &Dtool_MutableSequenceWrapper_insert, METH_VARARGS, nullptr}, + {"extend", &Dtool_MutableSequenceWrapper_extend, METH_O, nullptr}, + {nullptr, nullptr, 0, nullptr} + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_MutableSequenceWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_SequenceWrapper_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + methods, + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MutableSequenceWrapper_Type, "MutableSequence"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "MutableSequence"); } - (void)PyObject_INIT(wrap, &Dtool_MutableSequenceWrapper_Type); + (void)PyObject_INIT(wrap, &wrapper_type); Py_XINCREF(self); wrap->_base._self = self; wrap->_base._name = name; @@ -1589,14 +1366,95 @@ Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name) return (Dtool_MappingWrapper *)PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + nullptr, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_MappingWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyMappingMethods map_methods = { + Dtool_SequenceWrapper_length, + Dtool_MappingWrapper_getitem, + nullptr, // mp_ass_subscript + }; + + static PyMethodDef methods[] = { + {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr}, + {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr}, + {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr}, + {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr}, + {nullptr, nullptr, 0, nullptr} + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "mapping wrapper", + sizeof(Dtool_MappingWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_WrapperBase_repr, + nullptr, // tp_as_number + &seq_methods, + &map_methods, + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + Dtool_MappingWrapper_iter, + nullptr, // tp_iternext + methods, + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MappingWrapper_Type, "Mapping"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "Mapping"); } - (void)PyObject_INIT(wrap, &Dtool_MappingWrapper_Type); + (void)PyObject_INIT(wrap, &wrapper_type); Py_XINCREF(self); wrap->_base._self = self; wrap->_base._name = name; @@ -1616,14 +1474,100 @@ Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char return (Dtool_MappingWrapper *)PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + nullptr, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_MappingWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyMappingMethods map_methods = { + Dtool_SequenceWrapper_length, + Dtool_MappingWrapper_getitem, + Dtool_MutableMappingWrapper_setitem, + }; + + static PyMethodDef methods[] = { + {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr}, + {"pop", &Dtool_MutableMappingWrapper_pop, METH_VARARGS, nullptr}, + {"popitem", &Dtool_MutableMappingWrapper_popitem, METH_NOARGS, nullptr}, + {"clear", &Dtool_MutableMappingWrapper_clear, METH_VARARGS, nullptr}, + {"setdefault", &Dtool_MutableMappingWrapper_setdefault, METH_VARARGS, nullptr}, + {"update", (PyCFunction) &Dtool_MutableMappingWrapper_update, METH_VARARGS | METH_KEYWORDS, nullptr}, + {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr}, + {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr}, + {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr}, + {nullptr, nullptr, 0, nullptr} + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "mapping wrapper", + sizeof(Dtool_MappingWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_WrapperBase_repr, + nullptr, // tp_as_number + &seq_methods, + &map_methods, + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + Dtool_MappingWrapper_iter, + nullptr, // tp_iternext + methods, + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MutableMappingWrapper_Type, "MutableMapping"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "MutableMapping"); } - (void)PyObject_INIT(wrap, &Dtool_MutableMappingWrapper_Type); + (void)PyObject_INIT(wrap, &wrapper_type); Py_XINCREF(self); wrap->_base._self = self; wrap->_base._name = name; @@ -1634,14 +1578,135 @@ Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char return wrap; } +/** + * Creates a generator that invokes a given function with the given self arg. + */ +PyObject * +Dtool_NewGenerator(PyObject *self, iternextfunc gen_next) { + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "generator wrapper", + sizeof(Dtool_GeneratorWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PyObject_SelfIter, + Dtool_GeneratorWrapper_iternext, + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + Dtool_GeneratorWrapper *gen; + gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&wrapper_type, 0); + if (gen != nullptr) { + Py_INCREF(self); + gen->_base._self = self; + gen->_iternext_func = gen_next; + } + return (PyObject *)gen; +} + /** * This is a variant of the Python getset mechanism that permits static * properties. */ PyObject * Dtool_NewStaticProperty(PyTypeObject *type, const PyGetSetDef *getset) { + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "getset_descriptor", + sizeof(PyGetSetDescrObject), + 0, // tp_itemsize + (destructor)Dtool_StaticProperty_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_reserved + (reprfunc)Dtool_StaticProperty_repr, + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, + nullptr, // tp_doc + Dtool_StaticProperty_traverse, + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + (descrgetfunc)Dtool_StaticProperty_get, + (descrsetfunc)Dtool_StaticProperty_set, + 0, // tp_dictoffset + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new + nullptr, // tp_del + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + PyGetSetDescrObject *descr; - descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&Dtool_StaticProperty_Type, 0); + descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&wrapper_type, 0); if (descr != nullptr) { Py_XINCREF(type); descr->d_getset = (PyGetSetDef *)getset; diff --git a/dtool/src/interrogatedb/py_wrappers.h b/dtool/src/interrogatedb/py_wrappers.h index 7bf2c2e19f..96375d3598 100644 --- a/dtool/src/interrogatedb/py_wrappers.h +++ b/dtool/src/interrogatedb/py_wrappers.h @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_wrappers.h * @author rdb * @date 2017-11-26 @@ -56,22 +49,12 @@ struct Dtool_GeneratorWrapper { iternextfunc _iternext_func; }; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_SequenceWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableSequenceWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableMappingWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Items_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Keys_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Values_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_GeneratorWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_StaticProperty_Type; - -EXPCL_INTERROGATEDB Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name); -EXPCL_INTERROGATEDB Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name); -EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name); -EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name); -EXPCL_INTERROGATEDB PyObject *Dtool_NewGenerator(PyObject *self, const char *name, iternextfunc func); -EXPCL_INTERROGATEDB PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset); +Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name); +Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name); +Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name); +Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name); +PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func); +PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset); #endif // HAVE_PYTHON diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 96effc4c43..eae006b2ec 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3442,14 +3442,13 @@ TargetAdd('libp3dtoolconfig.dll', opts=['ADVAPI', 'OPENSSL', 'WINGDI', 'WINUSER' # DIRECTORY: dtool/src/interrogatedb/ # -OPTS=['DIR:dtool/src/interrogatedb', 'BUILDING:INTERROGATEDB', 'PYTHON'] +OPTS=['DIR:dtool/src/interrogatedb', 'BUILDING:INTERROGATEDB'] TargetAdd('p3interrogatedb_composite1.obj', opts=OPTS, input='p3interrogatedb_composite1.cxx') TargetAdd('p3interrogatedb_composite2.obj', opts=OPTS, input='p3interrogatedb_composite2.cxx') TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite1.obj') TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite2.obj') TargetAdd('libp3interrogatedb.dll', input='libp3dtool.dll') TargetAdd('libp3interrogatedb.dll', input='libp3dtoolconfig.dll') -TargetAdd('libp3interrogatedb.dll', opts=['PYTHON']) if not PkgSkip("PYTHON"): # This used to be called dtoolconfig.pyd, but it just contains the interrogatedb @@ -3489,8 +3488,16 @@ if (not RUNTIME): TargetAdd('interrogate.exe', input='libp3pystub.lib') TargetAdd('interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) + preamble = WriteEmbeddedStringFile('interrogate_preamble_python_native', inputs=[ + 'dtool/src/interrogatedb/py_panda.cxx', + 'dtool/src/interrogatedb/py_compat.cxx', + 'dtool/src/interrogatedb/py_wrappers.cxx', + 'dtool/src/interrogatedb/dtool_super_base.cxx', + ]) + TargetAdd('interrogate_module_preamble_python_native.obj', opts=OPTS, input=preamble) TargetAdd('interrogate_module_interrogate_module.obj', opts=OPTS, input='interrogate_module.cxx') TargetAdd('interrogate_module.exe', input='interrogate_module_interrogate_module.obj') + TargetAdd('interrogate_module.exe', input='interrogate_module_preamble_python_native.obj') TargetAdd('interrogate_module.exe', input='libp3cppParser.ilb') TargetAdd('interrogate_module.exe', input=COMMON_DTOOL_LIBS) TargetAdd('interrogate_module.exe', input='libp3interrogatedb.dll') diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 76dec39406..cf89b85e59 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -3190,6 +3190,48 @@ def WriteResourceFile(basename, **kwargs): ConditionalWriteFile(basename, GenerateResourceFile(**kwargs)) return basename + +def WriteEmbeddedStringFile(basename, inputs, string_name=None): + if os.path.splitext(basename)[1] not in SUFFIX_INC: + basename += '.cxx' + target = GetOutputDir() + "/tmp/" + basename + + if string_name is None: + string_name = os.path.basename(os.path.splitext(target)[0]) + string_name = string_name.replace('-', '_') + + data = bytearray() + for input in inputs: + fp = open(input, 'rb') + + # Insert a #line so that we get meaningful compile/assert errors when + # the result is inserted by interrogate_module into generated code. + if os.path.splitext(input)[1] in SUFFIX_INC: + line = '#line 1 "%s"\n' % (input) + data += bytearray(line.encode('ascii', 'replace')) + + data += bytearray(fp.read()) + fp.close() + + data.append(0) + + output = 'extern const char %s[] = {\n' % (string_name) + + i = 0 + for byte in data: + if i == 0: + output += ' ' + + output += ' 0x%02x,' % (byte) + i += 1 + if i >= 12: + output += '\n' + i = 0 + + output += '\n};\n' + ConditionalWriteFile(target, output) + return target + ######################################################################## ## ## FindLocation diff --git a/panda/src/event/asyncFuture_ext.cxx b/panda/src/event/asyncFuture_ext.cxx index 00ee3516b1..5bf7cb3c94 100644 --- a/panda/src/event/asyncFuture_ext.cxx +++ b/panda/src/event/asyncFuture_ext.cxx @@ -168,14 +168,7 @@ static PyObject *gen_next(PyObject *self) { */ PyObject *Extension:: __await__(PyObject *self) { - Dtool_GeneratorWrapper *gen; - gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&Dtool_GeneratorWrapper_Type, 0); - if (gen != nullptr) { - Py_INCREF(self); - gen->_base._self = self; - gen->_iternext_func = &gen_next; - } - return (PyObject *)gen; + return Dtool_NewGenerator(self, &gen_next); } /**