16 #include "config_interrogatedb.h"
20 PyMemberDef standard_type_members[] = {
21 {(
char *)
"this", (
sizeof(
void*) ==
sizeof(int)) ? T_UINT : T_ULONGLONG, offsetof(Dtool_PyInstDef, _ptr_to_object), READONLY, (
char *)
"C++ 'this' pointer, if any"},
22 {(
char *)
"this_ownership", T_BOOL, offsetof(Dtool_PyInstDef, _memory_rules), READONLY, (
char *)
"C++ 'this' ownership rules"},
23 {(
char *)
"this_const", T_BOOL, offsetof(Dtool_PyInstDef, _is_const), READONLY, (
char *)
"C++ 'this' const flag"},
25 {(
char *)
"this_metatype", T_OBJECT, offsetof(Dtool_PyInstDef, _My_Type), READONLY, (
char *)
"The dtool meta object"},
36 bool DtoolCanThisBeAPandaInstance(PyObject *
self) {
41 if (Py_TYPE(
self)->tp_basicsize >= (
int)
sizeof(Dtool_PyInstDef)) {
42 Dtool_PyInstDef *pyself = (Dtool_PyInstDef *)
self;
43 if (pyself->_signature == PY_PANDA_SIGNATURE) {
57 void DTOOL_Call_ExtractThisPointerForType(PyObject *
self, Dtool_PyTypedObject *classdef,
void **answer) {
58 if (DtoolCanThisBeAPandaInstance(
self)) {
59 *answer = ((Dtool_PyInstDef *)
self)->_My_Type->_Dtool_UpcastInterface(
self, classdef);
72 bool Dtool_Call_ExtractThisPointer(PyObject *
self, Dtool_PyTypedObject &classdef,
void **answer) {
73 if (
self == NULL || !DtoolCanThisBeAPandaInstance(
self)) {
74 Dtool_Raise_TypeError(
"C++ object is not yet constructed, or already destructed.");
78 *answer = ((Dtool_PyInstDef *)
self)->_My_Type->_Dtool_UpcastInterface(
self, &classdef);
93 bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *
self, Dtool_PyTypedObject &classdef,
94 void **answer,
const char *method_name) {
96 if (
self == NULL || !DtoolCanThisBeAPandaInstance(
self)) {
97 Dtool_Raise_TypeError(
"C++ object is not yet constructed, or already destructed.");
101 if (((Dtool_PyInstDef *)
self)->_is_const) {
103 PyErr_Format(PyExc_TypeError,
104 "Cannot call %s() on a const object.",
109 *answer = ((Dtool_PyInstDef *)
self)->_My_Type->_Dtool_UpcastInterface(
self, &classdef);
141 DTOOL_Call_GetPointerThisClass(PyObject *
self, Dtool_PyTypedObject *classdef,
142 int param,
const string &function_name,
bool const_ok,
143 bool report_errors) {
149 return Dtool_Raise_TypeError(
"self is NULL");
154 if (DtoolCanThisBeAPandaInstance(
self)) {
155 void *result = ((Dtool_PyInstDef *)
self)->_My_Type->_Dtool_UpcastInterface(
self, classdef);
157 if (result != NULL) {
158 if (const_ok || !((Dtool_PyInstDef *)
self)->_is_const) {
163 return PyErr_Format(PyExc_TypeError,
164 "%s() argument %d may not be const",
165 function_name.c_str(), param);
172 return Dtool_Raise_ArgTypeError(
self, param, function_name.c_str(), classdef->_PyType.tp_name);
178 void *DTOOL_Call_GetPointerThis(PyObject *
self) {
180 if (DtoolCanThisBeAPandaInstance(
self)) {
181 Dtool_PyInstDef * pyself = (Dtool_PyInstDef *)
self;
182 return pyself->_ptr_to_object;
203 bool Dtool_CheckErrorOccurred() {
204 if (_PyErr_OCCURRED()) {
208 Dtool_Raise_AssertionError();
221 PyObject *Dtool_Raise_AssertionError() {
223 #if PY_MAJOR_VERSION >= 3
228 Py_INCREF(PyExc_AssertionError);
229 PyErr_Restore(PyExc_AssertionError, message, (PyObject *)NULL);
239 PyObject *Dtool_Raise_TypeError(
const char *message) {
242 Py_INCREF(PyExc_TypeError);
243 #if PY_MAJOR_VERSION >= 3
244 PyErr_Restore(PyExc_TypeError, PyUnicode_FromString(message), (PyObject *)NULL);
246 PyErr_Restore(PyExc_TypeError, PyString_FromString(message), (PyObject *)NULL);
261 PyObject *Dtool_Raise_ArgTypeError(PyObject *obj,
int param,
const char *function_name,
const char *type_name) {
262 #if PY_MAJOR_VERSION >= 3
263 PyObject *message = PyUnicode_FromFormat(
265 PyObject *message = PyString_FromFormat(
267 "%s() argument %d must be %s, not %s",
268 function_name, param, type_name,
269 Py_TYPE(obj)->tp_name);
271 Py_INCREF(PyExc_TypeError);
272 PyErr_Restore(PyExc_TypeError, message, (PyObject *)NULL);
285 PyObject *Dtool_Raise_AttributeError(PyObject *obj,
const char *attribute) {
286 #if PY_MAJOR_VERSION >= 3
287 PyObject *message = PyUnicode_FromFormat(
289 PyObject *message = PyString_FromFormat(
291 "'%.100s' object has no attribute '%.200s'",
292 Py_TYPE(obj)->tp_name, attribute);
294 Py_INCREF(PyExc_TypeError);
295 PyErr_Restore(PyExc_TypeError, message, (PyObject *)NULL);
314 PyObject *_Dtool_Raise_BadArgumentsError() {
315 return Dtool_Raise_TypeError(
"arguments do not match any function overload");
323 PyObject *_Dtool_Return_None() {
324 if (_PyErr_OCCURRED()) {
329 return Dtool_Raise_AssertionError();
342 PyObject *Dtool_Return_Bool(
bool value) {
343 if (_PyErr_OCCURRED()) {
348 return Dtool_Raise_AssertionError();
351 PyObject *result = (value ? Py_True : Py_False);
362 PyObject *_Dtool_Return(PyObject *value) {
363 if (_PyErr_OCCURRED()) {
368 return Dtool_Raise_AssertionError();
380 PyObject *DTool_CreatePyInstanceTyped(
void *local_this_in, Dtool_PyTypedObject &known_class_type,
bool memory_rules,
bool is_const,
int type_index) {
385 nassertr(local_this_in != NULL, NULL);
390 if (type_index > 0) {
394 Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(type_index);
395 if (target_class != NULL) {
399 void *new_local_this = target_class->_Dtool_DowncastInterface(local_this_in, &known_class_type);
400 if (new_local_this != NULL) {
404 Dtool_PyInstDef *
self = (Dtool_PyInstDef *) target_class->As_PyTypeObject().tp_new(&target_class->As_PyTypeObject(), NULL, NULL);
406 self->_ptr_to_object = new_local_this;
407 self->_memory_rules = memory_rules;
408 self->_is_const = is_const;
410 self->_My_Type = target_class;
411 return (PyObject *)
self;
421 Dtool_PyInstDef *
self = (Dtool_PyInstDef *) known_class_type.As_PyTypeObject().tp_new(&known_class_type.As_PyTypeObject(), NULL, NULL);
423 self->_ptr_to_object = local_this_in;
424 self->_memory_rules = memory_rules;
425 self->_is_const = is_const;
427 self->_My_Type = &known_class_type;
429 return (PyObject *)
self;
436 PyObject *DTool_CreatePyInstance(
void *local_this, Dtool_PyTypedObject &in_classdef,
bool memory_rules,
bool is_const) {
437 if (local_this == NULL) {
444 Dtool_PyTypedObject *classdef = &in_classdef;
445 Dtool_PyInstDef *
self = (Dtool_PyInstDef *) classdef->As_PyTypeObject().tp_new(&classdef->As_PyTypeObject(), NULL, NULL);
447 self->_ptr_to_object = local_this;
448 self->_memory_rules = memory_rules;
449 self->_is_const = is_const;
450 self->_My_Type = classdef;
452 return (PyObject *)
self;
458 int DTool_PyInit_Finalize(PyObject *
self,
void *local_this, Dtool_PyTypedObject *type,
bool memory_rules,
bool is_const) {
462 ((Dtool_PyInstDef *)
self)->_My_Type = type;
463 ((Dtool_PyInstDef *)
self)->_ptr_to_object = local_this;
464 ((Dtool_PyInstDef *)
self)->_memory_rules = memory_rules;
465 ((Dtool_PyInstDef *)
self)->_is_const = is_const;
474 void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) {
475 for (; in->ml_name != NULL; in++) {
476 if (themap.find(in->ml_name) == themap.end()) {
477 themap[in->ml_name] = in;
490 RegisterRuntimeClass(Dtool_PyTypedObject *otype,
int class_id) {
492 interrogatedb_cat.warning()
493 <<
"Class " << otype->_PyType.tp_name
494 <<
" has a zero TypeHandle value; check that init_type() is called.\n";
496 }
else if (class_id > 0) {
497 RunTimeTypeDictionary &dict = GetRunTimeDictionary();
498 pair<RunTimeTypeDictionary::iterator, bool> result =
499 dict.insert(RunTimeTypeDictionary::value_type(class_id, otype));
500 if (!result.second) {
502 Dtool_PyTypedObject *other_type = (*result.first).second;
503 interrogatedb_cat.warning()
504 <<
"Classes " << otype->_PyType.tp_name
505 <<
" and " << other_type->_PyType.tp_name
506 <<
" share the same TypeHandle value (" << class_id
507 <<
"); check class definitions.\n";
510 GetRunTimeTypeList().insert(class_id);
518 Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(
int type) {
519 RunTimeTypeDictionary::iterator di = GetRunTimeDictionary().find(type);
520 if (di != GetRunTimeDictionary().end()) {
523 int type2 = get_best_parent_from_Set(type, GetRunTimeTypeList());
524 di = GetRunTimeDictionary().find(type2);
525 if (di != GetRunTimeDictionary().end()) {
533 #if PY_MAJOR_VERSION >= 3
534 PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def) {
536 PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[],
const char *modulename) {
539 MethodDefmap functions;
540 for (
int xx = 0; defs[xx] != NULL; xx++) {
541 Dtool_Accum_MethDefs(defs[xx]->_methods, functions);
544 PyMethodDef *newdef =
new PyMethodDef[functions.size() + 1];
545 MethodDefmap::iterator mi;
547 for (mi = functions.begin(); mi != functions.end(); mi++, offset++) {
548 newdef[offset] = *mi->second;
550 newdef[offset].ml_doc = NULL;
551 newdef[offset].ml_name = NULL;
552 newdef[offset].ml_meth = NULL;
553 newdef[offset].ml_flags = 0;
555 #if PY_MAJOR_VERSION >= 3
556 module_def->m_methods = newdef;
557 PyObject *module = PyModule_Create(module_def);
559 PyObject *module = Py_InitModule((
char *)modulename, newdef);
562 if (module == NULL) {
563 #if PY_MAJOR_VERSION >= 3
564 return Dtool_Raise_TypeError(
"PyModule_Create returned NULL");
566 return Dtool_Raise_TypeError(
"Py_InitModule returned NULL");
571 for (
int y = 0; defs[y] != NULL; y++) {
572 defs[y]->_constants(module);
575 PyModule_AddIntConstant(module,
"Dtool_PyNativeInterface", 1);
587 PyObject *Dtool_BorrowThisReference(PyObject *
self, PyObject *args) {
588 PyObject *from_in = NULL;
589 PyObject *to_in = NULL;
590 if (PyArg_UnpackTuple(args,
"Dtool_BorrowThisReference", 2, 2, &to_in, &from_in)) {
592 if (DtoolCanThisBeAPandaInstance(from_in) && DtoolCanThisBeAPandaInstance(to_in)) {
593 Dtool_PyInstDef *from = (Dtool_PyInstDef *) from_in;
594 Dtool_PyInstDef *to = (Dtool_PyInstDef *) to_in;
597 if (from->_My_Type == to->_My_Type) {
598 to->_memory_rules =
false;
599 to->_is_const = from->_is_const;
600 to->_ptr_to_object = from->_ptr_to_object;
606 return PyErr_Format(PyExc_TypeError,
"types %s and %s do not match",
607 Py_TYPE(from)->tp_name, Py_TYPE(to)->tp_name);
609 return Dtool_Raise_TypeError(
"One of these does not appear to be DTOOL Instance ??");
612 return (PyObject *) NULL;
618 PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
622 if (PyArg_ParseTuple(args,
"OSO", &
self, &key, &subject)) {
623 PyObject *dict = ((PyTypeObject *)
self)->tp_dict;
624 if (dict == NULL || !PyDict_Check(dict)) {
625 return Dtool_Raise_TypeError(
"No dictionary On Object");
627 PyDict_SetItem(dict, key, subject);
630 if (PyErr_Occurred()) {
631 return (PyObject *)NULL;
638 Py_hash_t DTOOL_PyObject_HashPointer(PyObject *
self) {
639 if (
self != NULL && DtoolCanThisBeAPandaInstance(
self)) {
640 Dtool_PyInstDef * pyself = (Dtool_PyInstDef *)
self;
641 return (Py_hash_t) pyself->_ptr_to_object;
654 int DTOOL_PyObject_ComparePointers(PyObject *v1, PyObject *v2) {
656 void *v1_this = DTOOL_Call_GetPointerThis(v1);
657 void *v2_this = DTOOL_Call_GetPointerThis(v2);
658 if (v1_this != NULL && v2_this != NULL) {
659 if (v1_this < v2_this) {
662 if (v1_this > v2_this) {
678 int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2) {
680 PyObject * func = PyObject_GetAttrString(v1,
"compare_to");
684 PyObject *res = NULL;
685 PyObject *args = PyTuple_Pack(1, v2);
687 res = PyObject_Call(func, args, NULL);
694 if (PyLong_Check(res)) {
695 long answer = PyLong_AsLong(res);
701 }
else if (answer > 0) {
707 #if PY_MAJOR_VERSION < 3
708 else if (PyInt_Check(res)) {
709 long answer = PyInt_AsLong(res);
715 }
else if (answer > 0) {
726 return DTOOL_PyObject_ComparePointers(v1, v2);
729 PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2,
int op) {
730 int cmpval = DTOOL_PyObject_Compare(v1, v2);
734 result = (cmpval < 0);
737 result = (cmpval <= 0);
740 result = (cmpval == 0);
743 result = (cmpval != 0);
746 result = (cmpval > 0);
749 result = (cmpval >= 0);
751 return PyBool_FromLong(result);
754 PyObject *make_list_for_item(PyObject *
self,
const char *num_name,
755 const char *element_name) {
756 PyObject *num_result = PyObject_CallMethod(
self, (
char *)num_name, (
char *)
"()");
757 if (num_result == NULL) {
761 Py_ssize_t num_elements;
762 #if PY_MAJOR_VERSION >= 3
763 num_elements = PyLong_AsSsize_t(num_result);
765 num_elements = PyInt_AsSsize_t(num_result);
767 Py_DECREF(num_result);
769 PyObject *list = PyList_New(num_elements);
770 for (
int i = 0; i < num_elements; ++i) {
771 PyObject *element = PyObject_CallMethod(
self, (
char *)element_name, (
char *)
"(i)", i);
772 if (element == NULL) {
776 PyList_SET_ITEM(list, i, element);
786 PyObject *copy_from_make_copy(PyObject *
self) {
787 return PyObject_CallMethod(
self, (
char *)
"make_copy", (
char *)
"()");
795 PyObject *copy_from_copy_constructor(PyObject *
self) {
796 PyObject *this_class = PyObject_Type(
self);
797 if (this_class == NULL) {
801 PyObject *result = PyObject_CallFunction(this_class, (
char *)
"(O)",
self);
802 Py_DECREF(this_class);
813 PyObject *map_deepcopy_to_copy(PyObject *
self, PyObject *args) {
814 return PyObject_CallMethod(
self, (
char *)
"__copy__", (
char *)
"()");
823 #if PY_MAJOR_VERSION < 3
824 EXPCL_DTOOLCONFIG PyObject *
825 PyLongOrInt_FromUnsignedLong(
unsigned long value) {
826 if ((
long)value < 0) {
827 return PyLong_FromUnsignedLong(value);
829 return PyInt_FromLong((
long)value);
834 #endif // HAVE_PYTHON
void clear_assert_failed()
Resets the assert_failed flag that is set whenever an assertion test fails.
static Notify * ptr()
Returns the pointer to the global Notify object.
TypeHandle find_type_by_id(int id) const
Looks for a previously-registered type with the given id number (as returned by TypeHandle::get_index...
static TypeRegistry * ptr()
Returns the pointer to the global TypeRegistry object.
const string & get_assert_error_message() const
Returns the error message that corresponds to the assertion that most recently failed.
An object that handles general error reporting to the user.