From 192d10b937a95f5a1a9b63e9b1e8406ee287cd6f Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 16 Feb 2013 19:22:26 +0000 Subject: [PATCH] Experimental Python 3 support to the C++ code including interrogate. Also adds support for rich comparison in interrogate. --- direct/src/dcparser/dcClass.cxx | 8 + direct/src/dcparser/dcField.cxx | 16 +- direct/src/dcparser/dcPacker.cxx | 57 +- direct/src/directbase/ppython.cxx | 59 +- .../src/distributed/cConnectionRepository.cxx | 20 +- direct/src/ffi/DoGenPyCode.py | 14 +- direct/src/ffi/FFIRename.py | 12 +- direct/src/showbase/PythonUtil.py | 3 +- dtool/metalibs/dtoolconfig/pydtool.cxx | 441 +++- .../interfaceMakerPythonNative.cxx | 1892 +++++++++-------- .../interrogate/interfaceMakerPythonNative.h | 23 +- .../interrogate/interfaceMakerPythonObj.cxx | 62 +- .../interfaceMakerPythonSimple.cxx | 59 +- dtool/src/interrogate/interrogateBuilder.cxx | 23 +- dtool/src/interrogate/interrogate_module.cxx | 35 +- dtool/src/interrogatedb/dtool_super_base.cxx | 99 +- dtool/src/interrogatedb/py_panda.cxx | 664 +++--- dtool/src/interrogatedb/py_panda.h | 270 ++- panda/src/display/graphicsWindow.cxx | 12 +- panda/src/event/pythonTask.cxx | 64 +- panda/src/express/pointerToArray.I | 33 +- panda/src/express/virtualFileSystem.cxx | 18 +- .../nativenet/buffered_datagramconnection.h | 2 +- panda/src/pgraph/pandaNode.cxx | 18 + 24 files changed, 2397 insertions(+), 1507 deletions(-) diff --git a/direct/src/dcparser/dcClass.cxx b/direct/src/dcparser/dcClass.cxx index dfeb02d70e..cd9a3856b3 100644 --- a/direct/src/dcparser/dcClass.cxx +++ b/direct/src/dcparser/dcClass.cxx @@ -997,7 +997,11 @@ client_format_generate_CMU(PyObject *distobj, DOID_TYPE do_id, for (int i = 0; i < num_optional_fields; i++) { PyObject *py_field_name = PySequence_GetItem(optional_fields, i); +#if PY_MAJOR_VERSION >= 3 + string field_name = PyUnicode_AsUTF8(py_field_name); +#else string field_name = PyString_AsString(py_field_name); +#endif Py_XDECREF(py_field_name); DCField *field = get_field_by_name(field_name); @@ -1082,7 +1086,11 @@ ai_format_generate(PyObject *distobj, DOID_TYPE do_id, for (int i = 0; i < num_optional_fields; ++i) { PyObject *py_field_name = PySequence_GetItem(optional_fields, i); +#if PY_MAJOR_VERSION >= 3 + string field_name = PyUnicode_AsUTF8(py_field_name); +#else string field_name = PyString_AsString(py_field_name); +#endif Py_XDECREF(py_field_name); DCField *field = get_field_by_name(field_name); diff --git a/direct/src/dcparser/dcField.cxx b/direct/src/dcparser/dcField.cxx index fc60c47362..7946b62aa1 100644 --- a/direct/src/dcparser/dcField.cxx +++ b/direct/src/dcparser/dcField.cxx @@ -269,7 +269,7 @@ pack_args(DCPacker &packer, PyObject *sequence) const { if (!Notify::ptr()->has_assert_failed()) { ostringstream strm; - PyObject *exc_type = PyExc_StandardError; + PyObject *exc_type = PyExc_Exception; if (as_parameter() != (DCParameter *)NULL) { // If it's a parameter-type field, the value may or may not be a @@ -345,7 +345,7 @@ unpack_args(DCPacker &packer) const { if (!Notify::ptr()->has_assert_failed()) { ostringstream strm; - PyObject *exc_type = PyExc_StandardError; + PyObject *exc_type = PyExc_Exception; if (packer.had_pack_error()) { strm << "Data error unpacking field "; @@ -585,14 +585,22 @@ get_pystr(PyObject *value) { PyObject *str = PyObject_Str(value); if (str != NULL) { +#if PY_MAJOR_VERSION >= 3 + string result = PyUnicode_AsUTF8(str); +#else string result = PyString_AsString(str); +#endif Py_DECREF(str); return result; } PyObject *repr = PyObject_Repr(value); if (repr != NULL) { +#if PY_MAJOR_VERSION >= 3 + string result = PyUnicode_AsUTF8(repr); +#else string result = PyString_AsString(repr); +#endif Py_DECREF(repr); return result; } @@ -600,7 +608,11 @@ get_pystr(PyObject *value) { if (value->ob_type != NULL) { PyObject *typestr = PyObject_Str((PyObject *)(value->ob_type)); if (typestr != NULL) { +#if PY_MAJOR_VERSION >= 3 + string result = PyUnicode_AsUTF8(typestr); +#else string result = PyString_AsString(typestr); +#endif Py_DECREF(typestr); return result; } diff --git a/direct/src/dcparser/dcPacker.cxx b/direct/src/dcparser/dcPacker.cxx index 56c83601a6..9be83fda34 100755 --- a/direct/src/dcparser/dcPacker.cxx +++ b/direct/src/dcparser/dcPacker.cxx @@ -695,11 +695,13 @@ pack_object(PyObject *object) { pack_int64(PyLong_AsLongLong(object)); return; } +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(object)) { pack_int64(PyInt_AsLong(object)); return; } +#endif break; case PT_uint64: if(PyLong_Check(object)) @@ -707,6 +709,7 @@ pack_object(PyObject *object) { pack_uint64(PyLong_AsUnsignedLongLong(object)); return; } +#if PY_MAJOR_VERSION < 3 else if(PyInt_Check(object)) { PyObject *obj1 = PyNumber_Long(object); @@ -714,6 +717,7 @@ pack_object(PyObject *object) { Py_DECREF(obj1); return; } +#endif break; case PT_int: if(PyLong_Check(object)) @@ -721,11 +725,13 @@ pack_object(PyObject *object) { pack_int(PyLong_AsLong(object)); return; } +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(object)) { pack_int(PyInt_AsLong(object)); return; } +#endif break; case PT_uint: if(PyLong_Check(object)) @@ -733,29 +739,45 @@ pack_object(PyObject *object) { pack_uint(PyLong_AsUnsignedLong(object)); return; } +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(object)) { - PyObject *obj1 = PyNumber_Long(object); + PyObject *obj1 = PyNumber_Long(object); pack_uint(PyLong_AsUnsignedLong(obj1)); Py_DECREF(obj1); return; } +#endif break; default: break; } - #ifdef USE_PYTHON_2_2_OR_EARLIER - if (PyInt_Check(object)) { - #else if (PyLong_Check(object)) { pack_int(PyLong_AsLong(object)); +#if PY_MAJOR_VERSION < 3 } else if (PyInt_Check(object)) { - #endif pack_int(PyInt_AS_LONG(object)); +#endif } else if (PyFloat_Check(object)) { pack_double(PyFloat_AS_DOUBLE(object)); } else if (PyLong_Check(object)) { pack_int64(PyLong_AsLongLong(object)); +#if PY_MAJOR_VERSION >= 3 + } else if (PyUnicode_Check(object)) { + char *buffer; + Py_ssize_t length; + buffer = PyUnicode_AsUTF8AndSize(object, &length); + if (buffer) { + pack_string(string(buffer, length)); + } + } else if (PyBytes_Check(object)) { + char *buffer; + Py_ssize_t length; + PyBytes_AsStringAndSize(object, &buffer, &length); + if (buffer) { + pack_string(string(buffer, length)); + } +#else } else if (PyString_Check(object) || PyUnicode_Check(object)) { char *buffer; Py_ssize_t length; @@ -763,6 +785,7 @@ pack_object(PyObject *object) { if (buffer) { pack_string(string(buffer, length)); } +#endif } else { // For some reason, PySequence_Check() is incorrectly reporting // that a class instance is a sequence, even if it doesn't provide @@ -871,18 +894,26 @@ unpack_object() { case PT_int: { int value = unpack_int(); +#if PY_MAJOR_VERSION >= 3 + object = PyLong_FromLong(value); +#else object = PyInt_FromLong(value); +#endif } break; case PT_uint: { unsigned int value = unpack_uint(); +#if PY_MAJOR_VERSION >= 3 + object = PyLong_FromLong(value); +#else if (value & 0x80000000) { object = PyLong_FromUnsignedLong(value); } else { object = PyInt_FromLong(value); } +#endif } break; @@ -900,12 +931,26 @@ unpack_object() { } break; - case PT_string: case PT_blob: +#if PY_MAJOR_VERSION >= 3 { string str; unpack_string(str); + object = PyBytes_FromStringAndSize(str.data(), str.size()); + } + break; +#endif + // On Python 2, fall through to below. + + case PT_string: + { + string str; + unpack_string(str); +#if PY_MAJOR_VERSION >= 3 + object = PyUnicode_FromStringAndSize(str.data(), str.size()); +#else object = PyString_FromStringAndSize(str.data(), str.size()); +#endif } break; diff --git a/direct/src/directbase/ppython.cxx b/direct/src/directbase/ppython.cxx index 28f0dcfd2c..df16243c61 100755 --- a/direct/src/directbase/ppython.cxx +++ b/direct/src/directbase/ppython.cxx @@ -8,6 +8,9 @@ /////////////////////////////////////////////////////////////////////// #include +#if PY_MAJOR_VERSION >= 3 +#include +#endif #ifndef IMPORT_MODULE #error IMPORT_MODULE must be defined when compiling ppython.cxx ! @@ -17,14 +20,54 @@ #define STRINGIFY(s) _STRINGIFY(s) #define IMPORT_MODULE_STR STRINGIFY(IMPORT_MODULE) -int main(int argc, char **argv) { - int sts = 0; +#if defined(_WIN32) && PY_MAJOR_VERSION >= 3 +// As Py_SetProgramName expects a wchar_t*, +// it's easiest to just use the wmain entry point. +int wmain(int argc, wchar_t *argv[]) { + Py_SetProgramName(argv[0]); + +#elif PY_MAJOR_VERSION >= 3 +// Convert from UTF-8 to wchar_t*. +int main(int argc, char *mb_argv[]) { + wchar_t **argv = new wchar_t*[argc + 1]; + for (int i = 0; i < argc; ++i) { + size_t len = mbstowcs(NULL, mb_argv[i], 0); + argv[i] = new wchar_t[len + 1]; + mbstowcs(argv[i], mb_argv[i], len); + argv[i][len] = NULL; + } + // Just for good measure + argv[argc] = NULL; Py_SetProgramName(argv[0]); - - // On windows, we need to set pythonhome correctly. We'll try to + +#else +// Python 2. +int main(int argc, char *argv[]) { + Py_SetProgramName(argv[0]); +#endif + + // On Windows, we need to set pythonhome correctly. We'll try to // find ppython.exe on the path and set pythonhome to its location. #ifdef _WIN32 +#if PY_MAJOR_VERSION >= 3 + // Py_SetPythonHome expects a wchar_t in Python 3. + wchar_t *path = _wgetenv(L"PATH"); + wchar_t *result = wcstok(path, L";"); + while (result != NULL) { + struct _stat st; + wchar_t *ppython = (wchar_t*) malloc(wcslen(result) * 2 + 26); + wcscpy(ppython, result); + wcscat(ppython, L"\\python.exe"); + if (_wstat(ppython, &st) == 0) { + Py_SetPythonHome(result); + free(ppython); + break; + } + result = wcstok(NULL, L";"); + free(ppython); + } +#else char *path = getenv("PATH"); char *result = strtok(path, ";"); while (result != NULL) { @@ -33,13 +76,14 @@ int main(int argc, char **argv) { strcpy(ppython, result); strcat(ppython, "\\ppython.exe"); if (stat(ppython, &st) == 0) { - Py_SetPythonHome(result); - free(ppython); - break; + Py_SetPythonHome(result); + free(ppython); + break; } result = strtok(NULL, ";"); free(ppython); } +#endif #endif Py_Initialize(); @@ -50,6 +94,7 @@ int main(int argc, char **argv) { PySys_SetArgv(argc, argv); + int sts = 0; PyObject* m = PyImport_ImportModule(IMPORT_MODULE_STR); if (m <= 0) { PyErr_Print(); diff --git a/direct/src/distributed/cConnectionRepository.cxx b/direct/src/distributed/cConnectionRepository.cxx index 5d089b0981..240af9be5c 100644 --- a/direct/src/distributed/cConnectionRepository.cxx +++ b/direct/src/distributed/cConnectionRepository.cxx @@ -769,7 +769,7 @@ handle_update_field() { Py_DECREF(dclass_obj); nassertr(dclass_this != NULL, false); - DCClass *dclass = (DCClass *)PyInt_AsLong(dclass_this); + DCClass *dclass = (DCClass *)PyLong_AsLong(dclass_this); Py_DECREF(dclass_this); // If in quiet zone mode, throw update away unless distobj @@ -778,7 +778,7 @@ handle_update_field() { PyObject *neverDisable = PyObject_GetAttrString(distobj, "neverDisable"); nassertr(neverDisable != NULL, false); - unsigned int cNeverDisable = PyInt_AsLong(neverDisable); + unsigned int cNeverDisable = PyLong_AsLong(neverDisable); if (!cNeverDisable) { // in quiet zone and distobj is disable-able // drop update on the floor @@ -863,7 +863,7 @@ handle_update_field_owner() { Py_DECREF(dclass_obj); nassertr(dclass_this != NULL, false); - DCClass *dclass = (DCClass *)PyInt_AsLong(dclass_this); + DCClass *dclass = (DCClass *)PyLong_AsLong(dclass_this); Py_DECREF(dclass_this); // check if we should forward this update to the owner view @@ -905,7 +905,7 @@ handle_update_field_owner() { Py_DECREF(dclass_obj); nassertr(dclass_this != NULL, false); - DCClass *dclass = (DCClass *)PyInt_AsLong(dclass_this); + DCClass *dclass = (DCClass *)PyLong_AsLong(dclass_this); Py_DECREF(dclass_this); // check if we should forward this update to the owner view @@ -982,14 +982,22 @@ describe_message(ostream &out, const string &prefix, if (_python_repository != (PyObject *)NULL) { PyObject *msgId = PyLong_FromLong(msg_type); nassertv(msgId != NULL); +#if PY_MAJOR_VERSION >= 3 + PyObject *methodName = PyUnicode_FromString("_getMsgName"); +#else PyObject *methodName = PyString_FromString("_getMsgName"); +#endif nassertv(methodName != NULL); PyObject *result = PyObject_CallMethodObjArgs(_python_repository, methodName, msgId, NULL); nassertv(result != NULL); +#if PY_MAJOR_VERSION >= 3 + msgName += string(PyUnicode_AsUTF8(result)); +#else msgName += string(PyString_AsString(result)); +#endif Py_DECREF(methodName); Py_DECREF(msgId); @@ -1032,8 +1040,8 @@ describe_message(ostream &out, const string &prefix, PyObject *dclass_this = PyObject_GetAttrString(dclass_obj, "this"); Py_DECREF(dclass_obj); nassertv(dclass_this != NULL); - - dclass = (DCClass *)PyInt_AsLong(dclass_this); + + dclass = (DCClass *)PyLong_AsLong(dclass_this); Py_DECREF(dclass_this); } } diff --git a/direct/src/ffi/DoGenPyCode.py b/direct/src/ffi/DoGenPyCode.py index 4749475d0b..f23725b1f7 100644 --- a/direct/src/ffi/DoGenPyCode.py +++ b/direct/src/ffi/DoGenPyCode.py @@ -103,17 +103,17 @@ def doGetopts(): # Extract the args the user passed in try: opts, pargs = getopt.getopt(sys.argv[1:], 'hvdOC:H:x:Ni:e:p:rns') - except Exception, e: + except e: # User passed in a bad option, print the error and the help, then exit - print e - print helpString + print(e) + print(helpString) sys.exit() # Store the option values into our variables for opt in opts: flag, value = opt if (flag == '-h'): - print helpString + print(helpString) sys.exit() elif (flag == '-v'): if not FFIConstants.notify.getInfo(): @@ -254,7 +254,7 @@ def generateNativeWrappers(): # Generate a series of "libpandaModules.py" etc. files, one for # each named module. for moduleName in FFIConstants.CodeModuleNameList: - print 'Importing code library: ' + moduleName + print('Importing code library: ' + moduleName) Dtool_PreloadDLL(moduleName) exec('import %s as module' % moduleName) @@ -264,7 +264,7 @@ def generateNativeWrappers(): # not necessarily downloaded. pandaModules.write('try:\n from %sModules import *\nexcept ImportError, err:\n if "DLL loader cannot find" not in str(err):\n raise\n' % (moduleName)) # Not sure if this message is helpful or annoying. - #pandaModules.write(' print "Failed to import %s"\n' % (moduleName)) + #pandaModules.write(' print("Failed to import %s")\n' % (moduleName)) pandaModules.write('\n') moduleModulesFilename = os.path.join(outputCodeDir, '%sModules.py' % (moduleName)) @@ -279,7 +279,7 @@ def generateNativeWrappers(): if type(classDef) == types.TypeType: extensionFilename = os.path.join(extensionsDir, '%s_extensions.py' % (className)) if os.path.exists(extensionFilename): - print ' Found extensions for class: %s' % (className) + print(' Found extensions for class: %s' % (className)) extension = open(extensionFilename, 'r') moduleModules.write(extension.read()) moduleModules.write('\n') diff --git a/direct/src/ffi/FFIRename.py b/direct/src/ffi/FFIRename.py index 9a5aed038d..69c985ffbe 100644 --- a/direct/src/ffi/FFIRename.py +++ b/direct/src/ffi/FFIRename.py @@ -6,14 +6,14 @@ pythonKeywords = ['and','del','for','is','raise','assert','elif','from','lambda' methodRenameDictionary = { - 'operator==': 'eq', - 'operator!=': 'ne', + 'operator==': '__eq__', + 'operator!=': '__ne__', 'operator<<': '__lshift__', 'operator>>': '__rshift__', - 'operator<': 'lessThan', - 'operator>': 'greaterThan', - 'operator<=': 'lessThanOrEqual', - 'operator>=': 'greaterThanOrEqual', + 'operator<': '__lt__', + 'operator>': '__gt__', + 'operator<=': '__le__', + 'operator>=': '__ge__', 'operator=': 'assign', 'operator()': '__call__', 'operator[]': '__getitem__', diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index 6015bcad24..9b77d6537e 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -2479,7 +2479,8 @@ def _getDtoolSuperBase(): global dtoolSuperBase from pandac.PandaModules import PandaNode dtoolSuperBase = PandaNode('').__class__.__bases__[0].__bases__[0].__bases__[0] - assert repr(dtoolSuperBase) == "" + assert repr(dtoolSuperBase) == "" \ + or repr(dtoolSuperBase) == "" safeReprNotify = None diff --git a/dtool/metalibs/dtoolconfig/pydtool.cxx b/dtool/metalibs/dtoolconfig/pydtool.cxx index a061bdf969..12a1887cd5 100644 --- a/dtool/metalibs/dtoolconfig/pydtool.cxx +++ b/dtool/metalibs/dtoolconfig/pydtool.cxx @@ -186,7 +186,7 @@ static PyObject * _inPfd5R4RgX(PyObject *, PyObject *args) { if (PyArg_ParseTuple(args, "")) { bool return_value = interrogate_error_flag(); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -199,7 +199,11 @@ static PyObject * _inPfd5R3Gip(PyObject *, PyObject *args) { if (PyArg_ParseTuple(args, "")) { int return_value = interrogate_number_of_manifests(); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -213,7 +217,11 @@ _inPfd5RRKDz(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_get_manifest((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -227,7 +235,11 @@ _inPfd5RgZ9N(PyObject *, PyObject *args) { char *param0; if (PyArg_ParseTuple(args, "s", ¶m0)) { int return_value = interrogate_get_manifest_by_name((char const *)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -241,7 +253,11 @@ _inPfd5RRQIx(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_manifest_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -255,7 +271,11 @@ _inPfd5RGVSj(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_manifest_definition((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -269,7 +289,7 @@ _inPfd5RznM6(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_manifest_has_type((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -283,7 +303,11 @@ _inPfd5RjiLg(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_manifest_get_type((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -297,7 +321,7 @@ _inPfd5R_yjE(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_manifest_has_getter((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -311,7 +335,11 @@ _inPfd5RzK9F(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_manifest_getter((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -325,7 +353,7 @@ _inPfd5RJju_(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_manifest_has_int_value((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -339,7 +367,11 @@ _inPfd5RZktk(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_manifest_get_int_value((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -353,7 +385,11 @@ _inPfd5RG71J(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_element_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -367,7 +403,11 @@ _inPfd5RgeUs(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_element_scoped_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -381,7 +421,11 @@ _inPfd5Rkg95(PyObject *, PyObject *args) { char *param0; if (PyArg_ParseTuple(args, "s", ¶m0)) { int return_value = interrogate_get_element_by_name((char const *)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -395,7 +439,11 @@ _inPfd5RluRc(PyObject *, PyObject *args) { char *param0; if (PyArg_ParseTuple(args, "s", ¶m0)) { int return_value = interrogate_get_element_by_scoped_name((char const *)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -409,7 +457,11 @@ _inPfd5RwtTf(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_element_type((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -423,7 +475,7 @@ _inPfd5Rrfao(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_element_has_getter((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -437,7 +489,11 @@ _inPfd5Rcedk(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_element_getter((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -451,7 +507,7 @@ _inPfd5RXmoo(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_element_has_setter((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -465,7 +521,11 @@ _inPfd5RclIo(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_element_setter((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -478,7 +538,11 @@ static PyObject * _inPfd5RU2_B(PyObject *, PyObject *args) { if (PyArg_ParseTuple(args, "")) { int return_value = interrogate_number_of_globals(); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -492,7 +556,11 @@ _inPfd5RHFO2(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_get_global((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -505,7 +573,11 @@ static PyObject * _inPfd5Rcfjm(PyObject *, PyObject *args) { if (PyArg_ParseTuple(args, "")) { int return_value = interrogate_number_of_global_functions(); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -519,7 +591,11 @@ _inPfd5R3Sjw(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_get_global_function((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -532,7 +608,11 @@ static PyObject * _inPfd5RgJcX(PyObject *, PyObject *args) { if (PyArg_ParseTuple(args, "")) { int return_value = interrogate_number_of_functions(); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -546,7 +626,11 @@ _inPfd5RYlw6(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_get_function((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -560,7 +644,11 @@ _inPfd5R3gns(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_function_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -574,7 +662,11 @@ _inPfd5RN968(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_function_scoped_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -588,7 +680,7 @@ _inPfd5RFJVJ(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_function_has_comment((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -602,7 +694,11 @@ _inPfd5RndTW(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_function_comment((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -616,7 +712,11 @@ _inPfd5RpjWj(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_function_prototype((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -630,7 +730,7 @@ _inPfd5RNcQW(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_function_is_method((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -644,7 +744,11 @@ _inPfd5RP_SX(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_function_class((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -658,7 +762,7 @@ _inPfd5R1iRq(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_function_has_module_name((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -672,7 +776,11 @@ _inPfd5REmel(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_function_module_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -686,7 +794,7 @@ _inPfd5R20Vx(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_function_has_library_name((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -700,7 +808,11 @@ _inPfd5RKcdW(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_function_library_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -714,7 +826,7 @@ _inPfd5RhUs9(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_function_is_virtual((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -728,7 +840,11 @@ _inPfd5RhF25(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_function_number_of_c_wrappers((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -743,7 +859,11 @@ _inPfd5Ru1qB(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_function_c_wrapper((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -757,7 +877,11 @@ _inPfd5RKMkY(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_function_number_of_python_wrappers((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -772,7 +896,11 @@ _inPfd5RRx9W(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_function_python_wrapper((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -786,7 +914,11 @@ _inPfd5R0C9G(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_wrapper_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -800,7 +932,7 @@ _inPfd5RhaPp(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_wrapper_is_callable_by_name((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -814,7 +946,7 @@ _inPfd5Rt_1v(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_wrapper_has_comment((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -828,7 +960,11 @@ _inPfd5R8KQG(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_wrapper_comment((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -842,7 +978,7 @@ _inPfd5REtIl(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_wrapper_has_return_value((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -856,7 +992,11 @@ _inPfd5RRFmo(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_wrapper_return_type((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -870,7 +1010,7 @@ _inPfd5RWHA0(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_wrapper_caller_manages_return_value((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -884,7 +1024,11 @@ _inPfd5RcyIl(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_wrapper_return_value_destructor((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -898,7 +1042,11 @@ _inPfd5RBnBv(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_wrapper_number_of_parameters((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -913,7 +1061,11 @@ _inPfd5RUvW7(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_wrapper_parameter_type((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -928,7 +1080,7 @@ _inPfd5RPdXf(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { bool return_value = interrogate_wrapper_parameter_has_name((int)param0, (int)param1); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -943,7 +1095,11 @@ _inPfd5Rd0dl(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { char const *return_value = interrogate_wrapper_parameter_name((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -958,7 +1114,7 @@ _inPfd5RdVbH(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { bool return_value = interrogate_wrapper_parameter_is_this((int)param0, (int)param1); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -972,7 +1128,7 @@ _inPfd5RBwF0(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_wrapper_has_pointer((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1000,7 +1156,11 @@ _inPfd5RhUwR(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_wrapper_unique_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1014,7 +1174,11 @@ _inPfd5RA1eF(PyObject *, PyObject *args) { char *param0; if (PyArg_ParseTuple(args, "s", ¶m0)) { int return_value = interrogate_get_wrapper_by_unique_name((char const *)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1028,7 +1192,11 @@ _inPfd5R8pBy(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_make_seq_class((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1042,7 +1210,11 @@ _inPfd5R85oW(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_make_seq_seq_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1056,7 +1228,11 @@ _inPfd5RYZz0(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_make_seq_num_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1070,7 +1246,11 @@ _inPfd5RzKCA(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_make_seq_element_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1083,7 +1263,11 @@ static PyObject * _inPfd5Rsxxs(PyObject *, PyObject *args) { if (PyArg_ParseTuple(args, "")) { int return_value = interrogate_number_of_global_types(); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1097,7 +1281,11 @@ _inPfd5RMT0z(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_get_global_type((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1110,7 +1298,11 @@ static PyObject * _inPfd5RiW3v(PyObject *, PyObject *args) { if (PyArg_ParseTuple(args, "")) { int return_value = interrogate_number_of_types(); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1124,7 +1316,11 @@ _inPfd5R4Px8(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_get_type((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1138,7 +1334,11 @@ _inPfd5RNHcs(PyObject *, PyObject *args) { char *param0; if (PyArg_ParseTuple(args, "s", ¶m0)) { int return_value = interrogate_get_type_by_name((char const *)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1152,7 +1352,11 @@ _inPfd5RqHrb(PyObject *, PyObject *args) { char *param0; if (PyArg_ParseTuple(args, "s", ¶m0)) { int return_value = interrogate_get_type_by_scoped_name((char const *)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1166,7 +1370,11 @@ _inPfd5RaOqq(PyObject *, PyObject *args) { char *param0; if (PyArg_ParseTuple(args, "s", ¶m0)) { int return_value = interrogate_get_type_by_true_name((char const *)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1180,7 +1388,11 @@ _inPfd5Rvue5(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_type_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1194,7 +1406,11 @@ _inPfd5RB_n_(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_type_scoped_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1208,7 +1424,11 @@ _inPfd5RDFET(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_type_true_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1222,7 +1442,7 @@ _inPfd5RUyNE(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_nested((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1236,7 +1456,11 @@ _inPfd5RpDlm(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_outer_class((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1250,7 +1474,7 @@ _inPfd5RAscF(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_has_comment((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1264,7 +1488,11 @@ _inPfd5RYjbU(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_type_comment((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1278,7 +1506,7 @@ _inPfd5RWmpU(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_has_module_name((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1292,7 +1520,11 @@ _inPfd5RnegH(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_type_module_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1306,7 +1538,7 @@ _inPfd5RrrnF(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_has_library_name((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1320,7 +1552,11 @@ _inPfd5R7ShX(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { char const *return_value = interrogate_type_library_name((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1334,7 +1570,7 @@ _inPfd5Rx_aO(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_atomic((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1348,7 +1584,11 @@ _inPfd5RpofZ(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { AtomicToken return_value = interrogate_type_atomic_token((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1362,7 +1602,7 @@ _inPfd5R2J9C(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_unsigned((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1376,7 +1616,7 @@ _inPfd5RA6iz(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_signed((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1390,7 +1630,7 @@ _inPfd5Ra78E(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_long((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1404,7 +1644,7 @@ _inPfd5RWD3W(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_longlong((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1418,7 +1658,7 @@ _inPfd5RYuud(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_short((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1432,7 +1672,7 @@ _inPfd5RlmJS(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_wrapped((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1446,7 +1686,7 @@ _inPfd5RLlrr(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_pointer((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1460,7 +1700,7 @@ _inPfd5Rw_wy(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_const((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1474,7 +1714,11 @@ _inPfd5Rgk_l(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_wrapped_type((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1488,7 +1732,7 @@ _inPfd5RXpHY(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_enum((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1502,7 +1746,11 @@ _inPfd5RHhIg(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_number_of_enum_values((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1517,7 +1765,11 @@ _inPfd5Rff0T(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { char const *return_value = interrogate_type_enum_value_name((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1532,7 +1784,11 @@ _inPfd5R5PPX(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { char const *return_value = interrogate_type_enum_value_scoped_name((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(return_value); +#else return PyString_FromString(return_value); +#endif } return (PyObject *)NULL; } @@ -1547,7 +1803,11 @@ _inPfd5RPww5(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_enum_value((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1561,7 +1821,7 @@ _inPfd5RPke3(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_struct((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1575,7 +1835,7 @@ _inPfd5RJmw3(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_class((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1589,7 +1849,7 @@ _inPfd5RR0Lc(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_union((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1603,7 +1863,7 @@ _inPfd5Rc6gE(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_fully_defined((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1617,7 +1877,7 @@ _inPfd5R1iT0(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_is_unpublished((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1631,7 +1891,11 @@ _inPfd5Rz1Mn(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_number_of_constructors((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1646,7 +1910,11 @@ _inPfd5RWlf2(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_constructor((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1660,7 +1928,7 @@ _inPfd5R1q8q(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_has_destructor((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1674,7 +1942,7 @@ _inPfd5Robo6(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { bool return_value = interrogate_type_destructor_is_inherited((int)param0); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1688,7 +1956,11 @@ _inPfd5RjevK(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_get_destructor((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1702,7 +1974,11 @@ _inPfd5ReBpM(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_number_of_elements((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1717,7 +1993,11 @@ _inPfd5RfmeN(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_element((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1731,7 +2011,11 @@ _inPfd5RKBCl(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_number_of_methods((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1746,7 +2030,11 @@ _inPfd5R936K(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_method((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1760,7 +2048,11 @@ _inPfd5RPPXQ(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_number_of_make_seqs((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1775,7 +2067,11 @@ _inPfd5Rnu86(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_make_seq((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1789,7 +2085,11 @@ _inPfd5Rngiq(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_number_of_casts((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1804,7 +2104,11 @@ _inPfd5RUXR0(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_cast((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1818,7 +2122,11 @@ _inPfd5RDO7D(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_number_of_derivations((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1833,7 +2141,11 @@ _inPfd5RhZFz(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_derivation((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1848,7 +2160,7 @@ _inPfd5RnKPe(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { bool return_value = interrogate_type_derivation_has_upcast((int)param0, (int)param1); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1863,7 +2175,11 @@ _inPfd5RP3lS(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_upcast((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1878,7 +2194,7 @@ _inPfd5RUlLp(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { bool return_value = interrogate_type_derivation_downcast_is_impossible((int)param0, (int)param1); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1893,7 +2209,7 @@ _inPfd5R9Xei(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { bool return_value = interrogate_type_derivation_has_downcast((int)param0, (int)param1); - return PyInt_FromLong(return_value); + return PyBool_FromLong(return_value); } return (PyObject *)NULL; } @@ -1908,7 +2224,11 @@ _inPfd5RaGkE(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_downcast((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1922,7 +2242,11 @@ _inPfd5Roe_l(PyObject *, PyObject *args) { int param0; if (PyArg_ParseTuple(args, "i", ¶m0)) { int return_value = interrogate_type_number_of_nested_types((int)param0); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -1937,7 +2261,11 @@ _inPfd5RuEdH(PyObject *, PyObject *args) { int param1; if (PyArg_ParseTuple(args, "ii", ¶m0, ¶m1)) { int return_value = interrogate_type_get_nested_type((int)param0, (int)param1); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(return_value); +#else return PyInt_FromLong(return_value); +#endif } return (PyObject *)NULL; } @@ -2074,13 +2402,32 @@ static PyMethodDef python_simple_funcs[] = { { NULL, NULL } }; -#ifdef _WIN32 -extern "C" __declspec(dllexport) void initlibp3dtoolconfig(); +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef python_simple_module = { + PyModuleDef_HEAD_INIT, + "libdtoolconfig", + NULL, + -1, + python_simple_funcs, + NULL, NULL, NULL, NULL +}; + +#define INIT_FUNC PyObject *PyInit_libdtoolconfig #else -extern "C" void initlibp3dtoolconfig(); +#define INIT_FUNC void initlibdtoolconfig #endif -void initlibp3dtoolconfig() { - Py_InitModule("libp3dtoolconfig", python_simple_funcs); +#ifdef _WIN32 +extern "C" __declspec(dllexport) INIT_FUNC(); +#else +extern "C" INIT_FUNC(); +#endif + +INIT_FUNC() { +#if PY_MAJOR_VERSION >= 3 + return PyModule_Create(&python_simple_module); +#else + Py_InitModule("libdtoolconfig", python_simple_funcs); +#endif } diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 3ef2956c9a..42ac6ffed7 100755 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -30,18 +30,16 @@ #include #include - extern bool inside_python_native; extern InterrogateType dummy_type; -extern std::string EXPORT_IMPORT_PREFEX; - -#define CLASS_PREFEX "Dtool_" -#define INSTANCE_PREFEX "Dtool_" -#define BASE_INSTANCE_NAME "Dtool_PyInstDef" +extern std::string EXPORT_IMPORT_PREFIX; +#define CLASS_PREFIX "Dtool_" +#define INSTANCE_PREFIX "Dtool_" +#define BASE_INSTANCE_NAME "Dtool_PyInstDef" ///////////////////////////////////////////////////////// -// Name Remaper... +// Name Remapper... // Snagged from ffi py code.... ///////////////////////////////////////////////////////// struct RenameSet { @@ -56,123 +54,129 @@ struct FlagSet { /////////////////////////////////////////////////////////////////////////////////////// RenameSet methodRenameDictionary[] = { - { "operator ==" , "eq", 0 }, - { "operator !=" , "ne", 0 }, - { "operator <<" , "__lshift__", 0 }, - { "operator >>" , "__rshift__", 0 }, - { "operator <" , "lessThan", 0 }, - { "operator >" , "greaterThan", 0 }, - { "operator <=" , "lessThanOrEqual", 0 }, - { "operator >=" , "greaterThanOrEqual", 0 }, - { "operator =" , "assign", 0 }, - { "operator ()" , "__call__", 0 }, - { "operator []" , "__getitem__", 0 }, - { "operator ++unary", "increment", 0 }, - { "operator ++" , "increment", 0 }, - { "operator --unary", "decrement", 0 }, - { "operator --" , "decrement", 0 }, - { "operator ^" , "__xor__", 0 }, - { "operator %" , "__mod__", 0 }, - { "operator !" , "logicalNot", 0 }, - { "operator ~unary", "__invert__", 0 }, - { "operator &" , "__and__", 0 }, - { "operator &&" , "logicalAnd", 0 }, - { "operator |" , "__or__", 0 }, - { "operator ||" , "logicalOr", 0 }, - { "operator +" , "__add__", 0 }, - { "operator -" , "__sub__", 0 }, - { "operator -unary", "__neg__", 0 }, - { "operator *" , "__mul__", 0 }, - { "operator /" , "__div__", 0 }, - { "operator +=" , "__iadd__", 1 }, - { "operator -=" , "__isub__", 1 }, - { "operator *=" , "__imul__", 1 }, - { "operator /=" , "__idiv__", 1 }, - { "operator ," , "concatenate", 0 }, - { "operator |=" , "__ior__", 1 }, - { "operator &=" , "__iand__", 1 }, - { "operator ^=" , "__ixor__", 1 }, - { "operator ~=" , "bitwiseNotEqual", 0 }, - { "operator ->" , "dereference", 0 }, - { "operator <<=" , "__ilshift__", 1 }, - { "operator >>=" , "__irshift__", 1 }, - { "operator typecast bool", "__nonzero__", 0 }, - { "__nonzero__" , "__nonzero__", 0 }, - { "__reduce__" , "__reduce__", 0 }, - { "__reduce_persist__" , "__reduce_persist__", 0 }, - { "__copy__" , "__copy__", 0 }, - { "__deepcopy__" , "__deepcopy__", 0 }, - { "print" , "Cprint", 0 }, - { "CInterval.set_t", "_priv__cSetT", 0 }, - { NULL, NULL, -1 } - }; - -const char * InPlaceSet[] = { - "__iadd__", - "__isub__", - "__imul__", - "__idiv__", - "__ior__", - "__iand__", - "__ixor__", - "__ilshift__", - "__irshift__", - NULL, - }; - + { "operator ==" , "__eq__", 0 }, + { "operator !=" , "__ne__", 0 }, + { "operator << " , "__lshift__", 0 }, + { "operator >>" , "__rshift__", 0 }, + { "operator <" , "__lt__", 0 }, + { "operator >" , "__gt__", 0 }, + { "operator <=" , "__le__", 0 }, + { "operator >=" , "__ge__", 0 }, + { "operator =" , "assign", 0 }, + { "operator ()" , "__call__", 0 }, + { "operator []" , "__getitem__", 0 }, + { "operator ++unary", "increment", 0 }, + { "operator ++" , "increment", 0 }, + { "operator --unary", "decrement", 0 }, + { "operator --" , "decrement", 0 }, + { "operator ^" , "__xor__", 0 }, + { "operator %" , "__mod__", 0 }, + { "operator !" , "logicalNot", 0 }, + { "operator ~unary", "__invert__", 0 }, + { "operator &" , "__and__", 0 }, + { "operator &&" , "logicalAnd", 0 }, + { "operator |" , "__or__", 0 }, + { "operator ||" , "logicalOr", 0 }, + { "operator +" , "__add__", 0 }, + { "operator -" , "__sub__", 0 }, + { "operator -unary", "__neg__", 0 }, + { "operator *" , "__mul__", 0 }, + { "operator /" , "__div__", 0 }, + { "operator +=" , "__iadd__", 1 }, + { "operator -=" , "__isub__", 1 }, + { "operator *=" , "__imul__", 1 }, + { "operator /=" , "__idiv__", 1 }, + { "operator ," , "concatenate", 0 }, + { "operator |=" , "__ior__", 1 }, + { "operator &=" , "__iand__", 1 }, + { "operator ^=" , "__ixor__", 1 }, + { "operator ~=" , "bitwiseNotEqual", 0 }, + { "operator ->" , "dereference", 0 }, + { "operator <<=" , "__ilshift__", 1 }, + { "operator >>=" , "__irshift__", 1 }, + { "operator typecast bool", "__nonzero__", 0 }, + { "__nonzero__" , "__nonzero__", 0 }, + { "__reduce__" , "__reduce__", 0 }, + { "__reduce_persist__", "__reduce_persist__", 0 }, + { "__copy__" , "__copy__", 0 }, + { "__deepcopy__" , "__deepcopy__", 0 }, + { "print" , "Cprint", 0 }, + { "CInterval.set_t", "_priv__cSetT", 0 }, + { "__bool__" , "__bool__", 0 }, + { "__bytes__" , "__bytes__", 0 }, + { NULL, NULL, -1 } +}; +const char *InPlaceSet[] = { + "__iadd__", + "__isub__", + "__imul__", + "__idiv__", + "__ior__", + "__iand__", + "__ixor__", + "__ilshift__", + "__irshift__", + "__itruediv__", + "__ifloordiv__", + "__imod__", + "__ipow__", + NULL, +}; /////////////////////////////////////////////////////////////////////////////////////// RenameSet classRenameDictionary[] = { // No longer used, now empty. - { NULL,NULL,-1 } - }; - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -const char * pythonKeywords[] = { - "and", - "del", - "for", - "is", - "raise", - "assert", - "elif", - "from", - "lambda", - "return", - "break", - "else", - "global", - "not", - "try", - "class", - "except", - "if", - "or", - "while", - "continue", - "exec", - "import", - "pass", - "def", - "finally", - "in", - "print", - NULL + { NULL, NULL, -1 } }; /////////////////////////////////////////////////////////////////////////////////////// -std::string checkKeyword(std::string & cppName) -{ - for(int x = 0; pythonKeywords[x] != NULL; x++) - { - if(cppName == pythonKeywords[x]) - { - return std::string("_")+cppName; - } +/////////////////////////////////////////////////////////////////////////////////////// +const char *pythonKeywords[] = { + "and", + "as", + "assert", + "break", + "class", + "continue", + "def", + "del", + "elif", + "else", + "except", + "exec", + "finally", + "for", + "from", + "global", + "if", + "import", + "in", + "is", + "lambda", + "nonlocal", + "not", + "or", + "pass", + "print", + "raise", + "return", + "try", + "while", + "with", + "yield", + NULL +}; + +/////////////////////////////////////////////////////////////////////////////////////// +std::string +checkKeyword(std::string &cppName) { + for (int x = 0; pythonKeywords[x] != NULL; x++) { + if (cppName == pythonKeywords[x]) { + return std::string("_") + cppName; } - return cppName; + } + return cppName; } /////////////////////////////////////////////////////////////////////////////////////// @@ -291,13 +295,14 @@ std::string methodNameFromCppName(InterfaceMaker::Function *func, const std::st /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -bool isInplaceFunction(InterfaceMaker::Function *func) -{ +bool isInplaceFunction(InterfaceMaker::Function *func) { std::string wname = methodNameFromCppName(func, "", false); - for(int x = 0; InPlaceSet[x] != NULL; x++) - if(InPlaceSet[x] == wname) + for (int x = 0; InPlaceSet[x] != NULL; x++) { + if (InPlaceSet[x] == wname) { return true; + } + } return false; } @@ -360,7 +365,7 @@ get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def) { return true; } - if (method_name == "operator <<") { + if (method_name == "operator << ") { def._answer_location = "tp_as_number->nb_lshift"; def._wrapper_type = WT_numeric_operator; return true; @@ -500,6 +505,14 @@ get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def) { } if (method_name == "__nonzero__") { + // Python 2 style. + def._answer_location = "tp_as_number->nb_nonzero"; + def._wrapper_type = WT_inquiry; + return true; + } + + if (method_name == "__bool__") { + // Python 3 style. def._answer_location = "tp_as_number->nb_nonzero"; def._wrapper_type = WT_inquiry; return true; @@ -535,9 +548,9 @@ get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def) { /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::GetValideChildClasses( std::map< std::string ,CastDetails > &answer, CPPStructType * inclass, const std::string &up_cast_seed, bool downcastposible) +void InterfaceMakerPythonNative::GetValideChildClasses(std::map &answer, CPPStructType *inclass, const std::string &up_cast_seed, bool downcastposible) { - if(inclass == NULL) + if (inclass == NULL) return; CPPStructType::Derivation::const_iterator bi; @@ -550,17 +563,17 @@ void InterfaceMakerPythonNative::GetValideChildClasses( std::map< std::string // if (base._vis <= V_public) // downcastposible = false; CPPStructType *base_type = TypeManager::resolve_type(base._base)->as_struct_type(); - if(base_type != NULL) + if (base_type != NULL) { std::string scoped_name = base_type->get_local_name(&parser); - if(answer.find(scoped_name) == answer.end()) + if (answer.find(scoped_name) == answer.end()) { answer[scoped_name]._can_downcast = downcastposible; answer[scoped_name]._to_class_name = scoped_name; answer[scoped_name]._structType = base_type; - if(base._is_virtual) + if (base._is_virtual) answer[scoped_name]._can_downcast = false; std::string local_up_cast("( "); @@ -583,31 +596,31 @@ void InterfaceMakerPythonNative::GetValideChildClasses( std::map< std::string /////////////////////////////////////////////////////////////////////////////// void InterfaceMakerPythonNative::WriteReturnInstance(ostream &out, int indent_level, std::string &return_expr, std::string &ows_memory_flag, const std::string &class_name, CPPType *ctype, bool inplace, const std::string &const_flag) { - if(inplace == true) + if (inplace == true) { - indent(out, indent_level)<<"Py_INCREF(self);\n"; - indent(out, indent_level)<<"return self;\n"; + indent(out, indent_level) << "Py_INCREF(self);\n"; + indent(out, indent_level) << "return self;\n"; } else { - indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; - indent(out, indent_level)<<"{\n"; - indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; - indent(out, indent_level)<<" return Py_None;\n"; - indent(out, indent_level)<<"}\n"; + indent(out, indent_level) << "if (" << return_expr<< " == NULL)\n"; + indent(out, indent_level) << "{\n"; + indent(out, indent_level) << " Py_INCREF(Py_None);\n"; + indent(out, indent_level) << " return Py_None;\n"; + indent(out, indent_level) << "}\n"; - if(IsPandaTypedObject(ctype->as_struct_type())) + if (IsPandaTypedObject(ctype->as_struct_type())) { std::string typestr = "(" + return_expr + ")->as_typed_object()->get_type_index()"; - indent(out, indent_level)<<"return DTool_CreatePyInstanceTyped((void *)" << return_expr <<"," << CLASS_PREFEX << make_safe_name(class_name) << ","<< ows_memory_flag << ", " << const_flag << ", " << typestr << ");\n"; + indent(out, indent_level) << "return DTool_CreatePyInstanceTyped((void *)" << return_expr << "," << CLASS_PREFIX << make_safe_name(class_name) << "," << ows_memory_flag << ", " << const_flag << ", " << typestr << ");\n"; } else { - // indent(out, indent_level)<< "if(" << return_expr <<"!= NULL)\n"; + // indent(out, indent_level) << "if (" << return_expr << "!= NULL)\n"; indent(out, indent_level) - <<"return DTool_CreatePyInstance((void *)" << return_expr <<"," << CLASS_PREFEX << make_safe_name(class_name) << ","<_itype.is_global() && isFunctionLegal(func)) - write_prototype_for(out_code, func); + if (!func->_itype.is_global() && isFunctionLegal(func)) + write_prototype_for (out_code, func); } */ Objects::iterator oi; - for (oi = _objects.begin(); oi != _objects.end(); ++oi) - { - Object *object = (*oi).second; - if(object->_itype.is_class() ||object->_itype.is_struct()) - { - if(isCppTypeLegal(object->_itype._cpptype)) - { - if(isExportThisRun(object->_itype._cpptype)) - { - write_prototypes_class(out_code,out_h,object); - } - else - //write_prototypes_class_external(out_code,object); - _external_imports.insert(make_safe_name(object->_itype.get_scoped_name())); - } + for (oi = _objects.begin(); oi != _objects.end(); ++oi) { + Object *object = (*oi).second; + if (object->_itype.is_class() || object->_itype.is_struct()) { + if (isCppTypeLegal(object->_itype._cpptype)) { + if (isExportThisRun(object->_itype._cpptype)) { + write_prototypes_class(out_code, out_h, object); + } else { + //write_prototypes_class_external(out_code,object); + _external_imports.insert(make_safe_name(object->_itype.get_scoped_name())); + } } + } } out_code << "//********************************************************************\n"; - out_code << "//*** prototypes for .. Extrernal Objects \n"; + out_code << "//*** prototypes for .. External Objects \n"; out_code << "//********************************************************************\n"; - for(std::set< std::string >::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) - out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" <<*ii <<";\n"; - + for (std::set::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) { + out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << *ii << ";\n"; + } inside_python_native = false; } @@ -703,31 +712,31 @@ void InterfaceMakerPythonNative::write_prototypes_class_external(ostream &out, O out << "//********************************************************************\n"; - out << "//*** prototypes for external.. " << class_name <<"\n"; + out << "//*** prototypes for external.. " << class_name << "\n"; out << "//********************************************************************\n"; - out << "typedef "<< c_class_name <<" "<< class_name <<"_localtype;\n"; - out << "Define_Module_Class_Forward("<< _def->module_name << ", "<< class_name << "," << class_name <<"_localtype,"<< classNameFromCppName(preferred_name, false) << ");\n"; + out << "typedef " << c_class_name << " " << class_name << "_localtype;\n"; + out << "Define_Module_Class_Forward(" << _def->module_name << ", " << class_name << "," << class_name << "_localtype," << classNameFromCppName(preferred_name, false) << ");\n"; } ///////////////////////////////////////// //////////////////////////////////////////////////// // Function : write_prototypes_class // ///////////////////////////////////////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::write_prototypes_class(ostream &out_code,ostream *out_h, Object * obj) +void InterfaceMakerPythonNative::write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) { std::string ClassName = make_safe_name(obj->_itype.get_scoped_name()); Functions::iterator fi; out_code << "//********************************************************************\n"; - out_code << "//*** prototypes for .. " << ClassName <<"\n"; + out_code << "//*** prototypes for .. " << ClassName << "\n"; out_code << "//********************************************************************\n"; /* for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { Function *func = (*fi); - write_prototype_for(out_code, func); + write_prototype_for (out_code, func); } */ @@ -736,12 +745,12 @@ void InterfaceMakerPythonNative::write_prototypes_class(ostream &out_code,ostrea { Function *func = (*fi); std::string fname = "int Dtool_Init_"+ClassName+"(PyObject *self, PyObject *args, PyObject *kwds)"; - write_prototype_for_name(out_code, obj, func,fname); + write_prototype_for_name(out_code, obj, func, fname); } */ - write_ClasseDeclarations(out_code,out_h,obj); + write_class_declarations(out_code, out_h, obj); } //////////////////////////////////////////////////////////////////// @@ -762,7 +771,7 @@ void InterfaceMakerPythonNative::write_functions(ostream &out) for (fi = _functions.begin(); fi != _functions.end(); ++fi) { Function *func = (*fi); - if(!func->_itype.is_global() && isFunctionLegal(func)) + if (!func->_itype.is_global() && isFunctionLegal(func)) write_function_for_top(out, NULL, func,""); } @@ -770,11 +779,11 @@ void InterfaceMakerPythonNative::write_functions(ostream &out) for (oi = _objects.begin(); oi != _objects.end(); ++oi) { Object *object = (*oi).second; - if(object->_itype.is_class() ||object->_itype.is_struct()) + if (object->_itype.is_class() ||object->_itype.is_struct()) { - if(isCppTypeLegal(object->_itype._cpptype)) - if(isExportThisRun(object->_itype._cpptype)) - write_ClasseDetails(out,object); + if (isCppTypeLegal(object->_itype._cpptype)) + if (isExportThisRun(object->_itype._cpptype)) + write_class_details(out,object); } } @@ -782,11 +791,11 @@ void InterfaceMakerPythonNative::write_functions(ostream &out) for (oi = _objects.begin(); oi != _objects.end(); ++oi) { Object *object = (*oi).second; - if(!object->_itype.get_outer_class()) + if (!object->_itype.get_outer_class()) { - if(object->_itype.is_class() ||object->_itype.is_struct()) - if(isCppTypeLegal(object->_itype._cpptype)) - if(isExportThisRun(object->_itype._cpptype)) + if (object->_itype.is_class() ||object->_itype.is_struct()) + if (isCppTypeLegal(object->_itype._cpptype)) + if (isExportThisRun(object->_itype._cpptype)) write_module_class(out,object); } } @@ -794,10 +803,10 @@ void InterfaceMakerPythonNative::write_functions(ostream &out) } //////////////////////////////////////////////////////////// -// Function : write_ClasseDetails +// Function : write_class_details //////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::write_ClasseDetails(ostream &out, Object * obj) -{ +void InterfaceMakerPythonNative:: +write_class_details(ostream &out, Object * obj) { Functions::iterator fi; //std::string cClassName = obj->_itype.get_scoped_name(); @@ -805,62 +814,56 @@ void InterfaceMakerPythonNative::write_ClasseDetails(ostream &out, Object * obj) std::string cClassName = obj->_itype.get_true_name(); out << "//********************************************************************\n"; - out << "//*** Functions for .. "<< cClassName <<" \n" ; + out << "//*** Functions for .. " << cClassName << " \n" ; out << "//********************************************************************\n"; - for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) - { - Function *func = (*fi); - if( (func)) - { - SlottedFunctionDef def; - get_slotted_function_def(obj, func, def); - - ostringstream GetThis; - GetThis << " "<_methods.begin(); fi != obj->_methods.end(); ++fi) { + Function *func = (*fi); + if (func) { + SlottedFunctionDef def; + get_slotted_function_def(obj, func, def); + + ostringstream GetThis; + GetThis << " " << cClassName << " *local_this = NULL;\n"; + GetThis << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName<< ", (void **)&local_this);\n"; + GetThis << " if (local_this == NULL) {\n"; + if (def._wrapper_type == WT_numeric_operator) { + // WT_numeric_operator means we must return NotImplemented, instead + // of raising an exception, if the this pointer doesn't + // match. This is for things like __sub__, which Python + // likes to call on the wrong-type objects. + GetThis << " Py_INCREF(Py_NotImplemented);\n"; + GetThis << " return Py_NotImplemented;\n"; + + } else { + // Other functions should raise an exception if the this + // pointer isn't set or is the wrong type. + GetThis << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n"; + GetThis << " return NULL;\n"; + } + GetThis << " }\n"; + write_function_for_top(out, obj, func, GetThis.str()); } - + } + // bool AnyLeganConstructors; - if(obj->_constructors.size() == 0) - { - std::string fname = "int Dtool_Init_"+ClassName+"(PyObject *self, PyObject *args, PyObject *kwds)"; - out << fname << "\n"; - out << "{\n"; - out << " PyErr_SetString(PyExc_TypeError, \"Error Can Not Init Constant Class (" << cClassName << ")\");\n"; - out << " return -1;\n" ; - out << "}\n"; + if (obj->_constructors.size() == 0) { + std::string fname = "int Dtool_Init_"+ClassName+"(PyObject *self, PyObject *args, PyObject *kwds)"; + out << fname << "\n"; + out << "{\n"; + out << " PyErr_SetString(PyExc_TypeError, \"Error Can Not Init Constant Class (" << cClassName << ")\");\n"; + out << " return -1;\n" ; + out << "}\n"; + + } else { + for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) { + Function *func = (*fi); + std::string fname = "int Dtool_Init_"+ClassName+"(PyObject *self, PyObject *args, PyObject *kwds)"; + write_function_for_name(out, obj, func,fname,"",ClassName); } - else - { - for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) - { - Function *func = (*fi); - std::string fname = "int Dtool_Init_"+ClassName+"(PyObject *self, PyObject *args, PyObject *kwds) "; - - write_function_for_name(out, obj, func,fname,"",ClassName); - } - } + } MakeSeqs::iterator msi; for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) { @@ -872,57 +875,54 @@ void InterfaceMakerPythonNative::write_ClasseDetails(ostream &out, Object * obj) std::map< string ,CastDetails >::iterator di; builder.get_type(TypeManager::unwrap(cpptype),false); GetValideChildClasses(details, cpptype->as_struct_type()); - for(di = details.begin(); di != details.end(); di++) - { - //InterrogateType ptype =idb->get_type(di->first); - if(di->second._is_legal_py_class && !isExportThisRun(di->second._structType)) - _external_imports.insert(make_safe_name(di->second._to_class_name)); - //out << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(di->second._to_class_name) <<";\n"; - } + for (di = details.begin(); di != details.end(); di++) { + //InterrogateType ptype =idb->get_type(di->first); + if (di->second._is_legal_py_class && !isExportThisRun(di->second._structType)) + _external_imports.insert(make_safe_name(di->second._to_class_name)); + //out << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(di->second._to_class_name) << ";\n"; + } { // the Cast Converter - out << "inline void * Dtool_UpcastInterface_"<< ClassName << "(PyObject *self, Dtool_PyTypedObject *requested_type)\n"; - out << "{\n"; + out << "inline void *Dtool_UpcastInterface_" << ClassName << "(PyObject *self, Dtool_PyTypedObject *requested_type) {\n"; out << " Dtool_PyTypedObject *SelfType = ((Dtool_PyInstDef *)self)->_My_Type;\n"; - out << " if(SelfType != &Dtool_" << ClassName <<")\n"; + out << " if (SelfType != &Dtool_" << ClassName << ")\n"; out << " {\n"; - out << " printf(\""<_My_Type->_name,requested_type->_name);fflush(NULL);\n";; + out << " printf(\"" << ClassName << " ** Bad Source Type-- Requesting Conversion from %s to %s\\n\", ((Dtool_PyInstDef *)self)->_My_Type->_name, requested_type->_name); fflush(NULL);\n";; out << " return NULL;\n"; out << " }\n"; out << " \n"; - out << " "<_ptr_to_object;\n"; - out << " if(requested_type == &Dtool_"<_ptr_to_object;\n"; + out << " if (requested_type == &Dtool_" << ClassName << ")\n"; out << " return local_this;\n"; - for(di = details.begin(); di != details.end(); di++) + for (di = details.begin(); di != details.end(); di++) { - if(di->second._is_legal_py_class) + if (di->second._is_legal_py_class) { - out << " if(requested_type == &Dtool_"<second._to_class_name)<<")\n"; - out << " return "<< di->second._up_cast_string << " local_this;\n"; + out << " if (requested_type == &Dtool_" <second._to_class_name) << ")\n"; + out << " return " << di->second._up_cast_string << " local_this;\n"; } } out << " return NULL;\n"; out << "}\n"; - out << "inline void * Dtool_DowncastInterface_"<< ClassName << "(void *from_this, Dtool_PyTypedObject *from_type)\n"; - out << "{\n"; - out << " if(from_this == NULL || from_type == NULL)\n"; + out << "inline void * Dtool_DowncastInterface_" << ClassName << "(void *from_this, Dtool_PyTypedObject *from_type) {\n"; + out << " if (from_this == NULL || from_type == NULL)\n"; out << " return NULL;\n"; - out << " if(from_type == &Dtool_" << ClassName<<")\n"; + out << " if (from_type == &Dtool_" << ClassName<< ")\n"; out << " return from_this;\n"; - for(di = details.begin(); di != details.end(); di++) + for (di = details.begin(); di != details.end(); di++) { - if(di->second._can_downcast && di->second._is_legal_py_class) + if (di->second._can_downcast && di->second._is_legal_py_class) { - out << " if(from_type == &Dtool_"<second._to_class_name)<<")\n"; + out << " if (from_type == &Dtool_" <second._to_class_name) << ")\n"; out << " {\n"; - out << " "<< di->second._to_class_name << "* other_this = ("<< di->second._to_class_name << "*)from_this;\n" ; - out << " return ("<< cClassName << "*)other_this;\n"; + out << " " << di->second._to_class_name << "* other_this = (" << di->second._to_class_name << "*)from_this;\n" ; + out << " return (" << cClassName << "*)other_this;\n"; out << " }\n"; } } @@ -933,47 +933,47 @@ void InterfaceMakerPythonNative::write_ClasseDetails(ostream &out, Object * obj) } //////////////////////////////////////////////////////////// -/// Function : write_ClasseDeclarations +/// Function : write_class_declarations // // //////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::write_ClasseDeclarations(ostream &out, ostream *out_h,Object * obj ) +void InterfaceMakerPythonNative::write_class_declarations(ostream &out, ostream *out_h,Object * obj ) { const InterrogateType &itype = obj->_itype; std::string class_name = make_safe_name(obj->_itype.get_scoped_name()); std::string c_class_name = obj->_itype.get_true_name(); std::string preferred_name = itype.get_name(); - std::string class_struct_name = std::string(CLASS_PREFEX) +class_name; + std::string class_struct_name = std::string(CLASS_PREFIX) +class_name; - out << "typedef "<< c_class_name <<" "<< class_name <<"_localtype;\n"; - if(obj->_itype.has_destructor() || + out << "typedef " << c_class_name << " " << class_name << "_localtype;\n"; + if (obj->_itype.has_destructor() || obj->_itype.destructor_is_inherited()) { - if(TypeManager::is_reference_count(obj->_itype._cpptype)) + if (TypeManager::is_reference_count(obj->_itype._cpptype)) { - out << "Define_Module_ClassRef("<< _def->module_name<<"," << class_name << "," << class_name <<"_localtype,"<< classNameFromCppName(preferred_name, false) <<");\n"; + out << "Define_Module_ClassRef(" << _def->module_name<< "," << class_name << "," << class_name << "_localtype," << classNameFromCppName(preferred_name, false) << ");\n"; } else { - out << "Define_Module_Class("<<_def->module_name << "," << class_name << "," <module_name << "," << class_name << "," <_itype._cpptype)) + if (TypeManager::is_reference_count(obj->_itype._cpptype)) { - out << "Define_Module_ClassRef_Private("<<_def->module_name << "," << class_name << "," << class_name <<"_localtype,"<< classNameFromCppName(preferred_name, false) <<");\n"; + out << "Define_Module_ClassRef_Private(" <<_def->module_name << "," << class_name << "," << class_name << "_localtype," << classNameFromCppName(preferred_name, false) << ");\n"; } else { - out << "Define_Module_Class_Private("<<_def->module_name<< "," << class_name << "," << class_name <<"_localtype,"<< classNameFromCppName(preferred_name, false) << ");\n"; + out << "Define_Module_Class_Private(" <<_def->module_name<< "," << class_name << "," << class_name << "_localtype," << classNameFromCppName(preferred_name, false) << ");\n"; } } - if(out_h != NULL) - *out_h << "extern \"C\" " << EXPORT_IMPORT_PREFEX << " struct Dtool_PyTypedObject Dtool_" << class_name <<";\n"; + if (out_h != NULL) + *out_h << "extern \"C\" " << EXPORT_IMPORT_PREFIX << " struct Dtool_PyTypedObject Dtool_" << class_name << ";\n"; } //////////////////////////////////////////////////////////////////// // Function: InterfaceMakerPythonNative::write_sub_module @@ -986,9 +986,9 @@ void InterfaceMakerPythonNative::write_sub_module(ostream &out, Object *obj) //Object * obj = _objects[_embeded_index] ; std::string ClassName = make_safe_name(obj->_itype.get_scoped_name()); out << "//********************************************************************\n"; - out << "//*** Module Init Updcall .." << obj->_itype.get_scoped_name() << "\n"; + out << "//*** Module Init Upcall .." << obj->_itype.get_scoped_name() << "\n"; out << "//********************************************************************\n"; - out << " Dtool_PyModuleClassInit_"<< ClassName <<"(module);\n"; + out << " Dtool_PyModuleClassInit_" << ClassName << "(module);\n"; } ///////////////////////////////////////////////////////////////////////////// // Function : write_module_support @@ -1005,25 +1005,25 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_ for (oi = _objects.begin(); oi != _objects.end(); ++oi) { Object *object = (*oi).second; - if(!object->_itype.get_outer_class()) + if (!object->_itype.get_outer_class()) { - if(object->_itype.is_enum()) + if (object->_itype.is_enum()) { int enum_count = object->_itype.number_of_enum_values(); - if(enum_count > 0) + if (enum_count > 0) { out << "//********************************************************************\n"; out << "//*** Module Enums .." << object->_itype.get_scoped_name() << "\n"; out << "//********************************************************************\n"; } - for(int xx = 0; xx< enum_count; xx++) { + for (int xx = 0; xx< enum_count; xx++) { string name1 = classNameFromCppName(object->_itype.get_enum_value_name(xx), false); string name2 = classNameFromCppName(object->_itype.get_enum_value_name(xx), true); int enum_value = object->_itype.get_enum_value(xx); - out << " PyModule_AddIntConstant(module,\"" << name1 <<"\","<< enum_value << ");\n"; + out << " PyModule_AddIntConstant(module,\"" << name1 << "\"," << enum_value << ");\n"; if (name1 != name2) { // Also write the mangled name, for historical purposes. - out << " PyModule_AddIntConstant(module,\"" << name2 <<"\","<< enum_value << ");\n"; + out << " PyModule_AddIntConstant(module,\"" << name2 << "\"," << enum_value << ");\n"; } } } @@ -1044,18 +1044,18 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_ string name1 = classNameFromCppName(iman.get_name(), false); string name2 = classNameFromCppName(iman.get_name(), true); - if(iman.has_int_value()) { + if (iman.has_int_value()) { int value = iman.get_int_value(); - out << " PyModule_AddIntConstant(module,\"" << name1 <<"\","<< value << ");\n"; + out << " PyModule_AddIntConstant(module,\"" << name1 << "\"," << value << ");\n"; if (name1 != name2) { // Also write the mangled name, for historical purposes. - out << " PyModule_AddIntConstant(module,\"" << name2 <<"\","<< value << ");\n"; + out << " PyModule_AddIntConstant(module,\"" << name2 << "\"," << value << ");\n"; } } else { string value = iman.get_definition(); - out << " PyModule_AddStringConstant(module,\"" << name1 <<"\",\""<< value << "\");\n"; + out << " PyModule_AddStringConstant(module,\"" << name1 << "\",\"" << value << "\");\n"; if (name1 != name2) { - out << " PyModule_AddStringConstant(module,\"" << name2 <<"\",\""<< value << "\");\n"; + out << " PyModule_AddStringConstant(module,\"" << name2 << "\",\"" << value << "\");\n"; } } } @@ -1063,20 +1063,20 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_ for (oi = _objects.begin(); oi != _objects.end(); ++oi) { Object *object = (*oi).second; - if(!object->_itype.get_outer_class()) + if (!object->_itype.get_outer_class()) { - if(object->_itype.is_class() ||object->_itype.is_struct()) - if(isCppTypeLegal(object->_itype._cpptype)) - if(isExportThisRun(object->_itype._cpptype)) + if (object->_itype.is_class() ||object->_itype.is_struct()) + if (isCppTypeLegal(object->_itype._cpptype)) + if (isExportThisRun(object->_itype._cpptype)) write_sub_module(out,object); } } out << "//********************************************************************\n"; - out << "//*** Module Init Updcall .. Externally Defined Class\n"; + out << "//*** Module Init Upcall .. Externally Defined Class\n"; out << "//********************************************************************\n"; -// for(std::set< std::string >::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) -// out << "Dtool_" <<*ii <<"._Dtool_ClassInit(NULL);\n"; +// for (std::set< std::string >::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) +// out << "Dtool_" <<*ii << "._Dtool_ClassInit(NULL);\n"; @@ -1089,63 +1089,74 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_ for (fi = _functions.begin(); fi != _functions.end(); ++fi) { Function *func = (*fi); - if(!func->_itype.is_global() && isFunctionLegal(func)) + if (!func->_itype.is_global() && isFunctionLegal(func)) { string name1 = methodNameFromCppName(func, "", false); string name2 = methodNameFromCppName(func, "", true); out << " { \"" << name1 << "\", (PyCFunction) &" - << func->_name << ", METH_VARARGS| METH_KEYWORDS, (char *)" << func->_name << "_comment},\n"; + << func->_name << ", METH_VARARGS | METH_KEYWORDS, (char *)" << func->_name << "_comment},\n"; if (name1 != name2) { out << " { \"" << name2 << "\", (PyCFunction) &" - << func->_name << ", METH_VARARGS| METH_KEYWORDS, (char *)" << func->_name << "_comment},\n"; + << func->_name << ", METH_VARARGS | METH_KEYWORDS, (char *)" << func->_name << "_comment},\n"; } } } - if(force_base_functions) + if (force_base_functions) { - out << " //Support Function For Dtool_types ... for now in each module ??\n"; + out << " // Support Function For Dtool_types ... for now in each module ??\n"; out << " {\"Dtool_BorrowThisReference\", &Dtool_BorrowThisReference,METH_VARARGS,\"Used to borrow 'this' pointer ( to, from)\\n Assumes no ownership\"}, \n"; out << " {\"Dtool_AddToDictionary\", &Dtool_AddToDictionary,METH_VARARGS,\"Used to add items into a tp_dict\"}, \n"; } - out << " { NULL, NULL ,0,NULL}\n" << "};\n\n"; + out << " {NULL, NULL, 0, NULL}\n" << "};\n\n"; - out << "struct LibrayDef " << moduledefdef->library_name <<"_moddef = {python_simple_funcs,BuildInstants};\n"; - if(out_h != NULL) - *out_h << "extern struct LibrayDef " << moduledefdef->library_name <<"_moddef;\n"; + out << "struct LibraryDef " << moduledefdef->library_name << "_moddef = {python_simple_funcs, BuildInstants};\n"; + if (out_h != NULL) + *out_h << "extern struct LibraryDef " << moduledefdef->library_name << "_moddef;\n"; } ///////////////////////////////////////////////////////////////////////////// ///// Function : write_module ///////////////////////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::write_module(ostream &out,ostream *out_h, InterrogateModuleDef *moduledefdef) -{ - InterfaceMakerPython::write_module(out,out_h, moduledefdef); - Objects::iterator oi; +void InterfaceMakerPythonNative:: +write_module(ostream &out,ostream *out_h, InterrogateModuleDef *moduledefdef) { + InterfaceMakerPython::write_module(out, out_h, moduledefdef); + Objects::iterator oi; - out << "//********************************************************************\n"; - out << "//*** Py Init Code For .. GlobalScope\n" ; - out << "//********************************************************************\n"; + out << "//********************************************************************\n"; + out << "//*** Py Init Code For .. GlobalScope\n" ; + out << "//********************************************************************\n"; - out << "#ifdef _WIN32\n" - << "extern \"C\" __declspec(dllexport) void init" << moduledefdef->module_name << "();\n" - << "#else\n" - << "extern \"C\" void init" << moduledefdef->module_name << "();\n" - << "#endif\n\n"; + out << "#if PY_MAJOR_VERSION >= 3\n" + << "#define INIT_FUNC PyObject *PyInit_" << moduledefdef->module_name << "\n" + << "#else\n" + << "#define INIT_FUNC void init" << moduledefdef->module_name << "\n" + << "#endif\n\n" - out << "void init" << moduledefdef->module_name << "() {\n"; - out << " LibrayDef * refs[] = {&" << moduledefdef->library_name << "_moddef,NULL};\n"; - out << " Dtool_PyModuleInitHelper(refs,\"" << moduledefdef->module_name << "\");\n"; - out << "}\n\n"; + << "#ifdef _WIN32\n" + << "extern \"C\" __declspec(dllexport) INIT_FUNC();\n" + << "#else\n" + << "extern \"C\" INIT_FUNC();\n" + << "#endif\n\n" + + << "INIT_FUNC() {\n" + << "PyObject *PyInit_" << moduledefdef->module_name << "() {\n" + << " LibraryDef *refs[] = {&" << moduledefdef->library_name << "_moddef, NULL};\n" + << "#if PY_MAJOR_VERSION >= 3\n" + << " return\n" + << "#endif\n" + << " Dtool_PyModuleInitHelper(refs, \"" << moduledefdef->module_name << "\");\n" + << "}\n\n"; } ///////////////////////////////////////////////////////////////////////////////////////////// // Function :write_module_class ///////////////////////////////////////////////////////////////////////////////////////////// void InterfaceMakerPythonNative:: -write_module_class(ostream &out, Object *obj) { +write_module_class(ostream &out, Object *obj) { bool has_local_hash = false; bool has_local_repr = false; bool has_local_str = false; + bool has_local_richcompare = false; { int num_nested = obj->_itype.number_of_nested_types(); @@ -1153,9 +1164,9 @@ write_module_class(ostream &out, Object *obj) { { TypeIndex nested_index = obj->_itype.get_nested_type(ni); Object * nested_obj = _objects[nested_index]; - if(nested_obj->_itype.is_class() ||nested_obj->_itype.is_struct()) + if (nested_obj->_itype.is_class() ||nested_obj->_itype.is_struct()) { - write_module_class(out,nested_obj); + write_module_class(out, nested_obj); } } } @@ -1169,12 +1180,12 @@ write_module_class(ostream &out, Object *obj) { Functions::iterator fi; out << "//********************************************************************\n"; - out << "//*** Py Init Code For .. "<< ClassName <<" | " << export_class_name <<"\n" ; + out << "//*** Py Init Code For .. " << ClassName << " | " << export_class_name << "\n" ; out << "//********************************************************************\n"; - out << "PyMethodDef Dtool_Methods_"<< ClassName << "[]= {\n"; + out << "PyMethodDef Dtool_Methods_" << ClassName << "[] = {\n"; - std::map static_functions; - std::map normal_Operator_functions; + std::map static_functions; + std::map normal_Operator_functions; std::map wraped_Operator_functions; // function Table bool got_copy = false; @@ -1198,11 +1209,11 @@ write_module_class(ostream &out, Object *obj) { string name1 = methodNameFromCppName(func, export_class_name, false); string name2 = methodNameFromCppName(func, export_class_name, true); out << " { \"" << name1 << "\",(PyCFunction ) &" - << func->_name << ", METH_VARARGS| METH_KEYWORDS, (char *)" << func->_name << "_comment},\n"; + << func->_name << ", METH_VARARGS | METH_KEYWORDS, (char *)" << func->_name << "_comment},\n"; ++x; if (name1 != name2) { out << " { \"" << name2 << "\",(PyCFunction ) &" - << func->_name << ", METH_VARARGS| METH_KEYWORDS, (char *)" << func->_name << "_comment},\n"; + << func->_name << ", METH_VARARGS | METH_KEYWORDS, (char *)" << func->_name << "_comment},\n"; ++x; } @@ -1257,43 +1268,39 @@ write_module_class(ostream &out, Object *obj) { for (di = 0; di < num_derivations; di++) { TypeIndex d_type_Index = obj->_itype.get_derivation(di); - if(!interrogate_type_is_unpublished(d_type_Index)) + if (!interrogate_type_is_unpublished(d_type_Index)) { const InterrogateType &d_itype = idb->get_type(d_type_Index); - if(isCppTypeLegal(d_itype._cpptype)) + if (isCppTypeLegal(d_itype._cpptype)) { - if(!isExportThisRun(d_itype._cpptype)) + if (!isExportThisRun(d_itype._cpptype)) { _external_imports.insert(make_safe_name(d_itype.get_scoped_name().c_str())); - //out << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(d_itype.get_scoped_name().c_str()) <<";\n"; + //out << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(d_itype.get_scoped_name().c_str()) << ";\n"; } } } } - std::vector< std::string > bases; - for (di = 0; di < num_derivations; di++) - { - TypeIndex d_type_Index = obj->_itype.get_derivation(di); - if(!interrogate_type_is_unpublished(d_type_Index)) - { - - const InterrogateType &d_itype = idb->get_type(d_type_Index); - if(isCppTypeLegal(d_itype._cpptype)) - { - bases.push_back(make_safe_name(d_itype.get_scoped_name().c_str())); - } - } + std::vector bases; + for (di = 0; di < num_derivations; di++) { + TypeIndex d_type_Index = obj->_itype.get_derivation(di); + if (!interrogate_type_is_unpublished(d_type_Index)) { + const InterrogateType &d_itype = idb->get_type(d_type_Index); + if (isCppTypeLegal(d_itype._cpptype)) { + bases.push_back(make_safe_name(d_itype.get_scoped_name().c_str())); + } } + } - if(bases.empty()) - bases.push_back("DTOOL_SUPPER_BASE"); - + if (bases.empty()) { + bases.push_back("DTOOL_SUPER_BASE"); + } { std::map::iterator rfi; // wraped_Operator_functions; - for(rfi = wraped_Operator_functions.begin(); rfi != wraped_Operator_functions.end(); rfi++) { + for (rfi = wraped_Operator_functions.begin(); rfi != wraped_Operator_functions.end(); rfi++) { switch (rfi->second._wrapper_type) { case WT_no_params: // PyObject *func(PyObject *self) @@ -1301,14 +1308,13 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static PyObject * " << func->_name << methodNameFromCppName(func,export_class_name, false) << "( PyObject * self)\n"; - out << "{\n"; - out << " PyObject *args = Py_BuildValue(\"()\");\n"; - out << " PyObject *result = " << func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " return result;\n"; + out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self) {\n"; + out << " PyObject *args = Py_BuildValue(\"()\");\n"; + out << " PyObject *result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " return result;\n"; out << "}\n\n"; } break; @@ -1320,14 +1326,13 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static PyObject *" << func->_name << methodNameFromCppName(func,export_class_name, false) << "(PyObject *self, PyObject *one)\n"; - out << "{\n"; - out << " PyObject *args = Py_BuildValue(\"(O)\", one);\n"; - out << " PyObject *result = " << func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " return result;\n"; + out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *one) {\n"; + out << " PyObject *args = Py_BuildValue(\"(O)\", one);\n"; + out << " PyObject *result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " return result;\n"; out << "}\n\n"; } break; @@ -1338,22 +1343,25 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static int " << func->_name << methodNameFromCppName(func,export_class_name, false) << "( PyObject * self, PyObject * one, PyObject * two)\n"; - out << "{\n"; - out << " PyObject *args;\n"; - out << " if (two == NULL) {\n"; - out << " args = Py_BuildValue(\"(O)\", one);\n"; - out << " } else {\n"; - out << " args = Py_BuildValue(\"(OO)\", one, two);\n"; - out << " }\n"; - out << " PyObject *py_result = " << func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " if (py_result == NULL) return -1;\n"; - out << " int result = PyInt_AsLong(py_result);\n"; - out << " Py_DECREF(py_result);\n"; - out << " return result;\n"; + out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *one, PyObject *two) {\n"; + out << " PyObject *args;\n"; + out << " if (two == NULL) {\n"; + out << " args = Py_BuildValue(\"(O)\", one);\n"; + out << " } else {\n"; + out << " args = Py_BuildValue(\"(OO)\", one, two);\n"; + out << " }\n"; + out << " PyObject *py_result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " if (py_result == NULL) return -1;\n"; + out << "#if PY_MAJOR_VERSION >= 3\n"; + out << " int result = PyLong_AsLong(py_result);\n"; + out << "#else\n"; + out << " int result = PyInt_AsLong(py_result);\n"; + out << "#endif\n"; + out << " Py_DECREF(py_result);\n"; + out << " return result;\n"; out << "}\n\n"; } break; @@ -1367,18 +1375,17 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static PyObject * " << func->_name << methodNameFromCppName(func,export_class_name, false) << "( PyObject * self, PyObject * one)\n"; - out << "{\n"; - out << " PyObject *args = Py_BuildValue(\"(O)\", one);\n"; - out << " PyObject *result = " << func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " if (result == NULL) {\n"; - out << " PyErr_Clear();\n"; - out << " return PyObject_GenericGetAttr(self, one);\n"; - out << " }\n"; - out << " return result;\n"; + out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *one) {\n"; + out << " PyObject *args = Py_BuildValue(\"(O)\", one);\n"; + out << " PyObject *result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " if (result == NULL) {\n"; + out << " PyErr_Clear();\n"; + out << " return PyObject_GenericGetAttr(self, one);\n"; + out << " }\n"; + out << " return result;\n"; out << "}\n\n"; } break; @@ -1389,14 +1396,13 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static PyObject * " << func->_name << methodNameFromCppName(func,export_class_name, false) << "( PyObject * self, Py_ssize_t index)\n"; - out << "{\n"; - out << " PyObject *args = Py_BuildValue(\"(i)\", index);\n"; - out << " PyObject *result = " << func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " return result;\n"; + out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, Py_ssize_t index) {\n"; + out << " PyObject *args = Py_BuildValue(\"(i)\", index);\n"; + out << " PyObject *result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " return result;\n"; out << "}\n\n"; } break; @@ -1407,18 +1413,17 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static int " << func->_name << methodNameFromCppName(func,export_class_name, false) << "( PyObject * self, Py_ssize_t index, PyObject *value)\n"; - out << "{\n"; - out << " PyObject *args = Py_BuildValue(\"(iO)\", index, value);\n"; - out << " PyObject *result = " << func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " if (result == NULL) {\n"; - out << " return -1;\n"; - out << " }\n"; - out << " Py_DECREF(result);\n"; - out << " return 0;\n"; + out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, Py_ssize_t index, PyObject *value) {\n"; + out << " PyObject *args = Py_BuildValue(\"(iO)\", index, value);\n"; + out << " PyObject *result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " if (result == NULL) {\n"; + out << " return -1;\n"; + out << " }\n"; + out << " Py_DECREF(result);\n"; + out << " return 0;\n"; out << "}\n\n"; } break; @@ -1429,19 +1434,22 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static Py_ssize_t " << func->_name << methodNameFromCppName(func,export_class_name, false) << "(PyObject *self)\n"; - out << "{\n"; - out << " PyObject *args = Py_BuildValue(\"()\");\n"; - out << " PyObject *result = "<< func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " if (result == NULL) {\n"; - out << " return -1;\n"; - out << " }\n"; - out << " Py_ssize_t num = PyInt_AsSsize_t(result);\n"; - out << " Py_DECREF(result);\n"; - out << " return num;\n"; + out << "static Py_ssize_t " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self) {\n"; + out << " PyObject *args = Py_BuildValue(\"()\");\n"; + out << " PyObject *result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " if (result == NULL) {\n"; + out << " return -1;\n"; + out << " }\n"; + out << "#if PY_MAJOR_VERSION >= 3\n"; + out << " Py_ssize_t num = PyLong_AsSsize_t(result);\n"; + out << "#else\n"; + out << " Py_ssize_t num = PyInt_AsSsize_t(result);\n"; + out << "#endif\n"; + out << " Py_DECREF(result);\n"; + out << " return num;\n"; out << "}\n\n"; } break; @@ -1452,18 +1460,17 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static int " << func->_name << methodNameFromCppName(func,export_class_name, false) << "( PyObject * self, PyObject * one, PyObject * two)\n"; - out << "{\n"; - out << " PyObject *args = Py_BuildValue(\"(OO)\", one, two);\n"; - out << " PyObject *result = " << func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " if (result == NULL) {\n"; - out << " return -1;\n"; - out << " }\n"; - out << " Py_DECREF(result);\n"; - out << " return 0;\n"; + out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *one, PyObject *two) {\n"; + out << " PyObject *args = Py_BuildValue(\"(OO)\", one, two);\n"; + out << " PyObject *result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " if (result == NULL) {\n"; + out << " return -1;\n"; + out << " }\n"; + out << " Py_DECREF(result);\n"; + out << " return 0;\n"; out << "}\n\n"; } break; @@ -1474,19 +1481,22 @@ write_module_class(ostream &out, Object *obj) { Function *func = rfi->first; out << "//////////////////\n"; out << "// A wrapper function to satisfy Python's internal calling conventions. \n"; - out << "// " <second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; + out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; out << "//////////////////\n"; - out << "static int " << func->_name << methodNameFromCppName(func,export_class_name, false) << "(PyObject *self)\n"; - out << "{\n"; - out << " PyObject *args = Py_BuildValue(\"()\");\n"; - out << " PyObject *result = " << func->_name <<"(self, args, NULL);\n"; - out << " Py_DECREF(args);\n"; - out << " if (result == NULL) {\n"; - out << " return -1;\n"; - out << " }\n"; - out << " int iresult = PyInt_AsLong(result);\n"; - out << " Py_DECREF(result);\n"; - out << " return iresult;\n"; + out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self) {\n"; + out << " PyObject *args = Py_BuildValue(\"()\");\n"; + out << " PyObject *result = " << func->_name << "(self, args, NULL);\n"; + out << " Py_DECREF(args);\n"; + out << " if (result == NULL) {\n"; + out << " return -1;\n"; + out << " }\n"; + out << "#if PY_MAJOR_VERSION >= 3\n"; + out << " int iresult = PyLong_AsLong(result);\n"; + out << "#else\n"; + out << " int iresult = PyInt_AsLong(result);\n"; + out << "#endif\n"; + out << " Py_DECREF(result);\n"; + out << " return iresult;\n"; out << "}\n\n"; } break; @@ -1500,114 +1510,169 @@ write_module_class(ostream &out, Object *obj) { if (!get_key.empty()) { out << "//////////////////\n"; out << "// A LocalHash(getKey) Function for this type\n"; - out << "// " <" << get_key << "();\n"; + out << "static Py_hash_t Dtool_HashKey_" <" << get_key << "();\n"; out << "}\n\n"; has_local_hash = true; } else { - if(bases.size() == 0) { + if (bases.size() == 0) { out << "//////////////////\n"; out << "// A LocalHash(This Pointer) Function for this type\n"; - out << "// " <_itype); - if(need_repr > 0) - { - out << "//////////////////\n"; - out << "// A __repr__ Function\n"; - out << "// " <output(os);\n"; - } else { - out << " local_this->python_repr(os, \"" - << classNameFromCppName(ClassName, false) << "\");\n"; - } - out << " std::string ss = os.str();\n"; - out << " return PyString_FromStringAndSize(ss.data(),ss.length());\n"; - out << "}\n"; - has_local_repr = true; + if (need_repr > 0) { + out << "//////////////////\n"; + out << "// A __repr__ function\n"; + out << "// " << ClassName << "\n"; + out << "//////////////////\n"; + out << "static PyObject *Dtool_Repr_" << ClassName << "(PyObject *self) {\n"; + out << " " << cClassName << " *local_this = NULL;\n"; + out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n"; + out << " if (local_this == NULL) {\n"; + out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n"; + out << " return NULL;\n"; + out << " }\n"; + out << " ostringstream os;\n"; + if (need_repr == 3) { + out << " _ext_" << ClassName << "_python_repr(local_this, os, \"" + << classNameFromCppName(ClassName, false) << "\");\n"; + } else if (need_repr == 2) { + out << " local_this->output(os);\n"; + } else { + out << " local_this->python_repr(os, \"" + << classNameFromCppName(ClassName, false) << "\");\n"; } + out << " std::string ss = os.str();\n"; + out << "#if PY_MAJOR_VERSION >= 3\n"; + out << " return PyUnicode_FromStringAndSize(ss.data(), ss.length());\n"; + out << "#else\n"; + out << " return PyString_FromStringAndSize(ss.data(), ss.length());\n"; + out << "#endif\n"; + out << "}\n\n"; + has_local_repr = true; + } int need_str = NeedsAStrFunction(obj->_itype); - if(need_str > 0) - { - out << "//////////////////\n"; - out << "// A __str__ Function\n"; - out << "// " <write(os,0);\n"; - else - out << " local_this->write(os);\n"; - out << " std::string ss = os.str();\n"; - out << " return PyString_FromStringAndSize(ss.data(),ss.length());\n"; - out << "}\n"; - has_local_str = true; + if (need_str > 0) { + out << "//////////////////\n"; + out << "// A __str__ function\n"; + out << "// " << ClassName << "\n"; + out << "//////////////////\n"; + out << "static PyObject *Dtool_Str_" << ClassName << "(PyObject *self) {\n"; + out << " " << cClassName << " *local_this = NULL;\n"; + out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n"; + out << " if (local_this == NULL) {\n"; + out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n"; + out << " return NULL;\n"; + out << " }\n"; + out << " ostringstream os;\n"; + if (need_str == 2) { + out << " local_this->write(os, 0);\n"; + } else { + out << " local_this->write(os);\n"; } - - + out << " std::string ss = os.str();\n"; + out << "#if PY_MAJOR_VERSION >= 3\n"; + out << " return PyUnicode_FromStringAndSize(ss.data(), ss.length());\n"; + out << "#else\n"; + out << " return PyString_FromStringAndSize(ss.data(), ss.length());\n"; + out << "#endif\n"; + out << "}\n\n"; + has_local_str = true; + } } + if (NeedsARichCompareFunction(obj->_itype)) { + //NB. It's a bit inefficient to first pack the 'other' arg into a tuple only to be + // parsed by PyArg_Parse again later, but there's no obvious other way to do it. + out << "//////////////////\n"; + out << "// A rich comparison function\n"; + out << "// " << ClassName << "\n"; + out << "//////////////////\n"; + out << "static PyObject *Dtool_RichCompare_" << ClassName << "(PyObject *self, PyObject *other, int op) {\n"; + out << " PyObject *args = PyTuple_Pack(1, other);\n"; + out << " PyObject *kwds = NULL;\n"; + out << " " << cClassName << " *local_this = NULL;\n"; + out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n"; + out << " if (local_this == NULL) {\n"; + out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n"; + out << " return NULL;\n"; + out << " }\n\n"; + out << " switch (op) {\n"; + for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { + std::set remaps; + Function *func = (*fi); + if (!func) { + continue; + } + // We only accept comparison operators that take one parameter (besides 'this'). + Function::Remaps::const_iterator ri; + for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { + FunctionRemap *remap = (*ri); + if (isRemapLegal(*remap) && remap->_has_this && remap->_parameters.size() == 2) { + remaps.insert(remap); + } + } + const string &fname = func->_ifunc.get_name(); + if (fname == "operator <") { + out << " case Py_LT:\n"; + } else if (fname == "operator <=") { + out << " case Py_LE:\n"; + } else if (fname == "operator ==") { + out << " case Py_EQ:\n"; + } else if (fname == "operator !=") { + out << " case Py_NE:\n"; + } else if (fname == "operator >") { + out << " case Py_GT:\n"; + } else if (fname == "operator >=") { + out << " case Py_GE:\n"; + } else { + continue; + } + ostringstream forward_decl; + string expected_params; + write_function_forset(out, obj, func, remaps, expected_params, 2, forward_decl, false); + out << " break;\n"; + has_local_richcompare = true; + } + out << " }\n"; + out << " Py_DECREF(args);\n"; + out << " Py_RETURN_NOTIMPLEMENTED;\n"; + out << "}\n\n"; + } - out << "void Dtool_PyModuleClassInit_" << ClassName << "(PyObject *module)\n"; + out << "void Dtool_PyModuleClassInit_" << ClassName << "(PyObject *module)\n"; out << "{\n"; out << " static bool initdone = false;\n"; - out << " if(!initdone)\n"; + out << " if (!initdone)\n"; out << " {\n"; out << " initdone = true;\n"; - // out << " memset(Dtool_"<< ClassName << ".As_PyTypeObject().tp_as_number,0,sizeof(PyNumberMethods));\n"; - // out << " memset(Dtool_"<< ClassName << ".As_PyTypeObject().tp_as_mapping,0,sizeof(PyMappingMethods));\n"; + // out << " memset(Dtool_" << ClassName << ".As_PyTypeObject().tp_as_number,0,sizeof(PyNumberMethods));\n"; + // out << " memset(Dtool_" << ClassName << ".As_PyTypeObject().tp_as_mapping,0,sizeof(PyMappingMethods));\n"; // out << " static Dtool_PyTypedObject *InheritsFrom[] = {"; // add doc string @@ -1622,143 +1687,151 @@ write_module_class(ostream &out, Object *obj) { } // add bases/// - if(bases.size() > 0) + if (bases.size() > 0) { out << " // Dependent Objects \n"; - std::string format1= ""; - std::string format2= ""; - for(std::vector< std::string >::iterator bi = bases.begin(); bi != bases.end(); bi++) + std::string format1 = ""; + std::string format2 = ""; + for (std::vector::iterator bi = bases.begin(); bi != bases.end(); bi++) { format1 += "O"; - format2 += ",&Dtool_" + *bi + ".As_PyTypeObject()"; - out << " Dtool_"<< make_safe_name(*bi) << "._Dtool_ClassInit(NULL);\n"; + format2 += ", &Dtool_" + *bi + ".As_PyTypeObject()"; + out << " Dtool_" << make_safe_name(*bi) << "._Dtool_ClassInit(NULL);\n"; } - out << " Dtool_"<::iterator ofi; - for(ofi = normal_Operator_functions.begin(); ofi != normal_Operator_functions.end(); ofi++) + for (ofi = normal_Operator_functions.begin(); ofi != normal_Operator_functions.end(); ofi++) { Function *func = ofi->first; - out << " // " << ofi->second <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; - out << " Dtool_" << ClassName <<".As_PyTypeObject()." << ofi->second <<" = &" << func->_name <<";\n"; + out << " // " << ofi->second << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; + out << " Dtool_" << ClassName << ".As_PyTypeObject()." << ofi->second << " = &" << func->_name << ";\n"; } - // wraped functions... + // wrapped functions... { std::map::iterator rfi; // wraped_Operator_functions; - for(rfi = wraped_Operator_functions.begin(); rfi != wraped_Operator_functions.end(); rfi++) + for (rfi = wraped_Operator_functions.begin(); rfi != wraped_Operator_functions.end(); rfi++) { Function *func = rfi->first; - out << " // " << rfi->second._answer_location <<" = "<< methodNameFromCppName(func,export_class_name, false) <<"\n"; - out << " Dtool_" << ClassName <<".As_PyTypeObject()." << rfi->second._answer_location <<" = &" << func->_name << methodNameFromCppName(func,export_class_name, false)<<";\n"; + out << " // " << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n"; + out << " Dtool_" << ClassName << ".As_PyTypeObject()." << rfi->second._answer_location << " = &" << func->_name << methodNameFromCppName(func, export_class_name, false) << ";\n"; } } // compare and hash work together in PY inherit behavior hmm grrr // __hash__ - if(has_local_hash == true) - { - out << " // __hash__\n"; - out << " Dtool_" << ClassName <<".As_PyTypeObject().tp_hash = &DTool_HashKey_"<= 3\n"; + if (!has_local_richcompare) { + out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_richcompare = &DTOOL_PyObject_RichCompare;\n"; } + out << "#else\n"; + out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_compare = &DTOOL_PyObject_Compare;\n"; + out << "#endif\n"; + } - if(has_local_repr == true) - { - out << " // __repr__\n"; - out << " Dtool_" << ClassName <<".As_PyTypeObject().tp_repr = & Dtool_Repr_"<_itype.number_of_nested_types(); for (int ni = 0; ni < num_nested; ni++) { TypeIndex nested_index = obj->_itype.get_nested_type(ni); Object * nested_obj = _objects[nested_index]; - if(nested_obj->_itype.is_class() ||nested_obj->_itype.is_struct()) + if (nested_obj->_itype.is_class() ||nested_obj->_itype.is_struct()) { std::string ClassName1 = make_safe_name(nested_obj->_itype.get_scoped_name()); std::string ClassName2 = make_safe_name(nested_obj->_itype.get_name()); - out << " // Nested Object "<< ClassName1 << ";\n"; + out << " // Nested Object " << ClassName1 << ";\n"; out << " Dtool_" << ClassName1 << "._Dtool_ClassInit(NULL);\n"; string name1 = classNameFromCppName(ClassName2, false); string name2 = classNameFromCppName(ClassName2, true); - out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict,\"" << name1 <<"\",(PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n"; + out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name1 << "\", (PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n"; if (name1 != name2) { - out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict,\"" << name2 <<"\",(PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n"; + out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name2 << "\", (PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n"; } } else { - if(nested_obj->_itype.is_enum()) + if (nested_obj->_itype.is_enum()) { - out << " // Enum "<< nested_obj->_itype.get_scoped_name() << ";\n"; + out << " // Enum " << nested_obj->_itype.get_scoped_name() << ";\n"; int enum_count = nested_obj->_itype.number_of_enum_values(); - for(int xx = 0; xx< enum_count; xx++) { + for (int xx = 0; xx< enum_count; xx++) { string name1 = classNameFromCppName(nested_obj->_itype.get_enum_value_name(xx), false); string name2 = classNameFromCppName(nested_obj->_itype.get_enum_value_name(xx), true); int enum_value = nested_obj->_itype.get_enum_value(xx); - out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict,\"" << name1 <<"\",PyInt_FromLong("<< enum_value << "));\n"; + out << "#if PY_MAJOR_VERSION >= 3\n"; + out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name1 << "\", PyLong_FromLong(" << enum_value << "));\n"; if (name1 != name2) { - out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict,\"" << name2 <<"\",PyInt_FromLong("<< enum_value << "));\n"; + out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name2 << "\", PyLong_FromLong(" << enum_value << "));\n"; } + out << "#else\n"; + out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name1 << "\", PyInt_FromLong(" << enum_value << "));\n"; + if (name1 != name2) { + out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name2 << "\", PyInt_FromLong(" << enum_value << "));\n"; + } + out << "#endif\n"; } } } } - out << " if(PyType_Ready(&Dtool_"<< ClassName << ".As_PyTypeObject()) < 0)\n"; + out << " if (PyType_Ready(&Dtool_" << ClassName << ".As_PyTypeObject()) < 0)\n"; out << " {\n"; - out << " PyErr_SetString(PyExc_TypeError, \"PyType_Ready("<< ClassName << ")\");\n"; + out << " PyErr_SetString(PyExc_TypeError, \"PyType_Ready(" << ClassName << ")\");\n"; out << " printf(\" Error In PyType_Ready" << ClassName << "\");\n"; out << " return;\n"; out << " }\n"; - out << " Py_INCREF(&Dtool_"<< ClassName << ".As_PyTypeObject());\n"; + out << " Py_INCREF(&Dtool_" << ClassName << ".As_PyTypeObject());\n"; // Why make the class a member of itself? - //out << " PyDict_SetItemString(Dtool_"<::iterator sfi; - for(sfi= static_functions.begin(); sfi != static_functions.end(); sfi++) + for (sfi= static_functions.begin(); sfi != static_functions.end(); sfi++) { - out << " // Static Method " << methodNameFromCppName(sfi->second,export_class_name, false) << "\n"; - string name1 = methodNameFromCppName(sfi->second,export_class_name, false); - string name2 = methodNameFromCppName(sfi->second,export_class_name, true); + out << " // Static Method " << methodNameFromCppName(sfi->second, export_class_name, false) << "\n"; + string name1 = methodNameFromCppName(sfi->second, export_class_name, false); + string name2 = methodNameFromCppName(sfi->second, export_class_name, true); out << " PyDict_SetItemString(Dtool_" << ClassName - << ".As_PyTypeObject().tp_dict,\"" << name1 - << "\",PyCFunction_New(&Dtool_Methods_"<< ClassName <<"[" << sfi->first - << "],&Dtool_"<< ClassName<< ".As_PyObject()));\n"; + << ".As_PyTypeObject().tp_dict, \"" << name1 + << "\",PyCFunction_New(&Dtool_Methods_" << ClassName << "[" << sfi->first + << "], &Dtool_" << ClassName<< ".As_PyObject()));\n"; if (name1 != name2) { out << " PyDict_SetItemString(Dtool_" << ClassName - << ".As_PyTypeObject().tp_dict,\"" << name2 - << "\",PyCFunction_New(&Dtool_Methods_"<< ClassName <<"[" << sfi->first - << "],&Dtool_"<< ClassName<< ".As_PyObject()));\n"; + << ".As_PyTypeObject().tp_dict, \"" << name2 + << "\",PyCFunction_New(&Dtool_Methods_" << ClassName << "[" << sfi->first + << "], &Dtool_" << ClassName<< ".As_PyObject()));\n"; } } @@ -1767,19 +1840,19 @@ write_module_class(ostream &out, Object *obj) { is_runtime_typed = true; } - if(is_runtime_typed) - out << " RegisterRuntimeClass(&Dtool_"<_itype.get_alt_name(i)); if (export_class_name != alt_name) { - out << " PyModule_AddObject(module, \"" << alt_name << "\",(PyObject *)&Dtool_"<< ClassName << ".As_PyTypeObject());\n"; + out << " PyModule_AddObject(module, \"" << alt_name << "\", (PyObject *)&Dtool_" << ClassName << ".As_PyTypeObject());\n"; } } @@ -1826,8 +1899,8 @@ get_wrapper_prefix() { // symbolic names, which are not necessarily C-callable // function names. //////////////////////////////////////////////////////////////////// -string InterfaceMakerPythonNative::get_unique_prefix() -{ +string InterfaceMakerPythonNative:: +get_unique_prefix() { return "Dtool_"; } @@ -1837,8 +1910,8 @@ string InterfaceMakerPythonNative::get_unique_prefix() // Description: Associates the function wrapper with its function in // the appropriate structures in the database. //////////////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::record_function_wrapper(InterrogateFunction &ifunc, FunctionWrapperIndex wrapper_index) -{ +void InterfaceMakerPythonNative:: +record_function_wrapper(InterrogateFunction &ifunc, FunctionWrapperIndex wrapper_index) { ifunc._python_wrappers.push_back(wrapper_index); } @@ -1847,18 +1920,16 @@ void InterfaceMakerPythonNative::record_function_wrapper(InterrogateFunction &if // Access: Private // Description: Writes the prototype for the indicated function. //////////////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::write_prototype_for(ostream &out, InterfaceMaker::Function *func) -{ - std::string fname = "PyObject *"+func->_name+"(PyObject *self, PyObject *args)"; - - - write_prototype_for_name(out,func,fname); +void InterfaceMakerPythonNative:: +write_prototype_for(ostream &out, InterfaceMaker::Function *func) { + std::string fname = "PyObject *" + func->_name + "(PyObject *self, PyObject *args)"; + write_prototype_for_name(out, func, fname); } //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::write_prototype_for_name(ostream &out, InterfaceMaker::Function *func, const std::string &function_namename) -{ +void InterfaceMakerPythonNative:: +write_prototype_for_name(ostream &out, InterfaceMaker::Function *func, const std::string &function_namename) { Function::Remaps::const_iterator ri; // for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { @@ -1870,7 +1941,7 @@ void InterfaceMakerPythonNative::write_prototype_for_name(ostream &out, Interfac } else { out << "extern \"C\" "; } - out << function_namename <<";\n"; + out << function_namename << ";\n"; // } } @@ -1880,11 +1951,11 @@ void InterfaceMakerPythonNative::write_prototype_for_name(ostream &out, Interfac // Description: Writes the definition for a function that will call // the indicated C++ function or method. //////////////////////////////////////////////////////////////////// -void InterfaceMakerPythonNative::write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker::Function *func, const std::string &PreProcess) -{ - std::string fname = "static PyObject *"+func->_name+"(PyObject *self, PyObject *args,PyObject *kwds)"; +void InterfaceMakerPythonNative:: +write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker::Function *func, const std::string &PreProcess) { + std::string fname = "static PyObject *" + func->_name + "(PyObject *self, PyObject *args, PyObject *kwds)"; - write_function_for_name(out,obj,func,fname,PreProcess,""); + write_function_for_name(out, obj, func, fname, PreProcess, ""); } //////////////////////////////////////////////////////////////////// @@ -1900,10 +1971,9 @@ write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMak ostringstream forward_decl; ostringstream out; - std::map > MapSets; - std::map >::iterator mii; - std::set::iterator sii; - + std::map > MapSets; + std::map >::iterator mii; + std::set::iterator sii; Function::Remaps::const_iterator ri; out1 << "/******************************************************************\n" << " * Python type method wrapper for\n"; @@ -1911,7 +1981,7 @@ write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMak FunctionRemap *remap = (*ri); if (isRemapLegal(*remap)) { int parameter_size = remap->_parameters.size(); - if(remap->_has_this && remap->_type != FunctionRemap::T_constructor) + if (remap->_has_this && remap->_type != FunctionRemap::T_constructor) parameter_size --; MapSets[parameter_size].insert(remap); @@ -1949,33 +2019,30 @@ write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMak if (MapSets.size() > 1) { string expected_params; - indent(out,4) << "int parameter_count = 1;\n"; - indent(out,4) << "if(PyTuple_Check(args))\n"; - indent(out,4) << "{\n"; - indent(out,4) << " parameter_count = PyTuple_Size(args);\n" ; - indent(out,4) << " if(kwds != NULL && PyDict_Check(kwds))\n"; - indent(out,4) << " parameter_count += PyDict_Size(kwds);\n" ; - indent(out,4) << "}\n"; + indent(out, 2) << "int parameter_count = 1;\n"; + indent(out, 2) << "if (PyTuple_Check(args)) {\n"; + indent(out, 2) << " parameter_count = PyTuple_Size(args);\n"; + indent(out, 2) << " if (kwds != NULL && PyDict_Check(kwds)) {\n"; + indent(out, 2) << " parameter_count += PyDict_Size(kwds);\n"; + indent(out, 2) << " }\n"; + indent(out, 2) << "}\n"; - indent(out,4) << "switch(parameter_count)\n"; - indent(out,4) << "{\n"; + indent(out, 2) << "switch (parameter_count) {\n"; for (mii = MapSets.begin(); mii != MapSets.end(); mii ++) { - indent(out,4) << "case(" << mii->first << "):\n"; - indent(out,8) << "{\n"; - - write_function_forset(out,obj,func,mii->second,expected_params,8,forward_decl,ClassName + function_name, is_inplace); + indent(out, 2) << "case " << mii->first << ": {\n"; + + write_function_forset(out, obj, func, mii->second, expected_params, 4, forward_decl, is_inplace); if ((*mii->second.begin())->_type == FunctionRemap::T_constructor) { constructor = true; } - - - indent(out,8)<< "}\n"; - indent(out,8)<< "break;\n"; - } + + indent(out, 4) << "}\n"; + indent(out, 4) << "break;\n"; + } - indent(out,4)<< "default:\n"; - indent(out,8)<< "{\n"; - indent(out,12) + indent(out, 2) << "default:\n"; + indent(out, 4) << "{\n"; + indent(out, 6) << "PyErr_Format(PyExc_TypeError, \"" << methodNameFromCppName(func, "", false) << "() takes "; @@ -2003,47 +2070,48 @@ write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMak out << " arguments (%d given)\", parameter_count + " << add_self << ");\n"; if (constructor) - indent(out,12) << "return -1;\n"; + indent(out, 6) << "return -1;\n"; else - indent(out,12) << "return (PyObject *) NULL; \n"; + indent(out, 6) << "return (PyObject *) NULL; \n"; - indent(out,8)<< "}\n"; - indent(out,8)<< "break;\n"; - indent(out,4)<< "}\n"; + indent(out, 4) << "}\n"; + indent(out, 4) << "break;\n"; + indent(out, 2) << "}\n"; - out << " if(!PyErr_Occurred()) // let error pass on \n"; - out << " PyErr_SetString(PyExc_TypeError, \n"; - out << " \"Arguments must match one of:\\n\"\n"; - output_quoted(out, 10, expected_params); + out << " if (!PyErr_Occurred()) // let error pass on \n"; + out << " PyErr_SetString(PyExc_TypeError, \n"; + out << " \"Arguments must match one of:\\n\"\n"; + output_quoted(out, 6, expected_params); out << ");\n"; if (constructor) - indent(out,4) << "return -1;\n"; + indent(out, 2) << "return -1;\n"; else - indent(out,4) << "return (PyObject *) NULL; \n"; + indent(out, 2) << "return (PyObject *) NULL;\n"; - if(!expected_params.empty() && FunctionComment1.empty()) + if (!expected_params.empty() && FunctionComment1.empty()) FunctionComment1 += "C++ Interface:\n"; FunctionComment1 += expected_params; } else { string expected_params = ""; - for (mii = MapSets.begin(); mii != MapSets.end(); mii ++) { - write_function_forset(out,obj,func,mii->second,expected_params,4,forward_decl,ClassName + function_name,is_inplace); - if((*mii->second.begin())->_type == FunctionRemap::T_constructor) { + for (mii = MapSets.begin(); mii != MapSets.end(); mii++) { + write_function_forset(out, obj, func, mii->second, expected_params, 2, forward_decl, is_inplace); + if ((*mii->second.begin())->_type == FunctionRemap::T_constructor) { constructor = true; } } - out << " if(!PyErr_Occurred())\n"; - out << " PyErr_SetString(PyExc_TypeError,\n"; - out << " \"Must Match :\\n\"\n"; - output_quoted(out, 10, expected_params); - out << ");\n"; + out << " if (!PyErr_Occurred()) {\n"; + out << " PyErr_SetString(PyExc_TypeError,\n"; + out << " \"Arguments must match:\\n\"\n"; + output_quoted(out, 6, expected_params); + out << " );\n"; + out << " }\n"; if (constructor) - indent(out,4) << "return -1;\n"; + indent(out, 2) << "return -1;\n"; else - indent(out,4) << "return (PyObject *) NULL; \n"; + indent(out, 2) << "return (PyObject *) NULL; \n"; if (!expected_params.empty() && FunctionComment1.empty()) { FunctionComment1 += "C++ Interface:\n"; @@ -2064,7 +2132,7 @@ write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMak // constructor doc string. out << "#ifndef NDEBUG\n"; out << "static const char * " << func->_name << "_comment =\n"; - output_quoted(out, 4, FunctionComment); + output_quoted(out, 2, FunctionComment); out << ";\n"; out << "#else\n"; out << "static const char * " << func->_name << "_comment = NULL;\n"; @@ -2083,7 +2151,7 @@ write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMak // // Support Function used to Sort the name based overrides.. For know must be complex to simple //////////////////////////////////////////////////////// -int GetParnetDepth(CPPType *type) +int GetParnetDepth(CPPType *type) { int answer = 0; // printf(" %s\n",type->get_local_name().c_str()); @@ -2106,7 +2174,7 @@ int GetParnetDepth(CPPType *type) InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); - if(itype.is_class() ||itype.is_struct()) + if (itype.is_class() ||itype.is_struct()) { int num_derivations = itype.number_of_derivations(); @@ -2115,7 +2183,7 @@ int GetParnetDepth(CPPType *type) TypeIndex d_type_Index = itype.get_derivation(di); const InterrogateType &d_itype = idb->get_type(d_type_Index); int this_one = GetParnetDepth(d_itype._cpptype); - if(this_one > deepest) + if (this_one > deepest) deepest = this_one; } } @@ -2130,20 +2198,20 @@ int GetParnetDepth(CPPType *type) //////////////////////////////////////////////////////// // The Core sort function for remap calling orders.. ////////////////////////////////////////////////////////// -int RemapCompareLesss(FunctionRemap * in1 , FunctionRemap * in2) +int RemapCompareLess(FunctionRemap * in1 , FunctionRemap * in2) { - if(in1->_parameters.size() != in2->_parameters.size()) + if (in1->_parameters.size() != in2->_parameters.size()) return (in1->_parameters.size() > in2->_parameters.size()); int pcount = in1->_parameters.size(); - for(int x = 0; x< pcount; x++) + for (int x = 0; x< pcount; x++) { CPPType *orig_type1 = in1->_parameters[x]._remap->get_orig_type(); CPPType *orig_type2 = in2->_parameters[x]._remap->get_orig_type(); int pd1 = GetParnetDepth(orig_type1); int pd2 = GetParnetDepth(orig_type2); - if(pd1 != pd2) + if (pd1 != pd2) return pd1> pd2; } @@ -2151,20 +2219,21 @@ int RemapCompareLesss(FunctionRemap * in1 , FunctionRemap * in2) return false; } + ////////////////////////////////////////////////////////// // Convience for the sort behavior.. /////////////////////////////////////////////////////////// -std::vector< FunctionRemap * > SortFunctionSet(std::set< FunctionRemap *> &remaps) -{ - std::vector< FunctionRemap * > out; - for(std::set< FunctionRemap *>::iterator ii = remaps.begin(); ii!= remaps.end(); ii++) - out.push_back(*ii); +std::vector +SortFunctionSet(std::set &remaps) { + std::vector out; + for (std::set::iterator ii = remaps.begin(); ii!= remaps.end(); ii++) { + out.push_back(*ii); + } - - std::sort(out.begin(), out.end(), RemapCompareLesss); - - return out; + std::sort(out.begin(), out.end(), RemapCompareLess); + return out; } + /////////////////////////////////////////////////////////// // Function : write_function_forset // @@ -2173,10 +2242,9 @@ std::vector< FunctionRemap * > SortFunctionSet(std::set< FunctionRemap *> &rema void InterfaceMakerPythonNative:: write_function_forset(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker::Function *func, - std::set< FunctionRemap *> &remapsin, + std::set &remapsin, string &expected_params, int indent_level, - ostream &forward_decl, const std::string &functionname, - bool is_inplace) { + ostream &forward_decl, bool is_inplace) { // Do we accept any parameters that are class objects? If so, we // might need to check for parameter coercion. bool coercion_possible = false; @@ -2212,13 +2280,13 @@ write_function_forset(ostream &out, InterfaceMaker::Object *obj, indent(out, indent_level) << "{\n"; indent_level += 2; - indent(out,indent_level) + indent(out, indent_level) << "PyObject *coerced = NULL;\n"; - indent(out,indent_level) + indent(out, indent_level) << "PyObject **coerced_ptr = NULL;\n"; - indent(out,indent_level) + indent(out, indent_level) << "bool report_errors = false;\n"; - indent(out,indent_level) + indent(out, indent_level) << "while (true) {\n"; indent_level += 2; } @@ -2232,31 +2300,31 @@ write_function_forset(ostream &out, InterfaceMaker::Object *obj, std::vector::iterator sii; for (sii = remaps.begin(); sii != remaps.end(); sii ++) { FunctionRemap *remap = (*sii); - if(isRemapLegal(*remap)) { + if (isRemapLegal(*remap)) { if (remap->_has_this && !remap->_const_method) { // If it's a non-const method, we only allow a // non-const this. - indent(out,indent_level) + indent(out, indent_level) << "if (!((Dtool_PyInstDef *)self)->_is_const) {\n"; } else { indent(out, indent_level) << "{\n"; } - indent(out,indent_level) << " // -2 " ; - remap->write_orig_prototype(out, 0); out << "\n" ; + indent(out, indent_level) << "// -2 "; + remap->write_orig_prototype(out, 0); out << "\n"; - write_function_instance(out, obj, func, remap,expected_params,indent_level+4,false,forward_decl, func->_name, is_inplace, coercion_possible); + write_function_instance(out, obj, func, remap, expected_params, indent_level + 2, false, forward_decl, func->_name, is_inplace, coercion_possible); - indent(out,indent_level+4)<< "PyErr_Clear(); \n"; - indent(out,indent_level)<< "}\n\n"; + indent(out, indent_level + 2) << "PyErr_Clear(); \n"; + indent(out, indent_level) << "}\n\n"; } } } else { // There is only one possible overload with this number of // parameters. Just call it. std::set::iterator sii; - for(sii = remapsin.begin(); sii != remapsin.end(); sii ++) { + for (sii = remapsin.begin(); sii != remapsin.end(); sii ++) { FunctionRemap *remap = (*sii); if (isRemapLegal(*remap)) { if (remap->_has_this && !remap->_const_method) { @@ -2269,11 +2337,11 @@ write_function_forset(ostream &out, InterfaceMaker::Object *obj, << "{\n"; } - indent(out,indent_level + 2) + indent(out, indent_level + 2) << "// 1-" ; remap->write_orig_prototype(out, 0); out << "\n" ; - write_function_instance(out, obj, func, remap,expected_params,indent_level+4,true,forward_decl, func->_name, is_inplace, coercion_possible); + write_function_instance(out, obj, func, remap, expected_params, indent_level + 2, true, forward_decl, func->_name, is_inplace, coercion_possible); if (remap->_has_this && !remap->_const_method) { indent(out, indent_level) @@ -2288,10 +2356,10 @@ write_function_forset(ostream &out, InterfaceMaker::Object *obj, << "() on a const object.\");\n"; indent(out, indent_level + 2) << "return (PyObject *) NULL;\n"; - indent(out,indent_level) + indent(out, indent_level) << "}\n\n"; } else { - indent(out,indent_level) + indent(out, indent_level) << "}\n\n"; } } @@ -2302,43 +2370,42 @@ write_function_forset(ostream &out, InterfaceMaker::Object *obj, if (coercion_possible) { // Try again, this time with coercion enabled. - indent(out,indent_level) + indent(out, indent_level) << "if (coerced_ptr == NULL && !report_errors) {\n"; - indent(out,indent_level + 2) + indent(out, indent_level + 2) << "coerced_ptr = &coerced;\n"; - indent(out,indent_level + 2) + indent(out, indent_level + 2) << "continue;\n"; - indent(out,indent_level) + indent(out, indent_level) << "}\n"; // No dice. Go back one more time, and this time get the error // message. - indent(out,indent_level) + indent(out, indent_level) << "if (!report_errors) {\n"; - indent(out,indent_level + 2) + indent(out, indent_level + 2) << "report_errors = true;\n"; - indent(out,indent_level + 2) + indent(out, indent_level + 2) << "continue;\n"; - indent(out,indent_level) + indent(out, indent_level) << "}\n"; // We've been through three times. We're done. - indent(out,indent_level) + indent(out, indent_level) << "break;\n"; indent_level -= 2; - indent(out,indent_level) + indent(out, indent_level) << "}\n"; - indent(out,indent_level) + indent(out, indent_level) << "Py_XDECREF(coerced);\n"; indent_level -= 2; - indent(out,indent_level) + indent(out, indent_level) << "}\n"; } } - //////////////////////////////////////////////////////////////////// // Function: InterfaceMakerPythonNative::write_function_instance // Access: Private @@ -2378,12 +2445,12 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, << "// Pre-initialize self for the constructor\n"; CPPType *orig_type = remap->_return_type->get_orig_type(); - TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)),false); + TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)), false); InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); indent(out, indent_level) << "DTool_PyInit_Finalize(self, NULL, &" - << CLASS_PREFEX << make_safe_name(itype.get_scoped_name()) + << CLASS_PREFIX << make_safe_name(itype.get_scoped_name()) << ", false, false);\n"; } @@ -2397,45 +2464,50 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, int pn; for (pn = 0; pn < (int)remap->_parameters.size(); pn++) { - if(pn > 0) { + if (pn > 0) { expected_params += ", "; } CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type(); CPPType *type = remap->_parameters[pn]._remap->get_new_type(); string param_name = remap->get_parameter_name(pn); - + // This is the string to convert our local variable to the // appropriate C++ type. Normally this is just a cast. string pexpr_string = "(" + type->get_local_name(&parser) + ")" + param_name; if (!remap->_has_this || pn != 0) { - keyword_list += "(char *)\""+remap->_parameters[pn]._name + "\", "; + keyword_list += "(char *)\"" + remap->_parameters[pn]._name + "\", "; } if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) { if (TypeManager::is_char_pointer(orig_type)) { - indent(out,indent_level)<< "char *" << param_name; + indent(out, indent_level) << "char *" << param_name; format_specifiers += "s"; parameter_list += ", &" + param_name; } else if (TypeManager::is_wchar_pointer(orig_type)) { - indent(out,indent_level) << "PyUnicodeObject *" << param_name << "\n"; + indent(out, indent_level) << "PyObject *" << param_name << "\n"; format_specifiers += "U"; parameter_list += ", &" + param_name; - extra_convert += " int " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + "); wchar_t *" + param_name + "_str = new wchar_t[" + param_name + "_len + 1]; PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len); " + param_name + "_str[" + param_name + "_len] = 0;"; + extra_convert += " int " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + ");" + " wchar_t *" + param_name + "_str = new wchar_t[" + param_name + "_len + 1];" + " PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len);" + " " + param_name + "_str[" + param_name + "_len] = 0;"; pexpr_string = param_name + "_str"; extra_cleanup += " delete[] " + param_name + "_str;"; } else if (TypeManager::is_wstring(orig_type)) { - indent(out,indent_level) << "PyUnicodeObject *" << param_name << "\n"; + indent(out, indent_level) << "PyObject *" << param_name << "\n"; format_specifiers += "U"; parameter_list += ", &" + param_name; - extra_convert += " int " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + "); wchar_t *" + param_name + "_str = new wchar_t[" + param_name + "_len]; PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len);"; + extra_convert += " int " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + ");" + " wchar_t *" + param_name + "_str = new wchar_t[" + param_name + "_len];" + " PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len);"; pexpr_string = "basic_string((wchar_t *)" + param_name + "_str, " + @@ -2444,11 +2516,13 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, extra_cleanup += " delete[] " + param_name + "_str;"; } else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) { - indent(out,indent_level) << "PyUnicodeObject *" << param_name << "\n"; + indent(out, indent_level) << "PyObject *" << param_name << "\n"; format_specifiers += "U"; parameter_list += ", &" + param_name; - extra_convert += " int " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + "); wchar_t *" + param_name + "_str = new wchar_t[" + param_name + "_len]; PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len);"; + extra_convert += " int " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + ");" + " wchar_t *" + param_name + "_str = new wchar_t[" + param_name + "_len];" + " PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len);"; pexpr_string = "&basic_string((wchar_t *)" + param_name + "_str, " + @@ -2457,7 +2531,7 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, extra_cleanup += " delete[] " + param_name + "_str;"; } else if (TypeManager::is_const_ptr_to_basic_string_char(orig_type)) { - indent(out,indent_level) << "char *" << param_name + indent(out, indent_level) << "char *" << param_name << "_str; int " << param_name << "_len"; format_specifiers += "s#"; parameter_list += ", &" + param_name @@ -2467,7 +2541,7 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, param_name + "_len)"; } else { - indent(out,indent_level) << "char *" << param_name + indent(out, indent_level) << "char *" << param_name << "_str; int " << param_name << "_len"; format_specifiers += "s#"; parameter_list += ", &" + param_name @@ -2479,7 +2553,7 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, expected_params += "string"; } else if (TypeManager::is_bool(type)) { - indent(out,indent_level) << "PyObject *" << param_name; + indent(out, indent_level) << "PyObject *" << param_name; format_specifiers += "O"; parameter_list += ", &" + param_name; pexpr_string = "(PyObject_IsTrue(" + param_name + ")!=0)"; @@ -2487,58 +2561,58 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, pname_for_pyobject += param_name; } else if (TypeManager::is_unsigned_longlong(type)) { - indent(out,indent_level) << "PyObject *" << param_name; + indent(out, indent_level) << "PyObject *" << param_name; format_specifiers += "O"; parameter_list += ", &" + param_name; extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");"; - extra_param_check += "|| (" + param_name + "_long == NULL)"; + extra_param_check += " || (" + param_name + "_long == NULL)"; pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)"; extra_cleanup += " Py_XDECREF(" + param_name + "_long);"; expected_params += "unsigned long long"; pname_for_pyobject += param_name; } else if (TypeManager::is_longlong(type)) { - indent(out,indent_level) << "PyObject *" << param_name; + indent(out, indent_level) << "PyObject *" << param_name; format_specifiers += "O"; parameter_list += ", &" + param_name; extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");"; - extra_param_check += "|| (" + param_name + "_long == NULL)"; + extra_param_check += " || (" + param_name + "_long == NULL)"; pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)"; extra_cleanup += " Py_XDECREF(" + param_name + "_long);"; expected_params += "long long"; pname_for_pyobject += param_name; } else if (TypeManager::is_unsigned_integer(type)) { - indent(out,indent_level) << "PyObject *" << param_name; + indent(out, indent_level) << "PyObject *" << param_name; format_specifiers += "O"; parameter_list += ", &" + param_name; extra_convert += " PyObject *" + param_name + "_uint = PyNumber_Long(" + param_name + ");"; - extra_param_check += "|| (" + param_name + "_uint == NULL)"; + extra_param_check += " || (" + param_name + "_uint == NULL)"; pexpr_string = "PyLong_AsUnsignedLong(" + param_name + "_uint)"; extra_cleanup += " Py_XDECREF(" + param_name + "_uint);"; expected_params += "unsigned int"; pname_for_pyobject += param_name; } else if (TypeManager::is_integer(type)) { - indent(out,indent_level) << "int " << param_name; + indent(out, indent_level) << "int " << param_name; format_specifiers += "i"; parameter_list += ", &" + param_name; expected_params += "int"; } else if (TypeManager::is_float(type)) { - indent(out,indent_level) << "double " << param_name; + indent(out, indent_level) << "double " << param_name; format_specifiers += "d"; parameter_list += ", &" + param_name; expected_params += "float"; } else if (TypeManager::is_char_pointer(type)) { - indent(out,indent_level) << "char *" << param_name; + indent(out, indent_level) << "char *" << param_name; format_specifiers += "s"; parameter_list += ", &" + param_name; expected_params += "string"; } else if (TypeManager::is_pointer_to_PyObject(type)) { - indent(out,indent_level) << "PyObject *" << param_name; + indent(out, indent_level) << "PyObject *" << param_name; format_specifiers += "O"; parameter_list += ", &" + param_name; pexpr_string = param_name; @@ -2563,7 +2637,7 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, parameter_list += ", &" + param_name; pname_for_pyobject += param_name; - TypeIndex p_type_index = builder.get_type(obj_type,false); + TypeIndex p_type_index = builder.get_type(obj_type, false); InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &p_itype = idb->get_type(p_type_index); @@ -2577,11 +2651,11 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, } //make_safe_name(itype.get_scoped_name()) - extra_convert += p_itype.get_scoped_name()+" *" + param_name + "_this = ("+p_itype.get_scoped_name()+" *)"; + extra_convert += p_itype.get_scoped_name()+" *" + param_name + "_this = (" + p_itype.get_scoped_name()+" *)"; // need to a forward scope for this class.. - if(!isExportThisRun(p_itype._cpptype)) { + if (!isExportThisRun(p_itype._cpptype)) { _external_imports.insert(make_safe_name(p_itype.get_scoped_name())); - //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(p_itype.get_scoped_name()) << ";\n"; + //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(p_itype.get_scoped_name()) << ";\n"; } string class_name; @@ -2607,13 +2681,13 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, str << ");\n"; extra_convert += str.str(); - extra_param_check += "|| (" + param_name + "_this == NULL)"; + extra_param_check += " || (" + param_name + "_this == NULL)"; pexpr_string = param_name + "_this"; } } else { // Ignore a parameter. - indent(out,indent_level) << "PyObject *" << param_name; + indent(out, indent_level) << "PyObject *" << param_name; format_specifiers += "O"; parameter_list += ", &" + param_name; expected_params += "any"; @@ -2643,49 +2717,49 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, if (!func1->_ifunc.is_unary_op()) { std::string format_specifiers1 = format_specifiers + ":" + methodNameFromCppName(func1, "", false); - indent(out,indent_level) - << "static char * key_word_list[] = {" << keyword_list << "NULL};\n"; + indent(out, indent_level) + << "static char *keyword_list[] = {" << keyword_list << "NULL};\n"; if (remap->_parameters.size() == 1 || (remap->_has_this && remap->_parameters.size() == 2)) { - indent(out,indent_level) - << "// Special Case to Make operator work \n"; - indent(out,indent_level) - << "if(PyTuple_Check(args) || (kwds != NULL && PyDict_Check(kwds)))\n"; - indent(out,indent_level) - << " (PyArg_ParseTupleAndKeywords(args,kwds, \"" - << format_specifiers1 << "\", key_word_list" << parameter_list - << "));\n"; - indent(out,indent_level) - << "else\n"; - indent(out,indent_level) - << " (PyArg_Parse(args, \"" << format_specifiers1 << "\"" - << parameter_list << "));\n"; - indent(out,indent_level) - << "if(!PyErr_Occurred())\n"; + indent(out, indent_level) + << "// Special case to make operators work \n"; + indent(out, indent_level) + << "if (PyTuple_Check(args) || (kwds != NULL && PyDict_Check(kwds))) {\n"; + indent(out, indent_level) + << " PyArg_ParseTupleAndKeywords(args, kwds, \"" + << format_specifiers1 << "\", keyword_list" << parameter_list + << ");\n"; + indent(out, indent_level) + << "} else {\n"; + indent(out, indent_level) + << " PyArg_Parse(args, \"" << format_specifiers1 << "\"" + << parameter_list << ");\n"; + indent(out, indent_level) + << "}\n"; + indent(out, indent_level) + << "if (!PyErr_Occurred())\n"; } else { - indent(out,indent_level) - << "if (PyArg_ParseTupleAndKeywords(args,kwds, \"" - << format_specifiers1 << "\", key_word_list" + indent(out, indent_level) + << "if (PyArg_ParseTupleAndKeywords(args, kwds, \"" + << format_specifiers1 << "\", keyword_list" << parameter_list << "))\n"; } } - indent(out,indent_level) << "{\n"; + indent(out, indent_level) << "{\n"; if (!extra_convert.empty()) { - indent(out,indent_level+4) + indent(out, indent_level + 2) << extra_convert << "\n"; } - int extra_indent_level = indent_level+4; + int extra_indent_level = indent_level + 2; if (!extra_param_check.empty()) { - indent(out,extra_indent_level) - << "if (!(" << extra_param_check.substr(3) << "))\n"; - indent(out,extra_indent_level) - <<"{\n"; - extra_indent_level+=4; + indent(out, extra_indent_level) + << "if (!(" << extra_param_check.substr(3) << ")) {\n"; + extra_indent_level += 2; } if ((remap->_flags & (FunctionRemap::F_getitem_int | FunctionRemap::F_setitem_int)) && @@ -2725,18 +2799,18 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n"; } if (track_interpreter) { - indent(out,extra_indent_level) << "in_interpreter = 0;\n"; + indent(out, extra_indent_level) << "in_interpreter = 0;\n"; } string tt; string return_expr = remap->call_function(out, extra_indent_level, false, container, pexprs); CPPType *type = remap->_return_type->get_orig_type(); - indent(out,extra_indent_level); + indent(out, extra_indent_level); type->output_instance(out, "return_value", &parser); // type->output_instance(tt, "return_value", &parser); out << " = " << return_expr << ";\n"; if (track_interpreter) { - indent(out,extra_indent_level) << "in_interpreter = 1;\n"; + indent(out, extra_indent_level) << "in_interpreter = 1;\n"; } if (remap->_blocking) { out << "#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)\n"; @@ -2745,12 +2819,12 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n"; } if (!extra_cleanup.empty()) { - indent(out,extra_indent_level) << extra_cleanup << "\n"; + indent(out, extra_indent_level) << extra_cleanup << "\n"; } return_expr = manage_return_value(out, 4, remap, "return_value"); do_assert_init(out, extra_indent_level,is_constructor); - pack_return_value(out, extra_indent_level, remap, return_expr,ForwardDeclrs,is_inplace); + pack_return_value(out, extra_indent_level, remap, return_expr, ForwardDeclrs, is_inplace); } else { if (remap->_blocking) { @@ -2762,13 +2836,13 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n"; } if (track_interpreter) { - indent(out,extra_indent_level) << "in_interpreter = 0;\n"; + indent(out, extra_indent_level) << "in_interpreter = 0;\n"; } string return_expr = remap->call_function(out, extra_indent_level, true, container, pexprs); if (return_expr.empty()) { if (track_interpreter) { - indent(out,extra_indent_level) << "in_interpreter = 1;\n"; + indent(out, extra_indent_level) << "in_interpreter = 1;\n"; } if (remap->_blocking) { out << "#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)\n"; @@ -2777,24 +2851,24 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n"; } if (!extra_cleanup.empty()) { - indent(out,extra_indent_level) << extra_cleanup << "\n"; + indent(out, extra_indent_level) << extra_cleanup << "\n"; } if (coercion_possible) { indent(out, extra_indent_level) << "Py_XDECREF(coerced);\n"; } do_assert_init(out, extra_indent_level,is_constructor); - indent(out,extra_indent_level) << "return Py_BuildValue(\"\");\n"; + indent(out, extra_indent_level) << "return Py_BuildValue(\"\");\n"; } else { CPPType *type = remap->_return_type->get_temporary_type(); - if(!is_inplace) { - indent(out,extra_indent_level); + if (!is_inplace) { + indent(out, extra_indent_level); type->output_instance(out, "return_value", &parser); out << " = " << return_expr << ";\n"; } if (track_interpreter) { - indent(out,extra_indent_level) << "in_interpreter = 1;\n"; + indent(out, extra_indent_level) << "in_interpreter = 1;\n"; } if (remap->_blocking) { out << "#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)\n"; @@ -2803,7 +2877,7 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n"; } if (!extra_cleanup.empty()) { - indent(out,extra_indent_level) << extra_cleanup << "\n"; + indent(out, extra_indent_level) << extra_cleanup << "\n"; } if (!is_inplace) { @@ -2814,7 +2888,7 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, << "Py_XDECREF(coerced);\n"; } do_assert_init(out, extra_indent_level,is_constructor); - pack_return_value(out, extra_indent_level, remap, remap->_return_type->temporary_to_return(return_expr),ForwardDeclrs,is_inplace); + pack_return_value(out, extra_indent_level, remap, remap->_return_type->temporary_to_return(return_expr), ForwardDeclrs, is_inplace); } } @@ -2824,11 +2898,11 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, << "}\n"; if (!extra_param_check.empty()) { - extra_indent_level-=4; - indent(out,extra_indent_level)<< "}\n"; + extra_indent_level -= 2; + indent(out, extra_indent_level) << "}\n"; } - indent(out,indent_level) << "}\n"; + indent(out, indent_level) << "}\n"; } //////////////////////////////////////////////////////////////////// @@ -2837,29 +2911,32 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, // Description: Outputs a command to pack the indicated expression, // of the return_type type, as a Python return value. //////////////////////////////////////////////////////////////////// - -void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_level, - FunctionRemap *remap, string return_expr, ostream &ForwardDeclrs, bool is_inplace) -{ +void InterfaceMakerPythonNative:: +pack_return_value(ostream &out, int indent_level, + FunctionRemap *remap, string return_expr, ostream &ForwardDeclrs, bool is_inplace) { CPPType *orig_type = remap->_return_type->get_orig_type(); CPPType *type = remap->_return_type->get_new_type(); if (remap->_return_type->new_type_is_atomic_string()) { if (TypeManager::is_char_pointer(orig_type)) { - indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; - indent(out, indent_level)<<"{\n"; - indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; - indent(out, indent_level)<<" return Py_None;\n"; - indent(out, indent_level)<<"}\n"; + indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n"; + indent(out, indent_level) << " Py_INCREF(Py_None);\n"; + indent(out, indent_level) << " return Py_None;\n"; + indent(out, indent_level) << "}\n"; + + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromString(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromString(" << return_expr << ");\n"; + out << "#endif\n"; } else if (TypeManager::is_wchar_pointer(orig_type)) { - indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; - indent(out, indent_level)<<"{\n"; - indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; - indent(out, indent_level)<<" return Py_None;\n"; - indent(out, indent_level)<<"}\n"; + indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n"; + indent(out, indent_level) << " Py_INCREF(Py_None);\n"; + indent(out, indent_level) << " return Py_None;\n"; + indent(out, indent_level) << "}\n"; indent(out, indent_level) << "return PyUnicode_FromWideChar(" << return_expr << ", wcslen(" << return_expr << "));\n"; @@ -2870,31 +2947,41 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve << return_expr << ".data(), (int)" << return_expr << ".length());\n"; } else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) { - indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; - indent(out, indent_level)<<"{\n"; - indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; - indent(out, indent_level)<<" return Py_None;\n"; - indent(out, indent_level)<<"}\n"; + indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n"; + indent(out, indent_level) << " Py_INCREF(Py_None);\n"; + indent(out, indent_level) << " return Py_None;\n"; + indent(out, indent_level) << "}\n"; indent(out, indent_level) << "return PyUnicode_FromWideChar(" << return_expr << "->data(), (int)" << return_expr << "->length());\n"; } else if (TypeManager::is_const_ptr_to_basic_string_char(orig_type)) { - indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; - indent(out, indent_level)<<"{\n"; - indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; - indent(out, indent_level)<<" return Py_None;\n"; - indent(out, indent_level)<<"}\n"; + indent(out, indent_level) << "if (" << return_expr<< " == NULL) {\n"; + indent(out, indent_level) << " Py_INCREF(Py_None);\n"; + indent(out, indent_level) << " return Py_None;\n"; + indent(out, indent_level) << "}\n"; + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromStringAndSize(" + << return_expr << "->data(), (Py_ssize_t)" << return_expr << "->length());\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromStringAndSize(" - << return_expr << "->data(), (int)" << return_expr << "->length());\n"; + << return_expr << "->data(), (Py_ssize_t)" << return_expr << "->length());\n"; + out << "#endif\n"; } else { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromStringAndSize(" + << return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromStringAndSize(" - << return_expr << ".data(), (int)" << return_expr << ".length());\n"; + << return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n"; + out << "#endif\n"; } } else if (TypeManager::is_bool(type)) { @@ -2909,40 +2996,53 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve indent(out, indent_level) << "return PyLong_FromLongLong(" << return_expr << ");\n"; - } else if(TypeManager::is_unsigned_integer(type)){ + } else if (TypeManager::is_unsigned_integer(type)){ + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyLong_FromUnsignedLong(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyLongOrInt_FromUnsignedLong(" << return_expr << ");\n"; - + out << "#endif\n"; + } else if (TypeManager::is_integer(type)) { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyLong_FromLong(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyInt_FromLong(" << return_expr << ");\n"; + out << "#endif\n"; } else if (TypeManager::is_float(type)) { indent(out, indent_level) << "return PyFloat_FromDouble(" << return_expr << ");\n"; } else if (TypeManager::is_char_pointer(type)) { - indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; - indent(out, indent_level)<<"{\n"; - indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; - indent(out, indent_level)<<" return Py_None;\n"; - indent(out, indent_level)<<"}\n"; - indent(out, indent_level) - << "return PyString_FromString(" << return_expr << ");\n"; + indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n"; + indent(out, indent_level) << " Py_INCREF(Py_None);\n"; + indent(out, indent_level) << " return Py_None;\n"; + indent(out, indent_level) << "}\n"; + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromString(" << return_expr << ");\n"; + out << "#else\n"; + indent(out, indent_level) + << "return PyString_FromString(" << return_expr << ");\n"; + out << "#endif\n"; } else if (TypeManager::is_wchar_pointer(type)) { - indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; - indent(out, indent_level)<<"{\n"; - indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; - indent(out, indent_level)<<" return Py_None;\n"; - indent(out, indent_level)<<"}\n"; + indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n"; + indent(out, indent_level) << " Py_INCREF(Py_None);\n"; + indent(out, indent_level) << " return Py_None;\n"; + indent(out, indent_level) << "}\n"; indent(out, indent_level) << "return PyUnicode_FromWideChar(" << return_expr << ", wcslen(" << return_expr << "));\n"; } else if (TypeManager::is_pointer_to_PyObject(type)) { indent(out, indent_level) - << "return "<< return_expr << ";\n"; + << "return " << return_expr << ";\n"; } else if (TypeManager::is_pointer(type)) { string const_flag; @@ -2954,30 +3054,30 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve if (TypeManager::is_struct(orig_type) || TypeManager::is_ref_to_anything(orig_type)) { - if( TypeManager::is_ref_to_anything(orig_type)) + if (TypeManager::is_ref_to_anything(orig_type)) { TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(type)),false); InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); std::string ows_memory_flag("true"); - if(remap->_return_value_needs_management) + if (remap->_return_value_needs_management) ows_memory_flag = "true"; else ows_memory_flag = "false"; - if(!isExportThisRun(itype._cpptype)) + if (!isExportThisRun(itype._cpptype)) { _external_imports.insert(make_safe_name(itype.get_scoped_name())); - //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; + //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; } - WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag); + WriteReturnInstance(out, indent_level, return_expr, ows_memory_flag, itype.get_scoped_name(), itype._cpptype, is_inplace, const_flag); } else { - if (remap->_type == FunctionRemap::T_constructor ) + if (remap->_type == FunctionRemap::T_constructor) { // should only reach this in the INIT function a a Class .. IE the PY exists before the CPP object // this is were we type to returned a class/struct.. ie CPP TYpe @@ -2987,31 +3087,31 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); indent(out, indent_level) - <<"return DTool_PyInit_Finalize(self, " << return_expr <<",&"<_return_value_needs_management) + if (remap->_return_value_needs_management) ows_memory_flag = "true"; else ows_memory_flag = "false"; - if(remap->_manage_reference_count) + if (remap->_manage_reference_count) { TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(type)),false); InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); - if(!isExportThisRun(itype._cpptype)) + if (!isExportThisRun(itype._cpptype)) { _external_imports.insert(make_safe_name(itype.get_scoped_name())); - //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; + //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; } - // ForwardDeclrs << "extern \"C\" struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; - WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag); + // ForwardDeclrs << "extern \"C\" struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; + WriteReturnInstance(out, indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag); } else { @@ -3019,44 +3119,44 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); - if(!isExportThisRun(itype._cpptype)) + if (!isExportThisRun(itype._cpptype)) { _external_imports.insert(make_safe_name(itype.get_scoped_name())); - //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; + //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; } - // ForwardDeclrs << "extern \"C\" struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; - WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag); + // ForwardDeclrs << "extern \"C\" struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; + WriteReturnInstance(out, indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag); } } } } - else if( TypeManager::is_struct(orig_type->as_pointer_type()->_pointing_at) ) + else if ( TypeManager::is_struct(orig_type->as_pointer_type()->_pointing_at) ) { TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)),false); InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); std::string ows_memory_flag("true"); - if(remap->_return_value_needs_management) + if (remap->_return_value_needs_management) ows_memory_flag ="true"; else ows_memory_flag = "false"; - if(!isExportThisRun(itype._cpptype)) + if (!isExportThisRun(itype._cpptype)) { _external_imports.insert(make_safe_name(itype.get_scoped_name())); - //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; + //ForwardDeclrs << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; } - // ForwardDeclrs << "extern \"C\" struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; - WriteReturnInstance(out,indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag); + // ForwardDeclrs << "extern \"C\" struct Dtool_PyTypedObject Dtool_" << make_safe_name(itype.get_scoped_name()) << ";\n"; + WriteReturnInstance(out, indent_level,return_expr,ows_memory_flag,itype.get_scoped_name(),itype._cpptype,is_inplace, const_flag); } else { - indent(out, indent_level)<<" Shouln Never Reach This InterfaceMakerPythonNative::pack_return_value"; + indent(out, indent_level) << " Shouln Never Reach This InterfaceMakerPythonNative::pack_return_value"; //<< "return PyInt_FromLong((int)" << return_expr << ");\n"; } @@ -3111,7 +3211,7 @@ InterfaceMaker::Object *InterfaceMakerPythonNative::record_object(TypeIndex type InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); - if(!isCppTypeLegal(itype._cpptype)) + if (!isCppTypeLegal(itype._cpptype)) { return (Object *)NULL; } @@ -3126,7 +3226,7 @@ InterfaceMaker::Object *InterfaceMakerPythonNative::record_object(TypeIndex type for (int ci = 0; ci < num_constructors; ci++) { function = record_function(itype, itype.get_constructor(ci)); - if(isFunctionLegal(function)) + if (isFunctionLegal(function)) object->_constructors.push_back(function); } @@ -3135,7 +3235,7 @@ InterfaceMaker::Object *InterfaceMakerPythonNative::record_object(TypeIndex type for (mi = 0; mi < num_methods; mi++) { function = record_function(itype, itype.get_method(mi)); - if(isFunctionLegal(function)) + if (isFunctionLegal(function)) object->_methods.push_back(function); } @@ -3144,7 +3244,7 @@ InterfaceMaker::Object *InterfaceMakerPythonNative::record_object(TypeIndex type for (mi = 0; mi < num_casts; mi++) { function = record_function(itype, itype.get_cast(mi)); - if(isFunctionLegal(function)) + if (isFunctionLegal(function)) object->_methods.push_back(function); } @@ -3154,12 +3254,12 @@ InterfaceMaker::Object *InterfaceMakerPythonNative::record_object(TypeIndex type TypeIndex d_type_Index = itype.get_derivation(di); idb->get_type(d_type_Index); - if(!interrogate_type_is_unpublished(d_type_Index)) + if (!interrogate_type_is_unpublished(d_type_Index)) { if (itype.derivation_has_upcast(di)) { function = record_function(itype, itype.derivation_get_upcast(di)); - if(isFunctionLegal(function)) + if (isFunctionLegal(function)) object->_methods.push_back(function); } if (itype.derivation_has_downcast(di)) @@ -3170,10 +3270,10 @@ InterfaceMaker::Object *InterfaceMakerPythonNative::record_object(TypeIndex type const InterrogateType &base_type = idb->get_type(base_type_index); function = record_function(base_type, itype.derivation_get_downcast(di)); - if(isFunctionLegal(function)) + if (isFunctionLegal(function)) { Object * pobject = record_object(base_type_index); - if(pobject != NULL) + if (pobject != NULL) pobject->_methods.push_back(function); } } @@ -3286,10 +3386,10 @@ void InterfaceMakerPythonNative::generate_wrappers() ////////////////////////////////////////////// bool InterfaceMakerPythonNative::isCppTypeLegal(CPPType *in_ctype) { - if(in_ctype == NULL) + if (in_ctype == NULL) return false; - if(builder.in_ignoretype(in_ctype->get_local_name(&parser))) + if (builder.in_ignoretype(in_ctype->get_local_name(&parser))) { return false; } @@ -3299,32 +3399,32 @@ bool InterfaceMakerPythonNative::isCppTypeLegal(CPPType *in_ctype) type = TypeManager::unwrap(type); //CPPType *type = ctype; - if(TypeManager::is_basic_string_char(type)) + if (TypeManager::is_basic_string_char(type)) { return true; } - else if(TypeManager::is_basic_string_wchar(type)) + else if (TypeManager::is_basic_string_wchar(type)) { return true; } - else if(TypeManager::is_simple(type)) + else if (TypeManager::is_simple(type)) { return true; } - else if(builder.in_forcetype(type->get_local_name(&parser))) + else if (builder.in_forcetype(type->get_local_name(&parser))) { return true; } - else if(TypeManager::IsExported(type) == true) + else if (TypeManager::IsExported(type) == true) { return true; } - else if(TypeManager::is_pointer_to_PyObject(in_ctype) == true) + else if (TypeManager::is_pointer_to_PyObject(in_ctype) == true) { return true; } - //if(answer == false) + //if (answer == false) // printf(" -------------------- Bad Type ?? %s \n",type->get_local_name().c_str()); return false; @@ -3336,10 +3436,10 @@ bool InterfaceMakerPythonNative::isCppTypeLegal(CPPType *in_ctype) bool InterfaceMakerPythonNative::isExportThisRun(CPPType *ctype) { CPPType *type = TypeManager::unwrap(ctype); - if(TypeManager::IsLocal(type)) + if (TypeManager::IsLocal(type)) return true; - if(builder.in_forcetype(type->get_local_name(&parser))) + if (builder.in_forcetype(type->get_local_name(&parser))) return true; return false; @@ -3350,7 +3450,7 @@ bool InterfaceMakerPythonNative::isExportThisRun(CPPType *ctype) ///////////////////////////////////////////// bool InterfaceMakerPythonNative::isExportThisRun(Function *func) { - if(func == NULL || !isFunctionLegal(func)) + if (func == NULL || !isFunctionLegal(func)) return false; Function::Remaps::const_iterator ri; @@ -3368,21 +3468,21 @@ bool InterfaceMakerPythonNative::isExportThisRun(Function *func) bool InterfaceMakerPythonNative::isRemapLegal( FunctionRemap &remap) { // return must be legal and managable.. - if(!isCppTypeLegal(remap._return_type->get_orig_type())) + if (!isCppTypeLegal(remap._return_type->get_orig_type())) { // printf(" isRemapLegal Return Is Bad %s\n",remap._return_type->get_orig_type()->get_fully_scoped_name().c_str()); return false; } // ouch .. bad things will happen here .. do not even try.. - if(remap._ForcedVoidReturn) + if (remap._ForcedVoidReturn) return false; // all params must be legal for (int pn = 0; pn < (int)remap._parameters.size(); pn++) { CPPType *orig_type = remap._parameters[pn]._remap->get_orig_type(); - if(!isCppTypeLegal(orig_type)) + if (!isCppTypeLegal(orig_type)) return false; } @@ -3398,7 +3498,7 @@ bool InterfaceMakerPythonNative::isFunctionLegal( Function *func) for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { FunctionRemap *remap = (*ri); - if(isRemapLegal(*remap)) + if (isRemapLegal(*remap)) { // printf(" Function Is Marked Legal %s\n",func->_name.c_str()); @@ -3420,7 +3520,7 @@ bool InterfaceMakerPythonNative::isFunctionWithThis( Function *func) for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { FunctionRemap *remap = (*ri); - if(remap->_has_this) + if (remap->_has_this) return true; } return false; @@ -3486,7 +3586,7 @@ void InterfaceMakerPythonNative::do_assert_init(ostream &out, int &indent_level, bool InterfaceMakerPythonNative::IsRunTimeTyped(const InterrogateType &itype) { TypeIndex ptype_id = itype.get_outer_class(); - if(ptype_id > 0) + if (ptype_id > 0) { InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); @@ -3495,7 +3595,7 @@ bool InterfaceMakerPythonNative::IsRunTimeTyped(const InterrogateType &itype) } - if(itype.get_name() == "TypedObject") + if (itype.get_name() == "TypedObject") return true; return false; @@ -3508,11 +3608,11 @@ bool InterfaceMakerPythonNative::IsRunTimeTyped(const InterrogateType &itype) /////////////////////////////////////////////////////////// bool InterfaceMakerPythonNative::DoesInheritFromIsClass( const CPPStructType * inclass, const std::string &name) { - if(inclass == NULL) + if (inclass == NULL) return false; std::string scoped_name = inclass->get_fully_scoped_name(); - if(scoped_name == name) + if (scoped_name == name) return true; CPPStructType::Derivation::const_iterator bi; @@ -3524,9 +3624,9 @@ bool InterfaceMakerPythonNative::DoesInheritFromIsClass( const CPPStructType * const CPPStructType::Base &base = (*bi); CPPStructType *base_type = TypeManager::resolve_type(base._base)->as_struct_type(); - if(base_type != NULL) + if (base_type != NULL) { - if(DoesInheritFromIsClass(base_type,name) == true) + if (DoesInheritFromIsClass(base_type,name) == true) return true; } } @@ -3600,7 +3700,7 @@ HasAGetClassTypeFunction(const InterrogateType &itype_class) { CPPType *ret_type = TypeManager::unwrap(cppfunc->_return_type); if (TypeManager::is_struct(ret_type) && ret_type->get_simple_name() == "TypeHandle") { - if(cppfunc->_parameters->_parameters.size() == 0) { + if (cppfunc->_parameters->_parameters.size() == 0) { return true; } } @@ -3780,6 +3880,44 @@ NeedsAReprFunction(const InterrogateType &itype_class) { return -1; } +//////////////////////////////////////////////////////////////////// +// Function: InterfaceMakerPythonNative::NeedsARichCompareFunction +// Access: Private +// Description: Returns true if the class defines a rich comparison +// operator. +//////////////////////////////////////////////////////////////////// +bool InterfaceMakerPythonNative:: +NeedsARichCompareFunction(const InterrogateType &itype_class) { + InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); + + int num_methods = itype_class.number_of_methods(); + int mi; + for (mi = 0; mi < num_methods; ++mi) { + FunctionIndex func_index = itype_class.get_method(mi); + const InterrogateFunction &ifunc = idb->get_function(func_index); + int op; + if (ifunc.get_name() == "operator <") { + return true; + } + if (ifunc.get_name() == "operator <=") { + return true; + } + if (ifunc.get_name() == "operator ==") { + return true; + } + if (ifunc.get_name() == "operator !=") { + return true; + } + if (ifunc.get_name() == "operator >") { + return true; + } + if (ifunc.get_name() == "operator >=") { + return true; + } + } + + return false; +} //////////////////////////////////////////////////////////////////// // Function: InterfaceMakerPythonNative::output_quoted diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.h b/dtool/src/interrogate/interfaceMakerPythonNative.h index ab011f73c8..cd5da0efe2 100755 --- a/dtool/src/interrogate/interfaceMakerPythonNative.h +++ b/dtool/src/interrogate/interfaceMakerPythonNative.h @@ -95,21 +95,21 @@ private: bool is_inplace, bool coercion_possible); void write_function_forset(ostream &out, Object *obj, Function *func, - std::set< FunctionRemap *> &remaps, string &expected_params, int indent_level , ostream &forwarddecl,const std::string &functionname, bool inplace) ; + std::set &remaps, string &expected_params, int indent_level, ostream &forwarddecl, bool inplace); void pack_return_value(ostream &out, int indent_level, - FunctionRemap *remap, std::string return_expr , ostream &forwarddecl, bool in_place); + FunctionRemap *remap, std::string return_expr, ostream &forwarddecl, bool in_place); void write_make_seq(ostream &out, Object *obj, const std::string &ClassName, MakeSeq *make_seq); void write_class_prototypes(ostream &out) ; - void write_ClasseDeclarations(ostream &out , ostream *out_h,Object * obj); - void write_ClasseDetails(ostream &out, Object * obj); + void write_class_declarations(ostream &out, ostream *out_h, Object *obj); + void write_class_details(ostream &out, Object *obj); void do_assert_init(ostream &out, int &indent_level, bool constructor) const; public: - bool isRemapLegal( FunctionRemap &remap); + bool isRemapLegal(FunctionRemap &remap); bool isFunctionLegal( Function *func); bool isCppTypeLegal(CPPType *ctype); bool isExportThisRun(CPPType *ctype); @@ -126,19 +126,20 @@ public: bool _is_legal_py_class; }; - void GetValideChildClasses( std::map< std::string ,CastDetails > &answer, CPPStructType * inclass, const std::string &up_cast_seed = "", bool downcastposible = true); - bool DoesInheritFromIsClass( const CPPStructType * inclass, const std::string &name); - bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); }; + void GetValideChildClasses( std::map< std::string ,CastDetails > &answer, CPPStructType * inclass, const std::string &up_cast_seed = "", bool downcastposible = true); + bool DoesInheritFromIsClass( const CPPStructType * inclass, const std::string &name); + bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); }; void WriteReturnInstance(ostream &out, int indent_level, std::string &return_expr, std::string &ows_memory_flag,const std::string &class_name, CPPType *ctype, bool inplace, const std::string &const_flag); string HasAGetKeyFunction(const InterrogateType &itype_class); bool HasAGetClassTypeFunction(const InterrogateType &itype_class); int NeedsAStrFunction(const InterrogateType &itype_class); int NeedsAReprFunction(const InterrogateType &itype_class); - + bool NeedsARichCompareFunction(const InterrogateType &itype_class); + void output_quoted(ostream &out, int indent_level, const std::string &str); - // stash the forwad declarations for this compile pass.. - std::set< std::string > _external_imports; + // stash the forward declarations for this compile pass.. + std::set _external_imports; }; #endif diff --git a/dtool/src/interrogate/interfaceMakerPythonObj.cxx b/dtool/src/interrogate/interfaceMakerPythonObj.cxx index 5ce5bb455e..d3a219e18b 100644 --- a/dtool/src/interrogate/interfaceMakerPythonObj.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonObj.cxx @@ -119,15 +119,33 @@ write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) { out << " { NULL, NULL }\n" << "};\n\n" - << "#ifdef _WIN32\n" - << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n" + << "#if PY_MAJOR_VERSION >= 3\n" + << "static struct PyModuleDef python_obj_module = {\n" + << " PyModuleDef_HEAD_INIT,\n" + << " \"" << def->library_name << "\",\n" + << " NULL,\n" + << " -1,\n" + << " python_obj_funcs,\n" + << " NULL, NULL, NULL, NULL\n" + << "};\n\n" + + << "#define INIT_FUNC PyObject *PyInit_" << def->library_name << "\n" << "#else\n" - << "extern \"C\" void init" << def->library_name << "();\n" + << "#define INIT_FUNC void init" << def->library_name << "\n" << "#endif\n\n" - - << "void init" << def->library_name << "() {\n" - << " Py_InitModule(\"" << def->library_name - << "\", python_obj_funcs);\n" + + << "#ifdef _WIN32\n" + << "extern \"C\" __declspec(dllexport) INIT_FUNC();\n" + << "#else\n" + << "extern \"C\" INIT_FUNC();\n" + << "#endif\n\n" + + << "INIT_FUNC() {\n" + << "#if PY_MAJOR_VERSION >= 3\n" + << " return PyModule_Create(&python_obj_module);\n" + << "#else\n" + << " Py_InitModule(\"" << def->library_name << "\", python_obj_funcs);\n" + << "#endif\n" << "}\n\n"; } @@ -225,8 +243,11 @@ write_class_wrapper(ostream &out, InterfaceMaker::Object *object) { << " int i;\n" << " PyObject *bases = PyTuple_New(0);\n" << " PyObject *dict = PyDict_New();\n" - << " PyObject *name = PyString_FromString(\"" - << python_name << "\");\n" + << "#if PY_MAJOR_VERSION >= 3\n" + << " PyObject *name = PyUnicode_FromString(\"" << python_name << "\");\n" + << "#else\n" + << " PyObject *name = PyString_FromString(\"" << python_name << "\");\n" + << "#endif\n" << " wrapper = PyClass_New(bases, dict, name);\n" << " for (i = 0; i < methods_size; ++i) {\n" << " PyObject *function, *method;\n" @@ -553,13 +574,24 @@ pack_return_value(ostream &out, int indent_level, if (remap->_return_type->new_type_is_atomic_string()) { if (TypeManager::is_char_pointer(orig_type)) { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromString(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromString(" << return_expr << ");\n"; + out << "#endif\n"; } else { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromStringAndSize(" + << return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromStringAndSize(" - << return_expr << ".data(), " << return_expr << ".length());\n"; + << return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n"; + out << "#endif\n"; } } else if (TypeManager::is_bool(type)) { @@ -579,16 +611,26 @@ pack_return_value(ostream &out, int indent_level, << "return PyLong_FromUnsignedLong(" << return_expr << ");\n"; } else if (TypeManager::is_integer(type)) { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyLong_FromLong(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyInt_FromLong(" << return_expr << ");\n"; + out << "#endif\n"; } else if (TypeManager::is_float(type)) { indent(out, indent_level) << "return PyFloat_FromDouble(" << return_expr << ");\n"; } else if (TypeManager::is_char_pointer(type)) { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromString(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromString(" << return_expr << ");\n"; + out << "#endif\n"; } else if (TypeManager::is_pointer(type)) { bool caller_manages = remap->_return_value_needs_management; diff --git a/dtool/src/interrogate/interfaceMakerPythonSimple.cxx b/dtool/src/interrogate/interfaceMakerPythonSimple.cxx index 449b16b2aa..b0e68c6683 100644 --- a/dtool/src/interrogate/interfaceMakerPythonSimple.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonSimple.cxx @@ -99,22 +99,40 @@ write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) { Function::Remaps::const_iterator ri; for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { FunctionRemap *remap = (*ri); - out << " { \"" << remap->_reported_name << "\", &" + out << " { \"" << remap->_reported_name << "\", &" << remap->_wrapper_name << ", METH_VARARGS },\n"; } - } + } out << " { NULL, NULL }\n" << "};\n\n" - << "#ifdef _WIN32\n" - << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n" + << "#if PY_MAJOR_VERSION >= 3\n" + << "static struct PyModuleDef python_simple_module = {\n" + << " PyModuleDef_HEAD_INIT,\n" + << " \"" << def->library_name << "\",\n" + << " NULL,\n" + << " -1,\n" + << " python_simple_funcs,\n" + << " NULL, NULL, NULL, NULL\n" + << "};\n\n" + + << "#define INIT_FUNC PyObject *PyInit_" << def->library_name << "\n" << "#else\n" - << "extern \"C\" void init" << def->library_name << "();\n" + << "#define INIT_FUNC void init" << def->library_name << "\n" << "#endif\n\n" - - << "void init" << def->library_name << "() {\n" - << " Py_InitModule(\"" << def->library_name - << "\", python_simple_funcs);\n" + + << "#ifdef _WIN32\n" + << "extern \"C\" __declspec(dllexport) INIT_FUNC();\n" + << "#else\n" + << "extern \"C\" INIT_FUNC();\n" + << "#endif\n\n" + + << "INIT_FUNC() {\n" + << "#if PY_MAJOR_VERSION >= 3\n" + << " return PyModule_Create(&python_simple_module);\n" + << "#else\n" + << " Py_InitModule(\"" << def->library_name << "\", python_simple_funcs);\n" + << "#endif\n" << "}\n\n"; } @@ -452,8 +470,13 @@ pack_return_value(ostream &out, int indent_level, if (remap->_return_type->new_type_is_atomic_string()) { if (TypeManager::is_char_pointer(orig_type)) { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromString(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromString(" << return_expr << ");\n"; + out << "#endif\n"; } else if (TypeManager::is_wstring(orig_type)) { indent(out, indent_level) @@ -461,9 +484,15 @@ pack_return_value(ostream &out, int indent_level, << return_expr << ".data(), (int)" << return_expr << ".length());\n"; } else { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromStringAndSize(" + << return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromStringAndSize(" - << return_expr << ".data(), " << return_expr << ".length());\n"; + << return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n"; + out << "#endif\n"; } } else if (TypeManager::is_bool(type)) { @@ -485,16 +514,26 @@ pack_return_value(ostream &out, int indent_level, << "return PyLong_FromUnsignedLong(" << return_expr << ");\n"; } else if (TypeManager::is_integer(type)) { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyLong_FromLong(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyInt_FromLong(" << return_expr << ");\n"; + out << "#endif\n"; } else if (TypeManager::is_float(type)) { indent(out, indent_level) << "return PyFloat_FromDouble(" << return_expr << ");\n"; } else if (TypeManager::is_char_pointer(type)) { + out << "#if PY_MAJOR_VERSION >= 3\n"; + indent(out, indent_level) + << "return PyUnicode_FromString(" << return_expr << ");\n"; + out << "#else\n"; indent(out, indent_level) << "return PyString_FromString(" << return_expr << ");\n"; + out << "#endif\n"; } else if (TypeManager::is_pointer_to_PyObject(type)) { indent(out, indent_level) diff --git a/dtool/src/interrogate/interrogateBuilder.cxx b/dtool/src/interrogate/interrogateBuilder.cxx index a526f67828..51eb0bbb3a 100644 --- a/dtool/src/interrogate/interrogateBuilder.cxx +++ b/dtool/src/interrogate/interrogateBuilder.cxx @@ -51,8 +51,8 @@ #include InterrogateBuilder builder; -std::string EXPORT_IMPORT_PREFEX; -bool inside_python_native = false; +std::string EXPORT_IMPORT_PREFIX; +bool inside_python_native = false; //////////////////////////////////////////////////////////////////// // Function: InterrogateBuilder::add_source_file @@ -332,16 +332,15 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int makers.push_back(maker); } - if (build_python_native ) { + if (build_python_native) { InterfaceMakerPythonNative *maker = new InterfaceMakerPythonNative(def); makers.push_back(maker); } - - EXPORT_IMPORT_PREFEX = std::string("EXPCL_") + def->module_name; - for (size_t i=0; imodule_name; + for (size_t i = 0; i < EXPORT_IMPORT_PREFIX.size(); i++) { + EXPORT_IMPORT_PREFIX[i] = toupper(EXPORT_IMPORT_PREFIX[i]); + } InterfaceMakers::iterator mi; // First, make all the wrappers. @@ -359,12 +358,10 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int } // Now, begin the actual output. Start with the #include lines. - - if (!no_database) - { + if (!no_database) { out_code << "#include \"dtoolbase.h\"\n" - << "#include \"interrogate_request.h\"\n" - << "#include \"dconfig.h\"\n"; + << "#include \"interrogate_request.h\"\n" + << "#include \"dconfig.h\"\n"; } diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index fc5b46dd5a..28a240ba3e 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -110,7 +110,7 @@ int write_python_table_native(ostream &out) { pset::iterator ii; for(ii = Libraries.begin(); ii != Libraries.end(); ii++) { printf("Referencing Library %s\n",(*ii).c_str()); - out << "extern LibrayDef "<< *ii << "_moddef ;\n"; + out << "extern LibraryDef "<< *ii << "_moddef ;\n"; } out << "#ifdef _WIN32\n" @@ -124,7 +124,7 @@ int write_python_table_native(ostream &out) { out << " in_interpreter = 1;\n"; } - out << " LibrayDef *defs[] = {"; + out << " LibraryDef *defs[] = {"; for(ii = Libraries.begin(); ii != Libraries.end(); ii++) out << "&"<< *ii << "_moddef,"; @@ -217,17 +217,38 @@ int write_python_table(ostream &out) { out << " { NULL, NULL }\n" << "};\n\n" - << "#ifdef _WIN32\n" - << "extern \"C\" __declspec(dllexport) void init" << library_name << "();\n" + << "#if PY_MAJOR_VERSION >= 3\n" + << "static struct PyModuleDef python_module = {\n" + << " PyModuleDef_HEAD_INIT,\n" + << " \"" << library_name << "\",\n" + << " NULL,\n" + << " -1,\n" + << " python_methods,\n" + << " NULL, NULL, NULL, NULL\n" + << "};\n\n" + + << "#define INIT_FUNC PyObject *PyInit_" << library_name << "\n" << "#else\n" - << "extern \"C\" void init" << library_name << "();\n" + << "#define INIT_FUNC void init" << library_name << "\n" << "#endif\n\n" - << "void init" << library_name << "() {\n"; + << "#ifdef _WIN32\n" + << "extern \"C\" __declspec(dllexport) INIT_FUNC();\n" + << "#else\n" + << "extern \"C\" INIT_FUNC();\n" + << "#endif\n\n" + + << "INIT_FUNC() {\n"; + if (track_interpreter) { out << " in_interpreter = 1;\n"; } - out << " Py_InitModule(\"" << library_name << "\", python_methods);\n" + + out << "#if PY_MAJOR_VERSION >= 3\n" + << " return PyModule_Create(&python_module);\n" + << "#else\n" + << " Py_InitModule(\"" << library_name << "\", python_methods);\n" + << "#endif\n" << "}\n\n"; return count; diff --git a/dtool/src/interrogatedb/dtool_super_base.cxx b/dtool/src/interrogatedb/dtool_super_base.cxx index 04ef765972..669748fb11 100644 --- a/dtool/src/interrogatedb/dtool_super_base.cxx +++ b/dtool/src/interrogatedb/dtool_super_base.cxx @@ -16,80 +16,71 @@ #ifdef HAVE_PYTHON -class EmptyClass -{ +class EmptyClass { }; -Define_Module_Class_Private(dtoolconfig,DTOOL_SUPPER_BASE,EmptyClass,DTOOL_SUPPER_BASE111); +Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111); -static PyObject * GetSupperBase(PyObject * self) -{ - Py_INCREF(&(Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject())); // order is important .. this is used for static functions - return (PyObject *)&Dtool_DTOOL_SUPPER_BASE; +static PyObject *GetSuperBase(PyObject *self) { + Py_INCREF(&(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject())); // order is important .. this is used for static functions + return (PyObject *) &Dtool_DTOOL_SUPER_BASE; }; - -PyMethodDef Dtool_Methods_DTOOL_SUPPER_BASE[]= { - { "DtoolGetSupperBase",(PyCFunction ) &GetSupperBase, METH_NOARGS,"Will Return SUPPERbase Class"}, +PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = { + { "DtoolGetSuperBase", (PyCFunction) &GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"}, { NULL, NULL } }; -static long DTool_HashKey_Methods_DTOOL_SUPPER_BASE(PyObject * self) -{ - void * local_this =DTOOL_Call_GetPointerThis(self); - if(local_this == NULL) - { - return -1; - }; - return (long)local_this; +static Py_hash_t DTool_HashKey_Methods_DTOOL_SUPER_BASE(PyObject *self) { + void *local_this = DTOOL_Call_GetPointerThis(self); + if (local_this == NULL) { + return -1; + } + return (Py_hash_t) local_this; }; +inline void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) { + static bool initdone = false; + if (!initdone) { -inline void Dtool_PyModuleClassInit_DTOOL_SUPPER_BASE(PyObject *module) -{ - static bool initdone = false; - if(!initdone) - { + initdone = true; + Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict = PyDict_New(); + PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict); - initdone = true; - Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject().tp_dict = PyDict_New(); - PyDict_SetItemString(Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject().tp_dict,"DtoolClassDict",Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject().tp_dict); - - // __hash__ - Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject().tp_hash = &DTool_HashKey_Methods_DTOOL_SUPPER_BASE; - Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject().tp_compare = &DTOOL_PyObject_Compare; - - if(PyType_Ready(&Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject()) < 0) - { - PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPPER_BASE)"); - return; - } - Py_INCREF(&Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject()); - - PyDict_SetItemString(Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject().tp_dict,"DtoolGetSupperBase",PyCFunction_New(&Dtool_Methods_DTOOL_SUPPER_BASE[0],&Dtool_DTOOL_SUPPER_BASE.As_PyObject())); + // __hash__ + Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_hash = &DTool_HashKey_Methods_DTOOL_SUPER_BASE; +#if PY_MAJOR_VERSION >= 3 + // Python 3 removed the regular tp_compare function - there is only tp_richcompare. + Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_richcompare = &DTOOL_PyObject_RichCompare; +#else + Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_compare = &DTOOL_PyObject_Compare; +#endif + if (PyType_Ready(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject()) < 0) { + PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)"); + return; } + Py_INCREF(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject()); - if(module != NULL) - { - Py_INCREF(&Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject()); - PyModule_AddObject(module, "DTOOL_SUPPER_BASE",(PyObject *)&Dtool_DTOOL_SUPPER_BASE.As_PyTypeObject()); - } + PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE.As_PyTypeObject().tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], &Dtool_DTOOL_SUPER_BASE.As_PyObject())); + } + + if (module != NULL) { + Py_INCREF(&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject()); + PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE.As_PyTypeObject()); + } } -inline void * Dtool_DowncastInterface_DTOOL_SUPPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) -{ - return (void *) NULL; +inline void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) { + return (void *) NULL; } -inline void * Dtool_UpcastInterface_DTOOL_SUPPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) -{ - return NULL; +inline void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) { + return NULL; } -int Dtool_Init_DTOOL_SUPPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) -{ - PyErr_SetString(PyExc_TypeError, "Error Can Not Init SUPPER BASE"); - return -1; +int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, "cannot init super base"); + return -1; } #endif // HAVE_PYTHON diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 0e3d90d4db..da210dda5c 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -26,21 +26,20 @@ PyMemberDef standard_type_members[] = { {NULL} /* Sentinel */ }; - //////////////////////////////////////////////////////////////////////// /// Simple Recognition Functions.. //////////////////////////////////////////////////////////////////////// -bool DtoolCanThisBeAPandaInstance(PyObject *self) -{ - // simple sanity check for the class type..size.. will stop basic foobars.. - if(self->ob_type->tp_basicsize >= (int)sizeof(Dtool_PyInstDef)) - { - Dtool_PyInstDef * pyself = (Dtool_PyInstDef *) self; - if(pyself->_signature == PY_PANDA_SIGNATURE) - return true; +bool DtoolCanThisBeAPandaInstance(PyObject *self) { + // simple sanity check for the class type..size.. will stop basic foobars.. + if (Py_TYPE(self)->tp_basicsize >= (int)sizeof(Dtool_PyInstDef)) { + Dtool_PyInstDef *pyself = (Dtool_PyInstDef *) self; + if (pyself->_signature == PY_PANDA_SIGNATURE) { + return true; } - return false; + } + return false; } + //////////////////////////////////////////////////////////////////////// // Function : DTOOL_Call_ExtractThisPointerForType // @@ -48,13 +47,13 @@ bool DtoolCanThisBeAPandaInstance(PyObject *self) // needed by the Dtool py interface.. Be very careful if you muck with these // as the generated code depends on how this is set up.. //////////////////////////////////////////////////////////////////////// -void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer) -{ - if(DtoolCanThisBeAPandaInstance(self)) - *answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self,classdef); - else - answer = NULL; -}; +void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer) { + if (DtoolCanThisBeAPandaInstance(self)) { + *answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self,classdef); + } else { + *answer = NULL; + } +} //////////////////////////////////////////////////////////////////// // Function: attempt_coercion @@ -192,15 +191,23 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, PyObject *fname = PyObject_GetAttrString((PyObject *)classdef, "__name__"); if (fname != (PyObject *)NULL) { +#if PY_MAJOR_VERSION >= 3 + str << PyUnicode_AsUTF8(fname); +#else str << PyString_AsString(fname); +#endif Py_DECREF(fname); } else { str << classdef->_name; } - PyObject *tname = PyObject_GetAttrString((PyObject *)self->ob_type, "__name__"); + PyObject *tname = PyObject_GetAttrString((PyObject *)Py_TYPE(self), "__name__"); if (tname != (PyObject *)NULL) { +#if PY_MAJOR_VERSION >= 3 + str << ", not " << PyUnicode_AsUTF8(tname); +#else str << ", not " << PyString_AsString(tname); +#endif Py_DECREF(tname); } else { str << ", not " << my_type->_name; @@ -226,15 +233,23 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, PyObject *fname = PyObject_GetAttrString((PyObject *)classdef, "__name__"); if (fname != (PyObject *)NULL) { +#if PY_MAJOR_VERSION >= 3 + str << PyUnicode_AsUTF8(fname); +#else str << PyString_AsString(fname); +#endif Py_DECREF(fname); } else { str << classdef->_name; } - PyObject *tname = PyObject_GetAttrString((PyObject *)self->ob_type, "__name__"); + PyObject *tname = PyObject_GetAttrString((PyObject *)Py_TYPE(self), "__name__"); if (tname != (PyObject *)NULL) { +#if PY_MAJOR_VERSION >= 3 + str << ", not " << PyUnicode_AsUTF8(tname); +#else str << ", not " << PyString_AsString(tname); +#endif Py_DECREF(tname); } @@ -244,26 +259,23 @@ DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, } } else { if (report_errors) { - PyErr_SetString(PyExc_TypeError, "Self Is Null"); + PyErr_SetString(PyExc_TypeError, "self is NULL"); } } return NULL; } -void * DTOOL_Call_GetPointerThis(PyObject *self) -{ - if(self != NULL) - { - if(DtoolCanThisBeAPandaInstance(self)) - { - Dtool_PyInstDef * pyself = (Dtool_PyInstDef *) self; - return pyself->_ptr_to_object; - } +void *DTOOL_Call_GetPointerThis(PyObject *self) { + if (self != NULL) { + if (DtoolCanThisBeAPandaInstance(self)) { + Dtool_PyInstDef * pyself = (Dtool_PyInstDef *) self; + return pyself->_ptr_to_object; + } } return NULL; -}; +} //////////////////////////////////////////////////////////////////////// // Function : DTool_CreatePyInstanceTyped @@ -271,128 +283,113 @@ void * DTOOL_Call_GetPointerThis(PyObject *self) // this function relies on the behavior of typed objects in the panda system. // //////////////////////////////////////////////////////////////////////// -PyObject * DTool_CreatePyInstanceTyped(void * local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, bool is_const, int RunTimeType) -{ - if(local_this_in == NULL ) - { - // Lets don't be stupid.. - PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this'"); - return NULL; - } - ///////////////////////////////////////////////////// - // IF the calss is posibly a run time typed object - ///////////////////////////////////////////////////// - if(RunTimeType > 0) - { - ///////////////////////////////////////////////////// - // get best fit class... - ///////////////////////////////////////////////////// - Dtool_PyTypedObject * target_class = Dtool_RuntimeTypeDtoolType(RunTimeType); - if(target_class != NULL) - { - ///////////////////////////////////////////////////// - // cast to the type... - ////////////////////////////////////////////////////// - void * new_local_this = target_class->_Dtool_DowncastInterface(local_this_in,&known_class_type); - if(new_local_this != NULL) - { - ///////////////////////////////////////////// - // ask class to allocate a instance.. - ///////////////////////////////////////////// - Dtool_PyInstDef * self = (Dtool_PyInstDef *) target_class->As_PyTypeObject().tp_new(&target_class->As_PyTypeObject(), NULL,NULL); - if(self != NULL) - { - self->_ptr_to_object = new_local_this; - self->_memory_rules = memory_rules; - self->_is_const = is_const; - self->_signature = PY_PANDA_SIGNATURE; - self->_My_Type = target_class; - return (PyObject *)self; - } - } - } - } +PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, bool is_const, int RunTimeType) { + if (local_this_in == NULL) { + // Let's not be stupid.. + PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this'"); + return NULL; + } + ///////////////////////////////////////////////////// + // IF the class is possibly a run time typed object + ///////////////////////////////////////////////////// + if (RunTimeType > 0) { ///////////////////////////////////////////////////// - // if we get this far .. just wrap the thing in the known type ?? - // better than aborting...I guess.... + // get best fit class... ///////////////////////////////////////////////////// - Dtool_PyInstDef * self = (Dtool_PyInstDef *) known_class_type.As_PyTypeObject().tp_new(&known_class_type.As_PyTypeObject(), NULL,NULL); - if(self != NULL) - { - self->_ptr_to_object = local_this_in; - self->_memory_rules = memory_rules; - self->_is_const = is_const; - self->_signature = PY_PANDA_SIGNATURE; - self->_My_Type = &known_class_type; + Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(RunTimeType); + if (target_class != NULL) { + ///////////////////////////////////////////////////// + // cast to the type... + ////////////////////////////////////////////////////// + void *new_local_this = target_class->_Dtool_DowncastInterface(local_this_in, &known_class_type); + if (new_local_this != NULL) { + ///////////////////////////////////////////// + // ask class to allocate an instance.. + ///////////////////////////////////////////// + Dtool_PyInstDef *self = (Dtool_PyInstDef *) target_class->As_PyTypeObject().tp_new(&target_class->As_PyTypeObject(), NULL, NULL); + if (self != NULL) { + self->_ptr_to_object = new_local_this; + self->_memory_rules = memory_rules; + self->_is_const = is_const; + self->_signature = PY_PANDA_SIGNATURE; + self->_My_Type = target_class; + return (PyObject *)self; + } + } } - return (PyObject *)self; -}; + } + + ///////////////////////////////////////////////////// + // if we get this far .. just wrap the thing in the known type ?? + // better than aborting...I guess.... + ///////////////////////////////////////////////////// + Dtool_PyInstDef * self = (Dtool_PyInstDef *) known_class_type.As_PyTypeObject().tp_new(&known_class_type.As_PyTypeObject(), NULL, NULL); + if (self != NULL) { + self->_ptr_to_object = local_this_in; + self->_memory_rules = memory_rules; + self->_is_const = is_const; + self->_signature = PY_PANDA_SIGNATURE; + self->_My_Type = &known_class_type; + } + return (PyObject *)self; +} //////////////////////////////////////////////////////////////////////// // DTool_CreatePyInstance .. wrapper function to finalize the existance of a general // dtool py instance.. //////////////////////////////////////////////////////////////////////// -PyObject * DTool_CreatePyInstance(void * local_this, Dtool_PyTypedObject & in_classdef, bool memory_rules, bool is_const) -{ - if(local_this == NULL) - { - PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this' "); - return NULL; - } +PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const) { + if (local_this == NULL) { + PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this'"); + return NULL; + } - Dtool_PyTypedObject * classdef = &in_classdef; - Dtool_PyInstDef * self = (Dtool_PyInstDef *) classdef->As_PyTypeObject().tp_new(&classdef->As_PyTypeObject(), NULL,NULL); - if(self != NULL) - { - self->_ptr_to_object = local_this; - self->_memory_rules = memory_rules; - self->_is_const = is_const; - self->_My_Type = classdef; - } - return (PyObject *)self; -}; + Dtool_PyTypedObject *classdef = &in_classdef; + Dtool_PyInstDef *self = (Dtool_PyInstDef *) classdef->As_PyTypeObject().tp_new(&classdef->As_PyTypeObject(), NULL, NULL); + if (self != NULL) { + self->_ptr_to_object = local_this; + self->_memory_rules = memory_rules; + self->_is_const = is_const; + self->_My_Type = classdef; + } + return (PyObject *)self; +} /////////////////////////////////////////////////////////////////////////////// /// Th Finalizer for simple instances.. /////////////////////////////////////////////////////////////////////////////// -int DTool_PyInit_Finalize(PyObject * self, void * 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 .. +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 = This; - ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules; - ((Dtool_PyInstDef *)self)->_is_const = is_const; - return 0; + ((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 heler function to glu methed definition together .. that can not be done at -// code generation time becouse of multiple generation passes in interigate.. +// 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 != NULL; in++) - { - if(themap.find(in->ml_name) == themap.end()) - { - themap[in->ml_name] = in; - } +void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) { + for (; in->ml_name != NULL; in++) { + if (themap.find(in->ml_name) == themap.end()) { + themap[in->ml_name] = in; } + } } /////////////////////////////////////////////////////////////////////////////// -// ** HACK ** allert.. +// ** HACK ** alert.. // // 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. // /////////////////////////////////////////////////////////////////////////////// - void RegisterRuntimeClass(Dtool_PyTypedObject * otype, int class_id) { if (class_id == 0) { @@ -417,113 +414,126 @@ RegisterRuntimeClass(Dtool_PyTypedObject * otype, int class_id) { otype->_Dtool_IsRunTimeCapable = true; } } -}; - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type) -{ - RunTimeTypeDictionary::iterator di = GetRunTimeDictionary().find(type); - if(di != GetRunTimeDictionary().end()) - return di->second; - else - { - int type2 = get_best_parent_from_Set(type,GetRunTimeTypeList()); - di = GetRunTimeDictionary().find(type2); - if(di != GetRunTimeDictionary().end()) - return di->second; - } - return NULL; -}; - -/////////////////////////////////////////////////////////////////////////////// -void Dtool_PyModuleInitHelper( LibrayDef *defs[], const char * modulename) -{ - // the module level function inits.... - MethodDefmap functions; - for(int xx = 0; defs[xx] != NULL; xx++) - Dtool_Accum_MethDefs(defs[xx]->_methods,functions); - - PyMethodDef *newdef = new PyMethodDef[functions.size()+1]; - MethodDefmap::iterator mi; - int offset = 0; - for(mi = functions.begin(); mi != functions.end(); mi++, offset++) - newdef[offset] = *mi->second; - newdef[offset].ml_doc = NULL; - newdef[offset].ml_name = NULL; - newdef[offset].ml_meth = NULL; - newdef[offset].ml_flags = 0; - - PyObject * module = Py_InitModule((char *)modulename,newdef); - - if(module == NULL) - { - PyErr_SetString(PyExc_TypeError, "Py_InitModule Returned NULL ???"); - return; - } - - - // the constant inits... enums, classes ... - for(int y = 0; defs[y] != NULL; y++) - defs[y]->_constants(module); - - PyModule_AddIntConstant(module,"Dtool_PyNativeInterface",1); } + /////////////////////////////////////////////////////////////////////////////// -/// HACK.... Be carefull +/////////////////////////////////////////////////////////////////////////////// +Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) { + RunTimeTypeDictionary::iterator di = GetRunTimeDictionary().find(type); + if (di != GetRunTimeDictionary().end()) { + return di->second; + } else { + int type2 = get_best_parent_from_Set(type, GetRunTimeTypeList()); + di = GetRunTimeDictionary().find(type2); + if (di != GetRunTimeDictionary().end()) { + return di->second; + } + } + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) { + // the module level function inits.... + MethodDefmap functions; + for (int xx = 0; defs[xx] != NULL; xx++) { + Dtool_Accum_MethDefs(defs[xx]->_methods, functions); + } + + PyMethodDef *newdef = new PyMethodDef[functions.size() + 1]; + MethodDefmap::iterator mi; + int offset = 0; + for (mi = functions.begin(); mi != functions.end(); mi++, offset++) { + newdef[offset] = *mi->second; + } + newdef[offset].ml_doc = NULL; + newdef[offset].ml_name = NULL; + newdef[offset].ml_meth = NULL; + newdef[offset].ml_flags = 0; + +#if PY_MAJOR_VERSION >= 3 + struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + modulename, + NULL, + -1, + newdef, + NULL, NULL, NULL, NULL + }; + PyObject *module = PyModule_Create(&moduledef); +#else + PyObject *module = Py_InitModule((char *)modulename, newdef); +#endif + + if (module == NULL) { +#if PY_MAJOR_VERSION >= 3 + PyErr_SetString(PyExc_TypeError, "PyModule_Create returned NULL"); +#else + PyErr_SetString(PyExc_TypeError, "Py_InitModule returned NULL"); +#endif + return NULL; + } + + + // the constant inits... enums, classes ... + for (int y = 0; defs[y] != NULL; y++) { + defs[y]->_constants(module); + } + + PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1); + + return module; +} + +/////////////////////////////////////////////////////////////////////////////// +/// HACK.... Be careful // // Dtool_BorrowThisReference // This function can be used to grab the "THIS" pointer from an object and use it // Required to support historical inheritance in the form of "is this instance of".. // /////////////////////////////////////////////////////////////////////////////// -PyObject * Dtool_BorrowThisReference(PyObject * self, PyObject * args ) -{ - PyObject *from_in = NULL; - PyObject *to_in = NULL; - if(PyArg_ParseTuple(args, "OO", &to_in, &from_in)) - { +PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) { + PyObject *from_in = NULL; + PyObject *to_in = NULL; + if (PyArg_ParseTuple(args, "OO", &to_in, &from_in)) { - if(DtoolCanThisBeAPandaInstance(from_in) && DtoolCanThisBeAPandaInstance(to_in)) - { - Dtool_PyInstDef * from = (Dtool_PyInstDef *) from_in; - Dtool_PyInstDef * to = (Dtool_PyInstDef *) to_in; - if(from->_My_Type == to->_My_Type) - { - to->_memory_rules = false; - to->_is_const = from->_is_const; - to->_ptr_to_object = from->_ptr_to_object; - return Py_BuildValue(""); - } - PyErr_SetString(PyExc_TypeError, "Must Be Same Type??"); - } - else - PyErr_SetString(PyExc_TypeError, "One of these does not appear to be DTOOL Instance ??"); + if (DtoolCanThisBeAPandaInstance(from_in) && DtoolCanThisBeAPandaInstance(to_in)) { + Dtool_PyInstDef * from = (Dtool_PyInstDef *) from_in; + Dtool_PyInstDef * to = (Dtool_PyInstDef *) to_in; + if (from->_My_Type == to->_My_Type) { + to->_memory_rules = false; + to->_is_const = from->_is_const; + to->_ptr_to_object = from->_ptr_to_object; + return Py_BuildValue(""); + } + PyErr_SetString(PyExc_TypeError, "Must Be Same Type??"); + } else { + PyErr_SetString(PyExc_TypeError, "One of these does not appear to be DTOOL Instance ??"); } - return (PyObject *) NULL; + } + return (PyObject *) NULL; } + ////////////////////////////////////////////////////////////////////////////////////////////// // We do expose a dictionay for dtool classes .. this should be removed at some point.. ////////////////////////////////////////////////////////////////////////////////////////////// -PyObject * Dtool_AddToDictionary(PyObject * self1, PyObject * args ) -{ - - PyObject * self; - PyObject * subject; - PyObject * key; - if(PyArg_ParseTuple(args, "OSO", &self, &key, &subject)) - { - PyObject * dict = ((PyTypeObject *)self)->tp_dict; - if(dict == NULL && !PyDict_Check(dict)) - PyErr_SetString(PyExc_TypeError, "No dictionary On Object"); - else - PyDict_SetItem(dict,key,subject); - - } - if(PyErr_Occurred()) - return (PyObject *)NULL; - return Py_BuildValue(""); - +PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) { + PyObject *self; + PyObject *subject; + PyObject *key; + if (PyArg_ParseTuple(args, "OSO", &self, &key, &subject)) { + PyObject *dict = ((PyTypeObject *)self)->tp_dict; + if (dict == NULL && !PyDict_Check(dict)) { + PyErr_SetString(PyExc_TypeError, "No dictionary On Object"); + } else { + PyDict_SetItem(dict,key,subject); + } + } + if (PyErr_Occurred()) { + return (PyObject *)NULL; + } + return Py_BuildValue(""); } /////////////////////////////////////////////////////////////////////////////////// /* @@ -533,8 +543,8 @@ inline long DTool_HashKey(PyObject * inst) PyObject * func = PyObject_GetAttrString(inst, "__hash__"); if (func == NULL) { - if(DtoolCanThisBeAPandaInstance(inst)) - if(((Dtool_PyInstDef *)inst)->_ptr_to_object != NULL) + if (DtoolCanThisBeAPandaInstance(inst)) + if (((Dtool_PyInstDef *)inst)->_ptr_to_object != NULL) outcome = (long)((Dtool_PyInstDef *)inst)->_ptr_to_object; } else @@ -569,131 +579,115 @@ inline long DTool_HashKey(PyObject * inst) XXX of error. */ -int DTOOL_PyObject_Compare_old(PyObject *v1, PyObject *v2) -{ - // if we are related.. - if(PyType_IsSubtype(v1->ob_type, v2->ob_type)) - { - void * v1_this = DTOOL_Call_GetPointerThis(v1); - void * v2_this = DTOOL_Call_GetPointerThis(v2); - if(v1_this != NULL && v2_this != NULL) // both are our types... - { - PyObject * func = PyObject_GetAttrString(v1, "compareTo"); - if (func == NULL) - { - PyErr_Clear(); - } - else - { - PyObject * res = NULL; - PyObject * args = Py_BuildValue("(O)", v2); - if (args != NULL) - { - res = PyObject_Call(func, args, NULL); - Py_DECREF(args); - } - Py_DECREF(func); - PyErr_Clear(); // just in case the function threw an error - // only use if the function return an INT... hmm - if(res != NULL && PyInt_Check(res)) - { - int answer = PyInt_AsLong(res); - Py_DECREF(res); - return answer; - } - if(res != NULL) - Py_DECREF(res); - - }; - // CompareTo Failed some how :( - // do a this compare .. if Possible... - if(v1_this < v2_this) - return -1; - - if(v1_this > v2_this) - return 1; - return 0; - } - // ok drop to a basic object compare hmmmmmm +int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2) { + // First try compareTo function.. + PyObject * func = PyObject_GetAttrString(v1, "compareTo"); + if (func == NULL) { + PyErr_Clear(); + } else { + PyObject *res = NULL; + PyObject *args = Py_BuildValue("(O)", v2); + if (args != NULL) { + res = PyObject_Call(func, args, NULL); + Py_DECREF(args); } - if(v1 < v2) - return -1; - if(v1 > v2) - return 1; - return 0; + Py_DECREF(func); + PyErr_Clear(); // just in case the function threw an error + // only use if the function returns an INT... hmm + if (res != NULL) { + if (PyLong_Check(res)) { + long answer = PyLong_AsLong(res); + Py_DECREF(res); + + // Python really wants us to return strictly -1, 0, or 1. + if (answer < 0) { + return -1; + } else if (answer > 0) { + return 1; + } else { + return 0; + } + } +#if PY_MAJOR_VERSION < 3 + else if (PyInt_Check(res)) { + long answer = PyInt_AsLong(res); + Py_DECREF(res); + + // Python really wants us to return strictly -1, 0, or 1. + if (answer < 0) { + return -1; + } else if (answer > 0) { + return 1; + } else { + return 0; + } + } +#endif + Py_DECREF(res); + } + }; + + // try this compare + void *v1_this = DTOOL_Call_GetPointerThis(v1); + void *v2_this = DTOOL_Call_GetPointerThis(v2); + if (v1_this != NULL && v2_this != NULL) { // both are our types... + if (v1_this < v2_this) + return -1; + + if (v1_this > v2_this) + return 1; + return 0; + } + + // ok self compare... + if (v1 < v2) + return -1; + if (v1 > v2) + return 1; + return 0; } - - - -int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2) -{ - // First try compare to function.. - PyObject * func = PyObject_GetAttrString(v1, "compareTo"); - if (func == NULL) - { - PyErr_Clear(); - } - else - { - PyObject * res = NULL; - PyObject * args = Py_BuildValue("(O)", v2); - if (args != NULL) - { - res = PyObject_Call(func, args, NULL); - Py_DECREF(args); - } - Py_DECREF(func); - PyErr_Clear(); // just in case the function threw an error - // only use if the function return an INT... hmm - if(res != NULL && PyInt_Check(res)) - { - int answer = PyInt_AsLong(res); - Py_DECREF(res); - - // Python really wants us to return strictly -1, 0, or 1. - if (answer < 0) { - return -1; - } else if (answer > 0) { - return 1; - } else { - return 0; - } - } - if(res != NULL) - Py_DECREF(res); - - }; - - // try this compare - void * v1_this = DTOOL_Call_GetPointerThis(v1); - void * v2_this = DTOOL_Call_GetPointerThis(v2); - if(v1_this != NULL && v2_this != NULL) // both are our types... - { - if(v1_this < v2_this) - return -1; - - if(v1_this > v2_this) - return 1; - return 0; - } - - // ok self compare... - if(v1 < v2) - return -1; - if(v1 > v2) - return 1; - return 0; +PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) { + int cmpval = DTOOL_PyObject_Compare(v1, v2); + bool result; + switch (op) { + case Py_LT: + result = (cmpval < 0); + break; + case Py_LE: + result = (cmpval <= 0); + break; + case Py_EQ: + result = (cmpval == 0); + break; + case Py_NE: + result = (cmpval != 0); + break; + case Py_GT: + result = (cmpval > 0); + break; + case Py_GE: + result = (cmpval >= 0); + } + return PyBool_FromLong(result); } - PyObject *make_list_for_item(PyObject *self, const char *num_name, const char *element_name) { PyObject *num_result = PyObject_CallMethod(self, (char *)num_name, (char *)"()"); if (num_result == NULL) { return NULL; } - Py_ssize_t num_elements = PyInt_AsSsize_t(num_result); + +#if PY_MAJOR_VERSION >= 3 + Py_ssize_t num_elements = PyLong_AsSsize_t(num_result); +#else + if (PyLong_Check(num_result)) { + Py_ssize_t num_elements = PyLong_AsSsize_t(num_result); + } else { + Py_ssize_t num_elements = PyInt_AsSsize_t(num_result); + } +#endif Py_DECREF(num_result); PyObject *list = PyList_New(num_elements); @@ -752,12 +746,16 @@ PyObject *map_deepcopy_to_copy(PyObject *self, PyObject *args) { //////////////////////////////////////////////////////////////////// EXPCL_DTOOLCONFIG PyObject * PyLongOrInt_FromUnsignedLong(unsigned long value) { +#if PY_MAJOR_VERSION >= 3 + // Python 3 only has longs. + return PyLong_FromUnsignedLong(value); +#else if ((long)value < 0) { return PyLong_FromUnsignedLong(value); } else { return PyInt_FromLong((long)value); } +#endif } - #endif // HAVE_PYTHON diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 8d65517d0b..4c6518e962 100755 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -83,38 +83,62 @@ inline PyObject* doPy_RETURN_FALSE() #define Py_RETURN_FALSE return doPy_RETURN_FALSE() #endif +#ifndef PyVarObject_HEAD_INIT +#define PyVarObject_HEAD_INIT(type, size) \ + PyObject_HEAD_INIT(type) size, +#endif + +#ifndef Py_TYPE +#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#endif + +#ifndef Py_TPFLAGS_CHECKTYPES +// Always on in Python 3 +#define Py_TPFLAGS_CHECKTYPES 0 +#endif + +#if PY_MAJOR_VERSION < 3 +// For more portably defining hash functions. +typedef long Py_hash_t; +#endif + +#if PY_MAJOR_VERSION >= 3 +#define nb_nonzero nb_bool +#define nb_divide nb_true_divide +#define nb_inplace_divide nb_inplace_true_divide +#endif + using namespace std; -#define PY_PANDA_SMALLER_FOOTPRINT 1 +#define PY_PANDA_SMALLER_FOOTPRINT 1 /////////////////////////////////////////////////////////////////////////////////// // this is tempory .. untill this is glued better into the panda build system /////////////////////////////////////////////////////////////////////////////////// #if defined(_WIN32) && !defined(LINK_ALL_STATIC) -#define EXPORT_THIS __declspec(dllexport) -#define IMPORT_THIS extern __declspec(dllimport) +#define EXPORT_THIS __declspec(dllexport) +#define IMPORT_THIS extern __declspec(dllimport) #else -#define EXPORT_THIS -#define IMPORT_THIS extern +#define EXPORT_THIS +#define IMPORT_THIS extern #endif /////////////////////////////////////////////////////////////////////////////////// -struct Dtool_PyTypedObject; -typedef std::map< int , Dtool_PyTypedObject *> RunTimeTypeDictionary; -typedef std::set RunTimeTypeList; - -EXPCL_DTOOLCONFIG RunTimeTypeDictionary & GetRunTimeDictionary(); -EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList(); +struct Dtool_PyTypedObject; +typedef std::map RunTimeTypeDictionary; +typedef std::set RunTimeTypeList; +EXPCL_DTOOLCONFIG RunTimeTypeDictionary &GetRunTimeDictionary(); +EXPCL_DTOOLCONFIG RunTimeTypeList &GetRunTimeTypeList(); ////////////////////////////////////////////////////////// // used to stamp dtool instance.. #define PY_PANDA_SIGNATURE 0xbeaf -typedef void * ( * ConvertFunctionType )(PyObject *,Dtool_PyTypedObject * ); -typedef void * ( * ConvertFunctionType1 )(void *, Dtool_PyTypedObject *); -typedef void ( *FreeFunction )(PyObject *); -typedef void ( *PyModuleClassInit)(PyObject *module); +typedef void * ( * ConvertFunctionType )(PyObject *,Dtool_PyTypedObject * ); +typedef void * ( * ConvertFunctionType1 )(void *, Dtool_PyTypedObject *); +typedef void ( *FreeFunction )(PyObject *); +typedef void ( *PyModuleClassInit)(PyObject *module); //inline Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type); inline void Dtool_Deallocate_General(PyObject * self); //inline int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2); @@ -124,8 +148,7 @@ inline void Dtool_Deallocate_General(PyObject * self); //////////////////////////////////////////////////////////////////////// #ifdef PY_PANDA_SMALLER_FOOTPRINT // this should save 8 bytes per object .... -struct Dtool_PyInstDef -{ +struct Dtool_PyInstDef { PyObject_HEAD void *_ptr_to_object; struct Dtool_PyTypedObject *_My_Type; @@ -134,8 +157,6 @@ struct Dtool_PyInstDef int _is_const : 1; // true if this is a "const" pointer. }; - - #else struct Dtool_PyInstDef { PyObject_HEAD @@ -159,7 +180,7 @@ struct Dtool_PyTypedObject { // Standard Python Features.. PyTypeObject _PyType; - // My Class Level Features.. + // My Class Level Features.. const char *_name; // cpp name for the object bool _Dtool_IsRunTimeCapable; // derived from TypedObject ConvertFunctionType _Dtool_UpcastInterface; // The Upcast Function By Slot @@ -172,10 +193,123 @@ struct Dtool_PyTypedObject { inline PyObject &As_PyObject() { return (PyObject &)_PyType; }; }; - //////////////////////////////////////////////////////////////////////// // Macros from Hell.. May want to just add this to the code generator.. //////////////////////////////////////////////////////////////////////// +#define Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \ + EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME = \ + { \ + { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + "lib" #MODULE_NAME "." #PUBLIC_NAME, /*type name with module */ \ + sizeof(Dtool_PyInstDef), /* tp_basicsize */ \ + 0, /* tp_itemsize */ \ + &Dtool_Deallocate_General, /* tp_dealloc */ \ + 0, /* tp_print */ \ + 0, /* tp_getattr */ \ + 0, /* tp_setattr */ \ + 0, /* tp_compare */ \ + 0, /* tp_repr */ \ + &Dtool_PyNumberMethods_##CLASS_NAME, /* tp_as_number */ \ + &Dtool_PySequenceMethods_##CLASS_NAME, /* tp_as_sequence */ \ + &Dtool_PyMappingMethods_##CLASS_NAME, /* tp_as_mapping */ \ + 0, /* tp_hash */ \ + 0, /* tp_call */ \ + 0, /* tp_str */ \ + PyObject_GenericGetAttr, /* tp_getattro */ \ + PyObject_GenericSetAttr, /* tp_setattro */ \ + 0, /* tp_as_buffer */ \ + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), /* tp_flags */ \ + 0, /* tp_doc */ \ + 0, /* tp_traverse */ \ + 0, /* tp_clear */ \ + 0, /* tp_richcompare */ \ + 0, /* tp_weaklistoffset */ \ + 0, /* tp_iter */ \ + 0, /* tp_iternext */ \ + Dtool_Methods_##CLASS_NAME, /* tp_methods */ \ + standard_type_members, /* tp_members */ \ + 0, /* tp_getset */ \ + 0, /* tp_base */ \ + 0, /* tp_dict */ \ + 0, /* tp_descr_get */ \ + 0, /* tp_descr_set */ \ + 0, /* tp_dictoffset */ \ + Dtool_Init_##CLASS_NAME, /* tp_init */ \ + PyType_GenericAlloc, /* tp_alloc */ \ + Dtool_new_##CLASS_NAME, /* tp_new */ \ + PyObject_Del, /* tp_free */ \ + }, \ + #CLASS_NAME, \ + false, \ + Dtool_UpcastInterface_##CLASS_NAME, \ + Dtool_DowncastInterface_##CLASS_NAME, \ + Dtool_FreeInstance_##CLASS_NAME, \ + Dtool_PyModuleClassInit_##CLASS_NAME \ + }; + +#if PY_MAJOR_VERSION >= 3 +#define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \ + static PyNumberMethods Dtool_PyNumberMethods_##CLASS_NAME = \ + { \ + 0,/*binaryfunc nb_add*/ \ + 0,/*binaryfunc nb_subtract*/ \ + 0,/*binaryfunc nb_multiply*/ \ + 0,/*binaryfunc nb_remainder*/ \ + 0,/*binaryfunc nb_divmod*/ \ + 0,/*ternaryfunc nb_power*/ \ + 0,/*unaryfunc nb_negative*/ \ + 0,/*unaryfunc nb_positive*/ \ + 0,/*unaryfunc nb_absolute*/ \ + 0,/*inquiry nb_bool*/ \ + 0,/*unaryfunc nb_invert*/ \ + 0,/*binaryfunc nb_lshift*/ \ + 0,/*binaryfunc nb_rshift*/ \ + 0,/*binaryfunc nb_and*/ \ + 0,/*binaryfunc nb_xor*/ \ + 0,/*binaryfunc nb_or*/ \ + 0,/*unaryfunc nb_int*/ \ + 0,/*void *nb_reserved*/ \ + 0,/*unaryfunc nb_float*/ \ + 0,/*binaryfunc nb_inplace_add*/ \ + 0,/*binaryfunc nb_inplace_subtract*/ \ + 0,/*binaryfunc nb_inplace_multiply*/ \ + 0,/*binaryfunc nb_inplace_remainder*/ \ + 0,/*ternaryfunc nb_inplace_power*/ \ + 0,/*binaryfunc nb_inplace_lshift*/ \ + 0,/*binaryfunc nb_inplace_rshift*/ \ + 0,/*binaryfunc nb_inplace_and*/ \ + 0,/*binaryfunc nb_inplace_xor*/ \ + 0,/*binaryfunc nb_inplace_or*/ \ + 0,/*binaryfunc nb_floor_divide*/ \ + 0,/*binaryfunc nb_true_divide*/ \ + 0,/*binaryfunc nb_inplace_floor_divide*/ \ + 0,/*binaryfunc nb_inplace_true_divide*/ \ + 0,/*unaryfunc nb_index*/ \ + }; \ + static PySequenceMethods Dtool_PySequenceMethods_##CLASS_NAME = \ + { \ + 0,/*lenfunc sq_length */ \ + 0,/*binaryfunc sq_concat */ \ + 0,/*ssizeargfunc sq_repeat */ \ + 0,/*ssizeargfunc sq_item */ \ + 0,/*void *was_sq_slice */ \ + 0,/*ssizeargfunc sq_ass_item */ \ + 0,/*void *was_sq_ass_slice */ \ + 0,/*objobjproc sq_contains */ \ + 0,/*binaryfunc sq_inplace_concat */ \ + 0,/*ssizeargfunc sq_inplace_repeat */ \ + }; \ + static PyMappingMethods Dtool_PyMappingMethods_##CLASS_NAME = \ + { \ + 0,/*inquiry mp_length */ \ + 0,/*binaryfunc mp_subscript */ \ + 0,/*objobjargproc mp_ass_subscript */ \ + }; \ + Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) + +#else // Python 2: + #define Define_Dtool_Class(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) \ static PyNumberMethods Dtool_PyNumberMethods_##CLASS_NAME = \ { \ @@ -235,65 +369,15 @@ struct Dtool_PyTypedObject { 0,/*binaryfunc mp_subscript */ \ 0,/*objobjargproc mp_ass_subscript */ \ }; \ - EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME = \ - { \ - { \ - PyObject_HEAD_INIT(NULL) \ - 0, \ - "lib" #MODULE_NAME "." #PUBLIC_NAME, /*type name with module */ \ - sizeof(Dtool_PyInstDef), /* tp_basicsize */ \ - 0, /* tp_itemsize */ \ - &Dtool_Deallocate_General, /* tp_dealloc */ \ - 0, /* tp_print */ \ - 0, /* tp_getattr */ \ - 0, /* tp_setattr */ \ - 0, /* tp_compare */ \ - 0, /* tp_repr */ \ - &Dtool_PyNumberMethods_##CLASS_NAME, /* tp_as_number */ \ - &Dtool_PySequenceMethods_##CLASS_NAME, /* tp_as_sequence */ \ - &Dtool_PyMappingMethods_##CLASS_NAME, /* tp_as_mapping */ \ - 0, /* tp_hash */ \ - 0, /* tp_call */ \ - 0, /* tp_str */ \ - PyObject_GenericGetAttr, /* tp_getattro */ \ - PyObject_GenericSetAttr, /* tp_setattro */ \ - 0, /* tp_as_buffer */ \ - (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), /* tp_flags */ \ - 0, /* tp_doc */ \ - 0, /* tp_traverse */ \ - 0, /* tp_clear */ \ - 0, /* tp_richcompare */ \ - 0, /* tp_weaklistoffset */ \ - 0, /* tp_iter */ \ - 0, /* tp_iternext */ \ - Dtool_Methods_##CLASS_NAME, /* tp_methods */ \ - standard_type_members, /* tp_members */ \ - 0, /* tp_getset */ \ - 0, /* tp_base */ \ - 0, /* tp_dict */ \ - 0, /* tp_descr_get */ \ - 0, /* tp_descr_set */ \ - 0, /* tp_dictoffset */ \ - Dtool_Init_##CLASS_NAME, /* tp_init */ \ - PyType_GenericAlloc, /* tp_alloc */ \ - Dtool_new_##CLASS_NAME, /* tp_new */ \ - _PyObject_Del, /* tp_free */ \ - }, \ - #CLASS_NAME, \ - false, \ - Dtool_UpcastInterface_##CLASS_NAME, \ - Dtool_DowncastInterface_##CLASS_NAME, \ - Dtool_FreeInstance_##CLASS_NAME, \ - Dtool_PyModuleClassInit_##CLASS_NAME \ - }; - + Define_Dtool_PyTypedObject(MODULE_NAME, CLASS_NAME, PUBLIC_NAME) +#endif //////////////////////////////////////////////////////////////////////// // The Fast Deallocator.. for Our instances.. //////////////////////////////////////////////////////////////////////// inline void Dtool_Deallocate_General(PyObject * self) { ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_FreeInstance(self); - self->ob_type->tp_free(self); + Py_TYPE(self)->tp_free(self); } //////////////////////////////////////////////////////////////////////// @@ -367,12 +451,11 @@ EXPCL_DTOOLCONFIG bool DtoolCanThisBeAPandaInstance(PyObject *self); //////////////////////////////////////////////////////////////////////// EXPCL_DTOOLCONFIG void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject * classdef, void ** answer); +EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced, bool report_errors); -EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced, bool report_errors); +EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced); -EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const string &function_name, bool const_ok, PyObject **coerced); - -EXPCL_DTOOLCONFIG void * DTOOL_Call_GetPointerThis(PyObject *self); +EXPCL_DTOOLCONFIG void *DTOOL_Call_GetPointerThis(PyObject *self); //////////////////////////////////////////////////////////////////////// // Function : DTool_CreatePyInstanceTyped @@ -396,7 +479,7 @@ EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTyp //struct Dtool_PyTypedObject Dtool_##CLASS_NAME; #define Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ -extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME; \ +extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME;\ extern struct PyMethodDef Dtool_Methods_##CLASS_NAME[];\ int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\ PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\ @@ -443,9 +526,9 @@ EXPCL_DTOOLCONFIG int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_Py // code generation time becouse of multiple generation passes in interigate.. // /////////////////////////////////////////////////////////////////////////////// -typedef std::map MethodDefmap; +typedef std::map MethodDefmap; -EXPCL_DTOOLCONFIG void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap); +EXPCL_DTOOLCONFIG void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap); /////////////////////////////////////////////////////////////////////////////// // ** HACK ** allert.. @@ -459,22 +542,21 @@ EXPCL_DTOOLCONFIG void RegisterRuntimeClass(Dtool_PyTypedObject * otype, int cla /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -EXPCL_DTOOLCONFIG Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type); +EXPCL_DTOOLCONFIG Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type); /////////////////////////////////////////////////////////////////////////////// //// 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 LibrayDef -{ - typedef void ( *ConstantFunction )(PyObject *); +struct LibraryDef { + typedef void (*ConstantFunction)(PyObject *); - PyMethodDef * _methods; - ConstantFunction _constants; + PyMethodDef *_methods; + ConstantFunction _constants; }; /////////////////////////////////////////////////////////////////////////////// -EXPCL_DTOOLCONFIG void Dtool_PyModuleInitHelper( LibrayDef *defs[], const char * modulename); +EXPCL_DTOOLCONFIG PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename); /////////////////////////////////////////////////////////////////////////////// /// HACK.... Be carefull @@ -484,12 +566,12 @@ EXPCL_DTOOLCONFIG void Dtool_PyModuleInitHelper( LibrayDef *defs[], const char // Required to support fom historical inharatence in the for of "is this instance of".. // /////////////////////////////////////////////////////////////////////////////// -EXPCL_DTOOLCONFIG PyObject * Dtool_BorrowThisReference(PyObject * self, PyObject * args ); +EXPCL_DTOOLCONFIG PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args); ////////////////////////////////////////////////////////////////////////////////////////////// // We do expose a dictionay for dtool classes .. this should be removed at some point.. ////////////////////////////////////////////////////////////////////////////////////////////// -EXPCL_DTOOLCONFIG PyObject * Dtool_AddToDictionary(PyObject * self1, PyObject * args ); +EXPCL_DTOOLCONFIG PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args); /////////////////////////////////////////////////////////////////////////////////// /* @@ -535,10 +617,10 @@ EXPCL_DTOOLCONFIG long DTool_HashKey(PyObject * inst) XXX of error. */ -EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare_old(PyObject *v1, PyObject *v2); - EXPCL_DTOOLCONFIG int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2); +EXPCL_DTOOLCONFIG PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op); + EXPCL_DTOOLCONFIG PyObject * make_list_for_item(PyObject *self, const char *num_name, const char *element_name); @@ -555,10 +637,8 @@ map_deepcopy_to_copy(PyObject *self, PyObject *args); EXPCL_DTOOLCONFIG PyObject * PyLongOrInt_FromUnsignedLong(unsigned long value); -EXPCL_DTOOLCONFIG extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPPER_BASE; +EXPCL_DTOOLCONFIG extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE; #endif // HAVE_PYTHON && !CPPPARSER - #endif // PY_PANDA_H_ - diff --git a/panda/src/display/graphicsWindow.cxx b/panda/src/display/graphicsWindow.cxx index 36dbfd8f1a..99ec1e4eb3 100644 --- a/panda/src/display/graphicsWindow.cxx +++ b/panda/src/display/graphicsWindow.cxx @@ -917,13 +917,19 @@ void GraphicsWindow:: remove_python_event_handler(PyObject* name){ list toRemove; PythonWinProcClasses::iterator iter; - for(iter = _python_window_proc_classes.begin(); iter != _python_window_proc_classes.end(); ++iter){ + for (iter = _python_window_proc_classes.begin(); iter != _python_window_proc_classes.end(); ++iter) { PythonGraphicsWindowProc* pgwp = *iter; - if(PyObject_Compare(pgwp->get_name(), name) == 0) + if (PyObject_RichCompareBool(pgwp->get_name(), name, Py_EQ) == 1) { toRemove.push_back(pgwp); + } +#if PY_MAJOR_VERSION < 3 + else if (PyObject_Compare(pgwp->get_name(), name) == 0) { + toRemove.push_back(pgwp); + } +#endif } list::iterator iter2; - for(iter2 = toRemove.begin(); iter2 != toRemove.end(); ++iter2){ + for (iter2 = toRemove.begin(); iter2 != toRemove.end(); ++iter2) { PythonGraphicsWindowProc* pgwp = *iter2; remove_window_proc(pgwp); _python_window_proc_classes.erase(pgwp); diff --git a/panda/src/event/pythonTask.cxx b/panda/src/event/pythonTask.cxx index 548de2d841..1cbb8a389d 100644 --- a/panda/src/event/pythonTask.cxx +++ b/panda/src/event/pythonTask.cxx @@ -248,7 +248,11 @@ __setattr__(const string &attr_name, PyObject *v) { PyObject *str = PyObject_Repr(v); task_cat.debug() << *this << ": task." << attr_name << " = " - << PyString_AsString(str) << "\n"; +#if PY_MAJOR_VERSION >= 3 + << PyUnicode_AsUTF8(str) << "\n"; +#else + << PyString_AsString(str) << "\n"; +#endif Py_DECREF(str); } @@ -263,7 +267,11 @@ __setattr__(const string &attr_name, PyObject *v) { } } else if (attr_name == "name") { +#if PY_MAJOR_VERSION >= 3 + char *name = PyUnicode_AsUTF8(v); +#else char *name = PyString_AsString(v); +#endif if (name != (char *)NULL) { set_name(name); } @@ -307,19 +315,37 @@ PyObject *PythonTask:: __getattr__(const string &attr_name) const { if (attr_name == "time") { return PyFloat_FromDouble(get_elapsed_time()); + } else if (attr_name == "name") { +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(get_name().c_str()); +#else return PyString_FromString(get_name().c_str()); +#endif + } else if (attr_name == "wakeTime") { return PyFloat_FromDouble(get_wake_time()); + } else if (attr_name == "delayTime") { if (!has_delay()) { Py_RETURN_NONE; } return PyFloat_FromDouble(get_delay()); + } else if (attr_name == "frame") { +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(get_elapsed_frames()); +#else return PyInt_FromLong(get_elapsed_frames()); +#endif + } else if (attr_name == "id") { +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(_task_id); +#else return PyInt_FromLong(_task_id); +#endif + } else { return PyMapping_GetItemString(_dict, (char *)attr_name.c_str()); } @@ -389,10 +415,17 @@ do_python_task() { // henceforth, instead of calling the function from the top // again. if (task_cat.is_debug()) { +#if PY_MAJOR_VERSION >= 3 + PyObject *str = PyObject_ASCII(_function); + task_cat.debug() + << PyUnicode_AsUTF8(str) << " in " << *this + << " yielded a generator.\n"; +#else PyObject *str = PyObject_Repr(_function); - task_cat.debug() + task_cat.debug() << PyString_AsString(str) << " in " << *this << " yielded a generator.\n"; +#endif Py_DECREF(str); } _generator = result; @@ -439,8 +472,14 @@ do_python_task() { return DS_done; } +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + long retval = PyLong_AS_LONG(result); +#else if (PyInt_Check(result)) { - int retval = PyInt_AS_LONG(result); + long retval = PyInt_AS_LONG(result); +#endif + switch (retval) { case DS_again: Py_XDECREF(_generator); @@ -454,7 +493,7 @@ do_python_task() { case DS_pause: // Legitimate value. Py_DECREF(result); - return (DoneStatus)retval; + return (DoneStatus) retval; case -1: // Legacy value. @@ -467,10 +506,16 @@ do_python_task() { } } - PyObject *str = PyObject_Repr(result); ostringstream strm; +#if PY_MAJOR_VERSION >= 3 + PyObject *str = PyObject_ASCII(result); + strm + << *this << " returned " << PyUnicode_AsUTF8(str); +#else + PyObject *str = PyObject_Repr(result); strm << *this << " returned " << PyString_AsString(str); +#endif Py_DECREF(str); Py_DECREF(result); string message = strm.str(); @@ -590,10 +635,17 @@ call_owner_method(const char *method_name) { if (_owner != Py_None) { PyObject *func = PyObject_GetAttrString(_owner, (char *)method_name); if (func == (PyObject *)NULL) { +#if PY_MAJOR_VERSION >= 3 + PyObject *str = PyObject_ASCII(_owner); + task_cat.error() + << "Owner object " << PyUnicode_AsUTF8(str) << " added to " + << *this << " has no method " << method_name << "().\n"; +#else PyObject *str = PyObject_Repr(_owner); - task_cat.error() + task_cat.error() << "Owner object " << PyString_AsString(str) << " added to " << *this << " has no method " << method_name << "().\n"; +#endif Py_DECREF(str); } else { diff --git a/panda/src/express/pointerToArray.I b/panda/src/express/pointerToArray.I index b5969b6e55..3e035f458b 100644 --- a/panda/src/express/pointerToArray.I +++ b/panda/src/express/pointerToArray.I @@ -82,7 +82,8 @@ PointerToArray(const PointerToArray ©) : // Function: PointerToArray::Constructor // Access: Published // Description: This special constructor accepts a Python list of -// elements, or a Python string. +// elements, or a Python string (or a bytes object, +// in Python 3). //////////////////////////////////////////////////////////////////// template PointerToArray:: @@ -100,10 +101,33 @@ PointerToArray(PyObject *self, PyObject *sequence) : return; } + // If we were passed a Python string, then instead of storing it + // character-at-a-time, just load the whole string as a data + // buffer. +#if PY_MAJOR_VERSION >= 3 + if (PyBytes_Check(sequence)) { + int size = PyBytes_Size(sequence); + if (size % sizeof(Element) != 0) { + ostringstream stream; + stream << "Buffer not a multiple of " << sizeof(Element) << " bytes"; + string str = stream.str(); + PyErr_SetString(PyExc_ValueError, str.c_str()); + return; + } + + int num_elements = size / sizeof(Element); + insert(begin(), num_elements, Element()); + + // Hope there aren't any constructors or destructors involved + // here. + if (size != 0) { + const char *data = PyBytes_AsString(sequence); + memcpy(p(), data, size); + } + return; + } +#else if (PyString_CheckExact(sequence)) { - // If we were passed a Python string, then instead of storing it - // character-at-a-time, just load the whole string as a data - // buffer. int size = PyString_Size(sequence); if (size % sizeof(Element) != 0) { ostringstream stream; @@ -124,6 +148,7 @@ PointerToArray(PyObject *self, PyObject *sequence) : } return; } +#endif // Now construct the internal list by copying the elements // one-at-a-time from Python. diff --git a/panda/src/express/virtualFileSystem.cxx b/panda/src/express/virtualFileSystem.cxx index 1b84db4092..c0d85bac0d 100644 --- a/panda/src/express/virtualFileSystem.cxx +++ b/panda/src/express/virtualFileSystem.cxx @@ -925,7 +925,8 @@ get_global_ptr() { // Function: VirtualFileSystem::__py__read_file // Access: Published // Description: Convenience function; returns the entire contents of -// the indicated file as a string. +// the indicated file as a string (or as a bytes object, +// in Python 3). // // This variant on read_file() is implemented directly // for Python, as a small optimization, to avoid the @@ -938,11 +939,19 @@ __py__read_file(const Filename &filename, bool auto_unwrap) const { bool okflag = read_file(filename, pv, auto_unwrap); nassertr(okflag, NULL); +#if PY_MAJOR_VERSION >= 3 + if (pv.empty()) { + return PyBytes_FromStringAndSize("", 0); + } else { + return PyBytes_FromStringAndSize((const char *)&pv[0], pv.size()); + } +#else if (pv.empty()) { return PyString_FromStringAndSize("", 0); } else { return PyString_FromStringAndSize((const char *)&pv[0], pv.size()); } +#endif } #endif // HAVE_PYTHON @@ -1014,9 +1023,16 @@ PyObject *VirtualFileSystem:: __py__write_file(const Filename &filename, PyObject *data, bool auto_wrap) { char *buffer; Py_ssize_t length; + +#if PY_MAJOR_VERSION >= 3 + if (PyBytes_AsStringAndSize(data, &buffer, &length) == -1) { + return NULL; + } +#else if (PyString_AsStringAndSize(data, &buffer, &length) == -1) { return NULL; } +#endif bool result = write_file(filename, (const unsigned char *)buffer, length, auto_wrap); return PyBool_FromLong(result); diff --git a/panda/src/nativenet/buffered_datagramconnection.h b/panda/src/nativenet/buffered_datagramconnection.h index 2aada81b5b..6214c19357 100755 --- a/panda/src/nativenet/buffered_datagramconnection.h +++ b/panda/src/nativenet/buffered_datagramconnection.h @@ -243,7 +243,7 @@ inline bool Buffered_DatagramConnection::SendMessage(const Datagram &msg) nativenet_cat.warning() << "Buffered_DatagramConnection::SendMessage->Error On Write--Out Buffer = " << _Writer.AmountBuffered() << "\n"; #ifdef HAVE_PYTHON ostringstream s; - PyObject *exc_type = PyExc_StandardError; + PyObject *exc_type = PyExc_ConnectionError; s << endl << "Error sending message: " << endl; msg.dump_hex(s); diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index 5e516ee5b0..ec4a2c4639 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -1780,7 +1780,11 @@ get_tag_keys() const { PyObject *result = PyList_New(keys.size()); for (size_t i = 0; i < keys.size(); ++i) { const string &tag_name = keys[i]; +#if PY_MAJOR_VERSION >= 3 + PyObject *str = PyUnicode_FromStringAndSize(tag_name.data(), tag_name.size()); +#else PyObject *str = PyString_FromStringAndSize(tag_name.data(), tag_name.size()); +#endif PyList_SET_ITEM(result, i, str); } @@ -1801,7 +1805,11 @@ get_python_tag_keys() const { PyObject *result = PyList_New(keys.size()); for (size_t i = 0; i < keys.size(); ++i) { const string &tag_name = keys[i]; +#if PY_MAJOR_VERSION >= 3 + PyObject *str = PyUnicode_FromStringAndSize(tag_name.data(), tag_name.size()); +#else PyObject *str = PyString_FromStringAndSize(tag_name.data(), tag_name.size()); +#endif PyList_SET_ITEM(result, i, str); } @@ -1861,7 +1869,17 @@ compare_tags(const PandaNode *other) const { return cmp; } +#if PY_MAJOR_VERSION >= 3 + if (PyObject_RichCompareBool((*api).second, (*bpi).second, Py_LT) == 1) { + return -1; + } else if (PyObject_RichCompareBool((*api).second, (*bpi).second, Py_GT) == 1) { + return 1; + } else if (PyObject_RichCompareBool((*api).second, (*bpi).second, Py_EQ) == 1) { + cmp = 0; + } else { +#else if (PyObject_Cmp((*api).second, (*bpi).second, &cmp) == -1) { +#endif // Unable to compare objects; just compare pointers. if ((*api).second != (*bpi).second) { cmp = (*api).second < (*bpi).second ? -1 : 1;