18 void DTOOL_Call_ExtractThisPointerForType(PyObject *
self, Dtool_PyTypedObject *classdef,
void **answer) {
19 if (DtoolInstance_Check(
self)) {
20 *answer = DtoolInstance_UPCAST(
self, *classdef);
31 bool Dtool_Call_ExtractThisPointer(PyObject *
self, Dtool_PyTypedObject &classdef,
void **answer) {
32 if (
self ==
nullptr || !DtoolInstance_Check(
self) || DtoolInstance_VOID_PTR(
self) ==
nullptr) {
33 Dtool_Raise_TypeError(
"C++ object is not yet constructed, or already destructed.");
37 *answer = DtoolInstance_UPCAST(
self, classdef);
49 bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *
self, Dtool_PyTypedObject &classdef,
50 void **answer,
const char *method_name) {
52 if (
self ==
nullptr || !DtoolInstance_Check(
self) || DtoolInstance_VOID_PTR(
self) ==
nullptr) {
53 Dtool_Raise_TypeError(
"C++ object is not yet constructed, or already destructed.");
57 if (DtoolInstance_IS_CONST(
self)) {
59 PyErr_Format(PyExc_TypeError,
60 "Cannot call %s() on a const object.",
65 *answer = DtoolInstance_UPCAST(
self, classdef);
92 DTOOL_Call_GetPointerThisClass(PyObject *
self, Dtool_PyTypedObject *classdef,
93 int param,
const string &function_name,
bool const_ok,
96 if (
self ==
nullptr) {
98 return Dtool_Raise_TypeError(
"self is nullptr");
103 if (DtoolInstance_Check(
self)) {
104 void *result = DtoolInstance_UPCAST(
self, *classdef);
106 if (result !=
nullptr) {
107 if (const_ok || !DtoolInstance_IS_CONST(
self)) {
112 return PyErr_Format(PyExc_TypeError,
113 "%s() argument %d may not be const",
114 function_name.c_str(), param);
121 return Dtool_Raise_ArgTypeError(
self, param, function_name.c_str(), classdef->_PyType.tp_name);
137 bool _Dtool_CheckErrorOccurred() {
138 if (_PyErr_OCCURRED()) {
142 Dtool_Raise_AssertionError();
152 PyObject *Dtool_Raise_AssertionError() {
154 #if PY_MAJOR_VERSION >= 3 159 Py_INCREF(PyExc_AssertionError);
160 PyErr_Restore(PyExc_AssertionError, message,
nullptr);
168 PyObject *Dtool_Raise_TypeError(
const char *message) {
171 Py_INCREF(PyExc_TypeError);
172 #if PY_MAJOR_VERSION >= 3 173 PyErr_Restore(PyExc_TypeError, PyUnicode_FromString(message),
nullptr);
175 PyErr_Restore(PyExc_TypeError, PyString_FromString(message),
nullptr);
187 PyObject *Dtool_Raise_ArgTypeError(PyObject *obj,
int param,
const char *function_name,
const char *type_name) {
188 #if PY_MAJOR_VERSION >= 3 189 PyObject *message = PyUnicode_FromFormat(
191 PyObject *message = PyString_FromFormat(
193 "%s() argument %d must be %s, not %s",
194 function_name, param, type_name,
195 Py_TYPE(obj)->tp_name);
197 Py_INCREF(PyExc_TypeError);
198 PyErr_Restore(PyExc_TypeError, message,
nullptr);
208 PyObject *Dtool_Raise_AttributeError(PyObject *obj,
const char *attribute) {
209 #if PY_MAJOR_VERSION >= 3 210 PyObject *message = PyUnicode_FromFormat(
212 PyObject *message = PyString_FromFormat(
214 "'%.100s' object has no attribute '%.200s'",
215 Py_TYPE(obj)->tp_name, attribute);
217 Py_INCREF(PyExc_AttributeError);
218 PyErr_Restore(PyExc_AttributeError, message,
nullptr);
232 PyObject *_Dtool_Raise_BadArgumentsError() {
233 return Dtool_Raise_TypeError(
"arguments do not match any function overload");
240 PyObject *_Dtool_Return_None() {
241 if (UNLIKELY(_PyErr_OCCURRED())) {
245 if (UNLIKELY(
Notify::ptr()->has_assert_failed())) {
246 return Dtool_Raise_AssertionError();
257 PyObject *Dtool_Return_Bool(
bool value) {
258 if (UNLIKELY(_PyErr_OCCURRED())) {
262 if (UNLIKELY(
Notify::ptr()->has_assert_failed())) {
263 return Dtool_Raise_AssertionError();
266 PyObject *result = (value ? Py_True : Py_False);
276 PyObject *_Dtool_Return(PyObject *value) {
277 if (UNLIKELY(_PyErr_OCCURRED())) {
281 if (UNLIKELY(
Notify::ptr()->has_assert_failed())) {
282 return Dtool_Raise_AssertionError();
288 #if PY_VERSION_HEX < 0x03040000 292 static PyObject *Dtool_EnumType_New(PyTypeObject *subtype, PyObject *args, PyObject *kwds) {
294 if (!Dtool_ExtractArg(&arg, args, kwds,
"value")) {
295 return PyErr_Format(PyExc_TypeError,
296 "%s() missing 1 required argument: 'value'",
300 if (Py_TYPE(arg) == subtype) {
305 PyObject *value2member = PyDict_GetItemString(subtype->tp_dict,
"_value2member_map_");
306 nassertr_always(value2member !=
nullptr,
nullptr);
308 PyObject *member = PyDict_GetItem(value2member, arg);
309 if (member !=
nullptr) {
314 PyObject *repr = PyObject_Repr(arg);
315 PyErr_Format(PyExc_ValueError,
"%s is not a valid %s",
316 #
if PY_MAJOR_VERSION >= 3
317 PyUnicode_AS_STRING(repr),
319 PyString_AS_STRING(repr),
326 static PyObject *Dtool_EnumType_Str(PyObject *
self) {
327 PyObject *name = PyObject_GetAttrString(
self,
"name");
328 #if PY_MAJOR_VERSION >= 3 329 PyObject *repr = PyUnicode_FromFormat(
"%s.%s", Py_TYPE(
self)->tp_name, PyString_AS_STRING(name));
331 PyObject *repr = PyString_FromFormat(
"%s.%s", Py_TYPE(
self)->tp_name, PyString_AS_STRING(name));
337 static PyObject *Dtool_EnumType_Repr(PyObject *
self) {
338 PyObject *name = PyObject_GetAttrString(
self,
"name");
339 PyObject *value = PyObject_GetAttrString(
self,
"value");
340 #if PY_MAJOR_VERSION >= 3 341 PyObject *repr = PyUnicode_FromFormat(
"<%s.%s: %ld>", Py_TYPE(
self)->tp_name, PyString_AS_STRING(name), PyLongOrInt_AS_LONG(value));
343 PyObject *repr = PyString_FromFormat(
"<%s.%s: %ld>", Py_TYPE(
self)->tp_name, PyString_AS_STRING(name), PyLongOrInt_AS_LONG(value));
355 PyTypeObject *Dtool_EnumType_Create(
const char *name, PyObject *names,
const char *module) {
356 static PyObject *enum_class =
nullptr;
357 #if PY_VERSION_HEX >= 0x03040000 358 static PyObject *enum_meta =
nullptr;
359 static PyObject *enum_create =
nullptr;
360 if (enum_meta ==
nullptr) {
361 PyObject *enum_module = PyImport_ImportModule(
"enum");
362 nassertr_always(enum_module !=
nullptr,
nullptr);
364 enum_class = PyObject_GetAttrString(enum_module,
"Enum");
365 enum_meta = PyObject_GetAttrString(enum_module,
"EnumMeta");
366 enum_create = PyObject_GetAttrString(enum_meta,
"_create_");
367 nassertr(enum_meta !=
nullptr,
nullptr);
370 PyObject *result = PyObject_CallFunction(enum_create, (
char *)
"OsN", enum_class, name, names);
371 nassertr(result !=
nullptr,
nullptr);
373 static PyObject *name_str;
374 static PyObject *name_sunder_str;
375 static PyObject *value_str;
376 static PyObject *value_sunder_str;
377 static PyObject *value2member_map_sunder_str;
379 if (enum_class ==
nullptr) {
380 #if PY_MAJOR_VERSION >= 3 381 name_str = PyUnicode_InternFromString(
"name");
382 value_str = PyUnicode_InternFromString(
"value");
383 name_sunder_str = PyUnicode_InternFromString(
"_name_");
384 value_sunder_str = PyUnicode_InternFromString(
"_value_");
385 value2member_map_sunder_str = PyUnicode_InternFromString(
"_value2member_map_");
387 name_str = PyString_InternFromString(
"name");
388 value_str = PyString_InternFromString(
"value");
389 name_sunder_str = PyString_InternFromString(
"_name_");
390 value_sunder_str = PyString_InternFromString(
"_value_");
391 value2member_map_sunder_str = PyString_InternFromString(
"_value2member_map_");
393 PyObject *name_value_tuple = PyTuple_New(4);
394 PyTuple_SET_ITEM(name_value_tuple, 0, name_str);
395 PyTuple_SET_ITEM(name_value_tuple, 1, value_str);
396 PyTuple_SET_ITEM(name_value_tuple, 2, name_sunder_str);
397 PyTuple_SET_ITEM(name_value_tuple, 3, value_sunder_str);
399 Py_INCREF(value_str);
401 PyObject *slots_dict = PyDict_New();
402 PyDict_SetItemString(slots_dict,
"__slots__", name_value_tuple);
403 Py_DECREF(name_value_tuple);
405 enum_class = PyObject_CallFunction((PyObject *)&PyType_Type, (
char *)
"s()N",
"Enum", slots_dict);
406 nassertr(enum_class !=
nullptr,
nullptr);
410 PyObject *value2member = PyDict_New();
411 PyObject *dict = PyDict_New();
412 PyDict_SetItem(dict, value2member_map_sunder_str, value2member);
413 PyObject *result = PyObject_CallFunction((PyObject *)&PyType_Type, (
char *)
"s(O)N", name, enum_class, dict);
414 nassertr(result !=
nullptr,
nullptr);
416 ((PyTypeObject *)result)->tp_new = Dtool_EnumType_New;
417 ((PyTypeObject *)result)->tp_str = Dtool_EnumType_Str;
418 ((PyTypeObject *)result)->tp_repr = Dtool_EnumType_Repr;
420 PyObject *empty_tuple = PyTuple_New(0);
424 Py_ssize_t size = PyTuple_GET_SIZE(names);
425 for (Py_ssize_t i = 0; i < size; ++i) {
426 PyObject *item = PyTuple_GET_ITEM(names, i);
427 PyObject *name = PyTuple_GET_ITEM(item, 0);
428 PyObject *value = PyTuple_GET_ITEM(item, 1);
429 PyObject *member = PyType_GenericNew((PyTypeObject *)result, empty_tuple,
nullptr);
430 PyObject_SetAttr(member, name_str, name);
431 PyObject_SetAttr(member, name_sunder_str, name);
432 PyObject_SetAttr(member, value_str, value);
433 PyObject_SetAttr(member, value_sunder_str, value);
434 PyObject_SetAttr(result, name, member);
435 PyDict_SetItem(value2member, value, member);
439 Py_DECREF(value2member);
440 Py_DECREF(empty_tuple);
443 if (module !=
nullptr) {
444 PyObject *modstr = PyUnicode_FromString(module);
445 PyObject_SetAttrString(result,
"__module__", modstr);
448 nassertr(PyType_Check(result),
nullptr);
449 return (PyTypeObject *)result;
455 PyObject *DTool_CreatePyInstanceTyped(
void *local_this_in, Dtool_PyTypedObject &known_class_type,
bool memory_rules,
bool is_const,
int type_index) {
460 nassertr(local_this_in !=
nullptr,
nullptr);
463 if (type_index > 0) {
465 Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)TypeHandle::from_index(type_index).get_python_type();
466 if (target_class !=
nullptr) {
468 void *new_local_this = target_class->_Dtool_DowncastInterface(local_this_in, &known_class_type);
469 if (new_local_this !=
nullptr) {
471 Dtool_PyInstDef *
self = (Dtool_PyInstDef *) target_class->_PyType.tp_new(&target_class->_PyType,
nullptr,
nullptr);
472 if (
self !=
nullptr) {
473 self->_ptr_to_object = new_local_this;
474 self->_memory_rules = memory_rules;
475 self->_is_const = is_const;
477 self->_My_Type = target_class;
478 return (PyObject *)
self;
486 Dtool_PyInstDef *
self = (Dtool_PyInstDef *) known_class_type._PyType.tp_new(&known_class_type._PyType,
nullptr,
nullptr);
487 if (
self !=
nullptr) {
488 self->_ptr_to_object = local_this_in;
489 self->_memory_rules = memory_rules;
490 self->_is_const = is_const;
492 self->_My_Type = &known_class_type;
494 return (PyObject *)
self;
499 PyObject *
DTool_CreatePyInstance(
void *local_this, Dtool_PyTypedObject &in_classdef,
bool memory_rules,
bool is_const) {
500 if (local_this ==
nullptr) {
507 Dtool_PyTypedObject *classdef = &in_classdef;
508 Dtool_PyInstDef *
self = (Dtool_PyInstDef *) classdef->_PyType.tp_new(&classdef->_PyType,
nullptr,
nullptr);
509 if (
self !=
nullptr) {
510 self->_ptr_to_object = local_this;
511 self->_memory_rules = memory_rules;
512 self->_is_const = is_const;
513 self->_My_Type = classdef;
515 return (PyObject *)
self;
521 Dtool_TypeMap *Dtool_GetGlobalTypeMap() {
522 PyObject *capsule = PySys_GetObject((
char *)
"_interrogate_types");
523 if (capsule !=
nullptr) {
524 return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule,
nullptr);
526 Dtool_TypeMap *type_map =
new Dtool_TypeMap;
527 capsule = PyCapsule_New((
void *)type_map,
nullptr,
nullptr);
528 PySys_SetObject((
char *)
"_interrogate_types", capsule);
534 #if PY_MAJOR_VERSION >= 3 535 PyObject *Dtool_PyModuleInitHelper(
const LibraryDef *defs[], PyModuleDef *module_def) {
537 PyObject *Dtool_PyModuleInitHelper(
const LibraryDef *defs[],
const char *modulename) {
540 string version = Py_GetVersion();
542 if (version[0] !=
'0' + PY_MAJOR_VERSION ||
543 version[2] !=
'0' + PY_MINOR_VERSION) {
546 std::ostringstream errs;
547 errs <<
"this module was compiled for Python " 548 << PY_MAJOR_VERSION <<
"." << PY_MINOR_VERSION <<
", which is " 549 <<
"incompatible with Python " << version.substr(0, 3);
550 string error = errs.str();
551 PyErr_SetString(PyExc_ImportError, error.c_str());
555 Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
558 MethodDefmap functions;
559 for (
size_t i = 0; defs[i] !=
nullptr; i++) {
560 const LibraryDef &def = *defs[i];
563 for (PyMethodDef *meth = def._methods; meth->ml_name !=
nullptr; meth++) {
564 if (functions.find(meth->ml_name) == functions.end()) {
565 functions[meth->ml_name] = meth;
570 const Dtool_TypeDef *types = def._types;
571 if (types !=
nullptr) {
572 while (types->name !=
nullptr) {
573 (*type_map)[std::string(types->name)] = types->type;
580 for (
size_t i = 0; defs[i] !=
nullptr; i++) {
581 const LibraryDef &def = *defs[i];
583 Dtool_TypeDef *types = def._external_types;
584 if (types !=
nullptr) {
585 while (types->name !=
nullptr) {
586 auto it = type_map->find(std::string(types->name));
587 if (it != type_map->end()) {
588 types->type = it->second;
590 return PyErr_Format(PyExc_NameError,
"name '%s' is not defined", types->name);
597 PyMethodDef *newdef =
new PyMethodDef[functions.size() + 1];
598 MethodDefmap::iterator mi;
600 for (mi = functions.begin(); mi != functions.end(); mi++, offset++) {
601 newdef[offset] = *mi->second;
603 newdef[offset].ml_doc =
nullptr;
604 newdef[offset].ml_name =
nullptr;
605 newdef[offset].ml_meth =
nullptr;
606 newdef[offset].ml_flags = 0;
608 #if PY_MAJOR_VERSION >= 3 609 module_def->m_methods = newdef;
610 PyObject *module = PyModule_Create(module_def);
612 PyObject *module = Py_InitModule((
char *)modulename, newdef);
615 if (module ==
nullptr) {
616 #if PY_MAJOR_VERSION >= 3 617 return Dtool_Raise_TypeError(
"PyModule_Create returned NULL");
619 return Dtool_Raise_TypeError(
"Py_InitModule returned NULL");
625 static bool initialized_main_dir =
false;
626 if (!initialized_main_dir) {
627 if (interrogatedb_cat.is_debug()) {
629 interrogatedb_cat.debug()
630 <<
"Python " << version <<
"\n";
635 PyObject *main_module = PyImport_ImportModule(
"__main__");
636 if (main_module == NULL) {
637 interrogatedb_cat.warning() <<
"Unable to import __main__\n";
642 PyObject *file_attr =
nullptr;
643 if (main_module !=
nullptr) {
644 file_attr = PyObject_GetAttrString(main_module,
"__file__");
646 if (file_attr ==
nullptr) {
650 #if PY_MAJOR_VERSION >= 3 652 wchar_t *buffer = PyUnicode_AsWideCharString(file_attr, &length);
653 if (buffer !=
nullptr) {
662 if (PyString_AsStringAndSize(file_attr, &buffer, &length) != -1) {
669 interrogatedb_cat.warning() <<
"Invalid string for __main__.__file__\n";
675 initialized_main_dir =
true;
678 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS) 679 global_thread_state_swap = PyThreadState_Swap;
683 PyModule_AddIntConstant(module,
"Dtool_PyNativeInterface", 1);
690 PyObject *Dtool_BorrowThisReference(PyObject *
self, PyObject *args) {
691 PyObject *from_in =
nullptr;
692 PyObject *to_in =
nullptr;
693 if (PyArg_UnpackTuple(args,
"Dtool_BorrowThisReference", 2, 2, &to_in, &from_in)) {
695 if (DtoolInstance_Check(from_in) && DtoolInstance_Check(to_in)) {
696 Dtool_PyInstDef *from = (Dtool_PyInstDef *) from_in;
697 Dtool_PyInstDef *to = (Dtool_PyInstDef *) to_in;
700 if (from->_My_Type == to->_My_Type) {
701 to->_memory_rules =
false;
702 to->_is_const = from->_is_const;
703 to->_ptr_to_object = from->_ptr_to_object;
709 return PyErr_Format(PyExc_TypeError,
"types %s and %s do not match",
710 Py_TYPE(from)->tp_name, Py_TYPE(to)->tp_name);
712 return Dtool_Raise_TypeError(
"One of these does not appear to be DTOOL Instance ??");
720 EXPCL_PYPANDA PyObject *
721 Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
725 if (PyArg_ParseTuple(args,
"OSO", &
self, &key, &subject)) {
726 PyObject *dict = ((PyTypeObject *)
self)->tp_dict;
727 if (dict ==
nullptr || !PyDict_Check(dict)) {
728 return Dtool_Raise_TypeError(
"No dictionary On Object");
730 PyDict_SetItem(dict, key, subject);
733 if (PyErr_Occurred()) {
744 PyObject *copy_from_make_copy(PyObject *
self, PyObject *noargs) {
745 PyObject *callable = PyObject_GetAttrString(
self,
"make_copy");
746 if (callable ==
nullptr) {
749 PyObject *result = _PyObject_CallNoArg(callable);
758 PyObject *copy_from_copy_constructor(PyObject *
self, PyObject *noargs) {
759 PyObject *callable = (PyObject *)Py_TYPE(
self);
760 return _PyObject_FastCall(callable, &
self, 1);
768 PyObject *map_deepcopy_to_copy(PyObject *
self, PyObject *args) {
769 PyObject *callable = PyObject_GetAttrString(
self,
"__copy__");
770 if (callable ==
nullptr) {
773 PyObject *result = _PyObject_CallNoArg(callable);
782 bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds,
783 const char *keyword) {
785 if (PyTuple_GET_SIZE(args) == 1) {
786 if (kwds ==
nullptr || PyDict_GET_SIZE(kwds) == 0) {
787 *result = PyTuple_GET_ITEM(args, 0);
790 }
else if (PyTuple_GET_SIZE(args) == 0) {
793 if (kwds !=
nullptr && PyDict_GET_SIZE(kwds) == 1 &&
794 PyDict_Next(kwds, &ppos, &key, result)) {
796 #if PY_VERSION_HEX >= 0x03060000 797 return PyUnicode_CheckExact(key) && _PyUnicode_EqualToASCIIString(key, keyword);
798 #elif PY_MAJOR_VERSION >= 3 799 return PyUnicode_CheckExact(key) && PyUnicode_CompareWithASCIIString(key, keyword) == 0;
801 return PyString_CheckExact(key) && strcmp(PyString_AS_STRING(key), keyword) == 0;
812 bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds) {
813 if (PyTuple_GET_SIZE(args) == 1 &&
814 (kwds ==
nullptr || PyDict_GET_SIZE(kwds) == 0)) {
815 *result = PyTuple_GET_ITEM(args, 0);
828 bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds,
829 const char *keyword) {
831 if (PyTuple_GET_SIZE(args) == 1) {
832 if (kwds ==
nullptr || PyDict_GET_SIZE(kwds) == 0) {
833 *result = PyTuple_GET_ITEM(args, 0);
836 }
else if (PyTuple_GET_SIZE(args) == 0) {
837 if (kwds !=
nullptr && PyDict_GET_SIZE(kwds) == 1) {
840 if (!PyDict_Next(kwds, &ppos, &key, result)) {
845 #if PY_VERSION_HEX >= 0x03060000 846 return PyUnicode_CheckExact(key) && _PyUnicode_EqualToASCIIString(key, keyword);
847 #elif PY_MAJOR_VERSION >= 3 848 return PyUnicode_CheckExact(key) && PyUnicode_CompareWithASCIIString(key, keyword) == 0;
850 return PyString_CheckExact(key) && strcmp(PyString_AS_STRING(key), keyword) == 0;
863 bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds) {
864 if (kwds !=
nullptr && PyDict_GET_SIZE(kwds) != 0) {
867 if (PyTuple_GET_SIZE(args) == 1) {
868 *result = PyTuple_GET_ITEM(args, 0);
871 return (PyTuple_GET_SIZE(args) == 0);
874 #endif // HAVE_PYTHON std::string get_dirname() const
Returns the directory part of the filename.
get_cwd
Returns the name of the current working directory.
const std::string & get_assert_error_message() const
Returns the error message that corresponds to the assertion that most recently failed.
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.
The name of a file, such as a texture file or an Egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void shadow_environment_variable(const std::string &var, const std::string &value)
Changes the apparent definition of the indicated environment variable by masking it within this class...
PyObject * DTool_CreatePyInstance(const T *obj, bool memory_rules)
These functions wrap a pointer for a class that defines get_type_handle().
void make_absolute()
Converts the filename to a fully-qualified pathname from the root (if it is a relative pathname),...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
static Filename from_os_specific_w(const std::wstring &os_specific, Type type=T_general)
The wide-string variant of from_os_specific().
has_environment_variable
Returns true if the indicated environment variable is defined.
An object that handles general error reporting to the user.
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...