diff --git a/dtool/Config.cmake b/dtool/Config.cmake index 912f9d4bbb..dff731ccd1 100644 --- a/dtool/Config.cmake +++ b/dtool/Config.cmake @@ -265,7 +265,7 @@ if(BUILD_INTERROGATE) panda3d-interrogate GIT_REPOSITORY https://github.com/panda3d/interrogate.git - GIT_TAG 4a9b7d2d9e40edf6bfb3177521b5481130291bda + GIT_TAG c19b93c00bd31ecdde861f6511e7830d9f69ac91 PREFIX ${_interrogate_dir} CMAKE_ARGS diff --git a/dtool/src/interrogatedb/CMakeLists.txt b/dtool/src/interrogatedb/CMakeLists.txt index f137a7b802..0457184feb 100644 --- a/dtool/src/interrogatedb/CMakeLists.txt +++ b/dtool/src/interrogatedb/CMakeLists.txt @@ -2,7 +2,6 @@ set(P3IGATERUNTIME_HEADERS interrogate_request.h py_compat.h py_panda.h py_panda.I - py_wrappers.h ) install(FILES ${P3IGATERUNTIME_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d) diff --git a/dtool/src/interrogatedb/py_panda.I b/dtool/src/interrogatedb/py_panda.I index f3cb5a1d12..edfd0690f8 100644 --- a/dtool/src/interrogatedb/py_panda.I +++ b/dtool/src/interrogatedb/py_panda.I @@ -59,63 +59,6 @@ DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &target_c return false; } -/** - * Function to create a hash from a wrapped Python object. - */ -INLINE Py_hash_t DtoolInstance_HashPointer(PyObject *self) { - if (self != nullptr && DtoolInstance_Check(self)) { - return (Py_hash_t)(intptr_t)DtoolInstance_VOID_PTR(self); - } - return -1; -} - -/** - * Python 2-style comparison function that compares objects by pointer. - */ -INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2) { - void *v1_this = DtoolInstance_Check(v1) ? DtoolInstance_VOID_PTR(v1) : nullptr; - void *v2_this = DtoolInstance_Check(v2) ? DtoolInstance_VOID_PTR(v2) : nullptr; - if (v1_this != nullptr && v2_this != nullptr) { - return (v1_this > v2_this) - (v1_this < v2_this); - } else { - return (v1 > v2) - (v1 < v2); - } -} - -/** - * Rich comparison function that compares objects by pointer. - */ -INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op) { - int cmpval = DtoolInstance_ComparePointers(v1, v2); - Py_RETURN_RICHCOMPARE(cmpval, 0, op); -} - -/** - * Utility function for assigning a PyObject pointer while managing refcounts. - */ -ALWAYS_INLINE void -Dtool_Assign_PyObject(PyObject *&ptr, PyObject *value) { - PyObject *prev_value = ptr; - if (prev_value != value) { - ptr = Py_XNewRef(value); - Py_XDECREF(prev_value); - } -} - -/** - * Converts the enum value to a C long. - */ -INLINE long Dtool_EnumValue_AsLong(PyObject *value) { - PyObject *val = PyObject_GetAttrString(value, "value"); - if (val != nullptr) { - long as_long = PyLongOrInt_AS_LONG(val); - Py_DECREF(val); - return as_long; - } else { - return -1; - } -} - /** * These functions wrap a pointer for a class that defines get_type_handle(). */ @@ -167,23 +110,6 @@ DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *typ return 0; } -/** - * Checks that the tuple is empty. - */ -ALWAYS_INLINE bool -Dtool_CheckNoArgs(PyObject *args) { - return PyTuple_GET_SIZE(args) == 0; -} - -/** - * Checks that the tuple is empty, and that the dict is empty or NULL. - */ -ALWAYS_INLINE bool -Dtool_CheckNoArgs(PyObject *args, PyObject *kwds) { - return PyTuple_GET_SIZE(args) == 0 && - (kwds == nullptr || PyDict_GET_SIZE(kwds) == 0); -} - /** * The following functions wrap an arbitrary C++ value into a PyObject. */ @@ -324,7 +250,8 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(PyObject *value) { return value; } -ALWAYS_INLINE PyObject *Dtool_WrapValue(const vector_uchar &value) { +template +ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::vector &value) { #if PY_MAJOR_VERSION >= 3 return PyBytes_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size()); #else diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 4b28908b9a..29a9cd4b28 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -8,15 +8,14 @@ #include #include #include +#include #ifdef USE_DEBUG_PYTHON #define Py_DEBUG #endif #include "pnotify.h" -#include "vector_uchar.h" #include "register_type.h" -#include "interrogate_request.h" #if defined(HAVE_PYTHON) && !defined(CPPPARSER) @@ -24,8 +23,6 @@ #include "py_compat.h" #include -using namespace std; - // this is tempory .. untill this is glued better into the panda build system #if defined(_WIN32) && !defined(LINK_ALL_STATIC) @@ -86,83 +83,6 @@ struct Dtool_PyTypedObject { CoerceFunction _Dtool_Coerce; }; -// This is now simply a forward declaration. The actual definition is created -// by the code generator. -#define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \ - extern Dtool_PyTypedObject Dtool_##CLASS_NAME; - -// More Macro(s) to Implement class functions.. Usually used if C++ needs type -// information -#define Define_Dtool_new(CLASS_NAME,CNAME)\ -static PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds) {\ - (void) args; (void) kwds;\ - PyObject *self = type->tp_alloc(type, 0);\ - ((Dtool_PyInstDef *)self)->_signature = PY_PANDA_SIGNATURE;\ - ((Dtool_PyInstDef *)self)->_My_Type = &Dtool_##CLASS_NAME;\ - return self;\ -} - -// The following used to be in the above macro, but it doesn't seem to be -// necessary as tp_alloc memsets the object to 0. -// ((Dtool_PyInstDef *)self)->_ptr_to_object = NULL; -// ((Dtool_PyInstDef *)self)->_memory_rules = false; -// ((Dtool_PyInstDef *)self)->_is_const = false; - -// Delete functions.. -#ifdef NDEBUG -#define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\ -static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ - Py_TYPE(self)->tp_free(self);\ -} -#else // NDEBUG -#define Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\ -static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ - if (DtoolInstance_VOID_PTR(self) != nullptr) {\ - if (((Dtool_PyInstDef *)self)->_memory_rules) {\ - std::cerr << "Detected leak for " << #CLASS_NAME \ - << " which interrogate cannot delete.\n"; \ - }\ - }\ - Py_TYPE(self)->tp_free(self);\ -} -#endif // NDEBUG - -#define Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\ -static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ - if (DtoolInstance_VOID_PTR(self) != nullptr) {\ - if (((Dtool_PyInstDef *)self)->_memory_rules) {\ - delete (CNAME *)DtoolInstance_VOID_PTR(self);\ - }\ - }\ - Py_TYPE(self)->tp_free(self);\ -} - -#define Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\ -static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ - if (DtoolInstance_VOID_PTR(self) != nullptr) {\ - if (((Dtool_PyInstDef *)self)->_memory_rules) {\ - unref_delete((CNAME *)DtoolInstance_VOID_PTR(self));\ - }\ - }\ - Py_TYPE(self)->tp_free(self);\ -} - -#define Define_Dtool_FreeInstanceRef_Private(CLASS_NAME,CNAME)\ -static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ - if (DtoolInstance_VOID_PTR(self) != nullptr) {\ - if (((Dtool_PyInstDef *)self)->_memory_rules) {\ - unref_delete((ReferenceCount *)(CNAME *)DtoolInstance_VOID_PTR(self));\ - }\ - }\ - Py_TYPE(self)->tp_free(self);\ -} - -#define Define_Dtool_Simple_FreeInstance(CLASS_NAME, CNAME)\ -static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ - ((Dtool_InstDef_##CLASS_NAME *)self)->_value.~##CLASS_NAME();\ - Py_TYPE(self)->tp_free(self);\ -} - // Extract the PyTypeObject pointer corresponding to a Dtool_PyTypedObject. #define Dtool_GetPyTypeObject(type) (&(type)->_PyType) @@ -178,31 +98,12 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ #define DtoolInstance_INIT_PTR(obj, ptr) { ((Dtool_PyInstDef *)obj)->_ptr_to_object = (void*)(ptr); } #define DtoolInstance_UPCAST(obj, type) (((Dtool_PyInstDef *)(obj))->_My_Type->_Dtool_UpcastInterface((obj), &(type))) -// ** HACK ** allert.. Need to keep a runtime type dictionary ... that is -// forward declared of typed object. We rely on the fact that typed objects -// are uniquly defined by an integer. - -#if PY_VERSION_HEX >= 0x030d0000 -class Dtool_TypeMap : public std::map { -public: - PyMutex _lock { 0 }; -}; -#else -typedef std::map Dtool_TypeMap; -#endif - -EXPCL_PYPANDA Dtool_TypeMap *Dtool_GetGlobalTypeMap(); - class DtoolProxy { public: mutable PyObject *_self; TypeHandle _type; }; -EXPCL_PYPANDA void DtoolProxy_Init(DtoolProxy *proxy, PyObject *self, - Dtool_PyTypedObject &classdef, - TypeRegistry::PythonWrapFunc *wrap_func); - /** */ @@ -218,19 +119,6 @@ EXPCL_PYPANDA bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_ template INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into); template INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &classdef); -INLINE Py_hash_t DtoolInstance_HashPointer(PyObject *self); -INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2); -INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op); - -// Functions related to error reporting. -EXPCL_PYPANDA bool _Dtool_CheckErrorOccurred(); - -#ifdef NDEBUG -#define Dtool_CheckErrorOccurred() (UNLIKELY(PyErr_Occurred() != nullptr)) -#else -#define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred())) -#endif - EXPCL_PYPANDA PyObject *Dtool_Raise_AssertionError(); EXPCL_PYPANDA PyObject *Dtool_Raise_TypeError(const char *message); EXPCL_PYPANDA PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name); @@ -251,31 +139,6 @@ EXPCL_PYPANDA int _Dtool_Raise_BadArgumentsError_Int(const char *message); #define Dtool_Raise_BadArgumentsError_Int(x) _Dtool_Raise_BadArgumentsError_Int(x) #endif -// 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_PYPANDA PyObject *_Dtool_Return_None(); -EXPCL_PYPANDA PyObject *Dtool_Return_Bool(bool value); -EXPCL_PYPANDA PyObject *_Dtool_Return(PyObject *value); - -#ifdef NDEBUG -#define Dtool_Return_None() (LIKELY(PyErr_Occurred() == nullptr) ? (Py_NewRef(Py_None)) : nullptr) -#define Dtool_Return(value) (LIKELY(PyErr_Occurred() == nullptr) ? value : nullptr) -#else -#define Dtool_Return_None() _Dtool_Return_None() -#define Dtool_Return(value) _Dtool_Return(value) -#endif - -ALWAYS_INLINE void Dtool_Assign_PyObject(PyObject *&ptr, PyObject *value); - -/** - * Wrapper around Python 3.4's enum library, which does not have a C API. - */ -EXPCL_PYPANDA PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, - const char *module = nullptr); -INLINE long Dtool_EnumValue_AsLong(PyObject *value); - - /** */ @@ -292,102 +155,9 @@ template INLINE PyObject *DTool_CreatePyInstance(T *obj, bool memory_ru template INLINE PyObject *DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules); template INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memory_rules); -// Macro(s) class definition .. Used to allocate storage and init some values -// for a Dtool Py Type object. - -// struct Dtool_PyTypedObject Dtool_##CLASS_NAME; - -#define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ -extern struct Dtool_PyTypedObject Dtool_##CLASS_NAME;\ -static int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\ -static PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds); - -#define Define_Module_Class(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ -Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ -Define_Dtool_new(CLASS_NAME,CNAME)\ -Define_Dtool_FreeInstance(CLASS_NAME,CNAME)\ -Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) - -#define Define_Module_Class_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ -Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ -Define_Dtool_new(CLASS_NAME,CNAME)\ -Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\ -Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) - -#define Define_Module_ClassRef_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ -Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ -Define_Dtool_new(CLASS_NAME,CNAME)\ -Define_Dtool_FreeInstanceRef_Private(CLASS_NAME,CNAME)\ -Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) - -#define Define_Module_ClassRef(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ -Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ -Define_Dtool_new(CLASS_NAME,CNAME)\ -Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\ -Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) - // The finalizer for simple instances. 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; - -// 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 - -struct Dtool_TypeDef { - const char *const name; - Dtool_PyTypedObject *type; -}; - -struct LibraryDef { - PyMethodDef *const _methods; - const Dtool_TypeDef *const _types; - Dtool_TypeDef *const _external_types; - const InterrogateModuleDef *const _module_def; -}; - -#if PY_MAJOR_VERSION >= 3 -EXPCL_PYPANDA PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def); -#else -EXPCL_PYPANDA 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_PYPANDA PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args); - -#define DTOOL_PyObject_HashPointer DtoolInstance_HashPointer -#define DTOOL_PyObject_ComparePointers DtoolInstance_ComparePointers - -EXPCL_PYPANDA PyObject * -copy_from_make_copy(PyObject *self, PyObject *noargs); - -EXPCL_PYPANDA PyObject * -copy_from_copy_constructor(PyObject *self, PyObject *noargs); - -EXPCL_PYPANDA PyObject * -map_deepcopy_to_copy(PyObject *self, PyObject *args); - -/** - * These functions check whether the arguments passed to a function conform to - * certain expectations. - */ -ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args); -ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args, PyObject *kwds); -EXPCL_PYPANDA bool Dtool_ExtractArg(PyObject **result, PyObject *args, - PyObject *kwds, const char *keyword); -EXPCL_PYPANDA bool Dtool_ExtractArg(PyObject **result, PyObject *args, - PyObject *kwds); -EXPCL_PYPANDA bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, - PyObject *kwds, const char *keyword); -EXPCL_PYPANDA bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, - PyObject *kwds); - /** * These functions convert a C++ value into the corresponding Python object. * This used to be generated by the code generator, but it seems more reliable @@ -412,7 +182,8 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(char value); ALWAYS_INLINE PyObject *Dtool_WrapValue(wchar_t value); ALWAYS_INLINE PyObject *Dtool_WrapValue(std::nullptr_t); ALWAYS_INLINE PyObject *Dtool_WrapValue(PyObject *value); -ALWAYS_INLINE PyObject *Dtool_WrapValue(const vector_uchar &value); +template +ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::vector &value); #if PY_MAJOR_VERSION >= 0x02060000 ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value); @@ -423,9 +194,12 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::pair &value); EXPCL_PYPANDA Dtool_PyTypedObject *Dtool_GetSuperBase(); -#include "py_panda.I" +/** + * Creates a Python generator object from a next() function. + */ +EXPCL_PYPANDA PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func); -#include "py_wrappers.h" +#include "py_panda.I" #endif // HAVE_PYTHON && !CPPPARSER diff --git a/dtool/src/interrogatedb/py_wrappers.h b/dtool/src/interrogatedb/py_wrappers.h deleted file mode 100644 index eb5658cb6b..0000000000 --- a/dtool/src/interrogatedb/py_wrappers.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @file py_wrappers.h - * @author rdb - * @date 2017-11-26 - */ - -#ifndef PY_WRAPPERS_H -#define PY_WRAPPERS_H - -#include "py_panda.h" - -#ifdef HAVE_PYTHON - -/** - * These classes are returned from properties that require a subscript - * interface, ie. something.children[i] = 3. - */ -struct Dtool_WrapperBase { - PyObject_HEAD; - PyObject *_self; - const char *_name; -}; - -struct Dtool_SequenceWrapper { - Dtool_WrapperBase _base; - lenfunc _len_func; - ssizeargfunc _getitem_func; -}; - -struct Dtool_MutableSequenceWrapper { - Dtool_WrapperBase _base; - lenfunc _len_func; - ssizeargfunc _getitem_func; - ssizeobjargproc _setitem_func; - PyObject *(*_insert_func)(PyObject *, size_t, PyObject *); -}; - -struct Dtool_MappingWrapper { - union { - Dtool_WrapperBase _base; - Dtool_SequenceWrapper _keys; - }; - binaryfunc _getitem_func; - objobjargproc _setitem_func; -}; - -struct Dtool_GeneratorWrapper { - Dtool_WrapperBase _base; - iternextfunc _iternext_func; -}; - -EXPCL_PYPANDA Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name); -EXPCL_PYPANDA Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name); -EXPCL_PYPANDA Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name); -EXPCL_PYPANDA Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name); -EXPCL_PYPANDA PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func); -EXPCL_PYPANDA PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset); - -#endif // HAVE_PYTHON - -#endif // PY_WRAPPERS_H diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 71a7df38fd..1d79c9061c 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -589,8 +589,8 @@ def GetInterrogateDir(): return INTERROGATE_DIR dir = os.path.join(GetOutputDir(), "tmp", "interrogate") - if not os.path.isdir(os.path.join(dir, "panda3d_interrogate-0.6.1.dist-info")): - oscmd("\"%s\" -m pip install --force-reinstall --upgrade -t \"%s\" panda3d-interrogate==0.6.1" % (sys.executable, dir)) + if not os.path.isdir(os.path.join(dir, "panda3d_interrogate-0.7.0.dist-info")): + oscmd("\"%s\" -m pip install --force-reinstall --upgrade -t \"%s\" panda3d-interrogate==0.7.0" % (sys.executable, dir)) INTERROGATE_DIR = dir