Experimental Python 3 support to the C++ code including interrogate. Also adds support for rich comparison in interrogate.

This commit is contained in:
rdb 2013-02-16 19:22:26 +00:00
parent 441666fb79
commit 192d10b937
24 changed files with 2397 additions and 1507 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -8,6 +8,9 @@
///////////////////////////////////////////////////////////////////////
#include <Python.h>
#if PY_MAJOR_VERSION >= 3
#include <wchar.h>
#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();

View File

@ -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);
}
}

View File

@ -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')

View File

@ -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__',

View File

@ -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) == "<type 'libdtoolconfig.DTOOL_SUPPER_BASE111'>"
assert repr(dtoolSuperBase) == "<type 'libdtoolconfig.DTOOL_SUPER_BASE111'>" \
or repr(dtoolSuperBase) == "<type 'libdtoolconfig.DTOOL_SUPPER_BASE111'>"
safeReprNotify = None

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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<FunctionRemap*> &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<std::string> _external_imports;
};
#endif

View File

@ -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;

View File

@ -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)

View File

@ -51,8 +51,8 @@
#include <algorithm>
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; i<EXPORT_IMPORT_PREFEX.size(); i++)
EXPORT_IMPORT_PREFEX[i] = toupper(EXPORT_IMPORT_PREFEX[i]);
EXPORT_IMPORT_PREFIX = std::string("EXPCL_") + def->module_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";
}

View File

@ -110,7 +110,7 @@ int write_python_table_native(ostream &out) {
pset<std::string >::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;

View File

@ -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

View File

@ -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

View File

@ -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<int > RunTimeTypeList;
EXPCL_DTOOLCONFIG RunTimeTypeDictionary & GetRunTimeDictionary();
EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList();
struct Dtool_PyTypedObject;
typedef std::map<int, Dtool_PyTypedObject *> RunTimeTypeDictionary;
typedef std::set<int> 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<std::string, PyMethodDef * > MethodDefmap;
typedef std::map<std::string, PyMethodDef *> 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_

View File

@ -917,13 +917,19 @@ void GraphicsWindow::
remove_python_event_handler(PyObject* name){
list<PythonGraphicsWindowProc*> 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<PythonGraphicsWindowProc*>::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);

View File

@ -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 {

View File

@ -82,7 +82,8 @@ PointerToArray(const PointerToArray<Element> &copy) :
// 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<class Element>
PointerToArray<Element>::
@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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;