mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
interrogate: support enum class to limited extent in Python 2
Only the basics are supported; the __members__ or iter interface is not supported at this time. See also #351 for discussion on pulling in enum34 module.
This commit is contained in:
parent
cce21a5bee
commit
68e7f681f4
@ -1312,15 +1312,19 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||||||
|
|
||||||
CPPType *underlying_type = TypeManager::unwrap_const(object->_itype._cpptype->as_enum_type()->get_underlying_type());
|
CPPType *underlying_type = TypeManager::unwrap_const(object->_itype._cpptype->as_enum_type()->get_underlying_type());
|
||||||
string cast_to = underlying_type->get_local_name(&parser);
|
string cast_to = underlying_type->get_local_name(&parser);
|
||||||
out << "#if PY_VERSION_HEX >= 0x03040000\n\n";
|
|
||||||
out << " // enum class " << object->_itype.get_scoped_name() << "\n";
|
out << " // enum class " << object->_itype.get_scoped_name() << "\n";
|
||||||
out << " {\n";
|
out << " {\n";
|
||||||
out << " PyObject *members = PyTuple_New(" << enum_count << ");\n";
|
out << " PyObject *members = PyTuple_New(" << enum_count << ");\n";
|
||||||
out << " PyObject *member;\n";
|
out << " PyObject *member;\n";
|
||||||
for (int xx = 0; xx < enum_count; xx++) {
|
for (int xx = 0; xx < enum_count; xx++) {
|
||||||
out << " member = PyTuple_New(2);\n"
|
out << " member = PyTuple_New(2);\n"
|
||||||
" PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\""
|
"#if PY_MAJOR_VERSION >= 3\n"
|
||||||
|
" PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\""
|
||||||
<< object->_itype.get_enum_value_name(xx) << "\"));\n"
|
<< object->_itype.get_enum_value_name(xx) << "\"));\n"
|
||||||
|
"#else\n"
|
||||||
|
" PyTuple_SET_ITEM(member, 0, PyString_FromString(\""
|
||||||
|
<< object->_itype.get_enum_value_name(xx) << "\"));\n"
|
||||||
|
"#endif\n"
|
||||||
" PyTuple_SET_ITEM(member, 1, Dtool_WrapValue(("
|
" PyTuple_SET_ITEM(member, 1, Dtool_WrapValue(("
|
||||||
<< cast_to << ")" << object->_itype.get_scoped_name() << "::"
|
<< cast_to << ")" << object->_itype.get_scoped_name() << "::"
|
||||||
<< object->_itype.get_enum_value_name(xx) << "));\n"
|
<< object->_itype.get_enum_value_name(xx) << "));\n"
|
||||||
@ -1332,7 +1336,6 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||||||
out << " PyModule_AddObject(module, \"" << object->_itype.get_name()
|
out << " PyModule_AddObject(module, \"" << object->_itype.get_name()
|
||||||
<< "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n";
|
<< "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n";
|
||||||
out << " }\n";
|
out << " }\n";
|
||||||
out << "#endif\n";
|
|
||||||
} else {
|
} else {
|
||||||
out << " // enum " << object->_itype.get_scoped_name() << "\n";
|
out << " // enum " << object->_itype.get_scoped_name() << "\n";
|
||||||
for (int xx = 0; xx < enum_count; xx++) {
|
for (int xx = 0; xx < enum_count; xx++) {
|
||||||
@ -3129,27 +3132,30 @@ write_module_class(ostream &out, Object *obj) {
|
|||||||
int enum_count = nested_obj->_itype.number_of_enum_values();
|
int enum_count = nested_obj->_itype.number_of_enum_values();
|
||||||
CPPType *underlying_type = TypeManager::unwrap_const(nested_obj->_itype._cpptype->as_enum_type()->get_underlying_type());
|
CPPType *underlying_type = TypeManager::unwrap_const(nested_obj->_itype._cpptype->as_enum_type()->get_underlying_type());
|
||||||
string cast_to = underlying_type->get_local_name(&parser);
|
string cast_to = underlying_type->get_local_name(&parser);
|
||||||
out << "#if PY_VERSION_HEX >= 0x03040000\n\n";
|
|
||||||
out << " // enum class " << nested_obj->_itype.get_scoped_name() << ";\n";
|
out << " // enum class " << nested_obj->_itype.get_scoped_name() << ";\n";
|
||||||
out << " {\n";
|
out << " {\n";
|
||||||
out << " PyObject *members = PyTuple_New(" << enum_count << ");\n";
|
out << " PyObject *members = PyTuple_New(" << enum_count << ");\n";
|
||||||
out << " PyObject *member;\n";
|
out << " PyObject *member;\n";
|
||||||
for (int xx = 0; xx < enum_count; xx++) {
|
for (int xx = 0; xx < enum_count; xx++) {
|
||||||
out << " member = PyTuple_New(2);\n"
|
out << " member = PyTuple_New(2);\n"
|
||||||
|
"#if PY_MAJOR_VERSION >= 3\n"
|
||||||
" PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\""
|
" PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\""
|
||||||
<< nested_obj->_itype.get_enum_value_name(xx) << "\"));\n"
|
<< nested_obj->_itype.get_enum_value_name(xx) << "\"));\n"
|
||||||
|
"#else\n"
|
||||||
|
" PyTuple_SET_ITEM(member, 0, PyString_FromString(\""
|
||||||
|
<< nested_obj->_itype.get_enum_value_name(xx) << "\"));\n"
|
||||||
|
"#endif\n"
|
||||||
" PyTuple_SET_ITEM(member, 1, Dtool_WrapValue(("
|
" PyTuple_SET_ITEM(member, 1, Dtool_WrapValue(("
|
||||||
<< cast_to << ")" << nested_obj->_itype.get_scoped_name() << "::"
|
<< cast_to << ")" << nested_obj->_itype.get_scoped_name() << "::"
|
||||||
<< nested_obj->_itype.get_enum_value_name(xx) << "));\n"
|
<< nested_obj->_itype.get_enum_value_name(xx) << "));\n"
|
||||||
" PyTuple_SET_ITEM(members, " << xx << ", member);\n";
|
" PyTuple_SET_ITEM(members, " << xx << ", member);\n";
|
||||||
}
|
}
|
||||||
out << " Dtool_Ptr_" << safe_name << " = Dtool_EnumType_Create(\""
|
out << " Dtool_Ptr_" << safe_name << " = Dtool_EnumType_Create(\""
|
||||||
<< nested_obj->_itype.get_name() << "\", members, \""
|
<< nested_obj->_itype.get_name() << "\", members, \""
|
||||||
<< _def->module_name << "\");\n";
|
<< _def->module_name << "\");\n";
|
||||||
out << " PyDict_SetItemString(dict, \"" << nested_obj->_itype.get_name()
|
out << " PyDict_SetItemString(dict, \"" << nested_obj->_itype.get_name()
|
||||||
<< "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n";
|
<< "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n";
|
||||||
out << " }\n";
|
out << " }\n";
|
||||||
out << "#endif\n";
|
|
||||||
|
|
||||||
} else if (nested_obj->_itype.is_enum()) {
|
} else if (nested_obj->_itype.is_enum()) {
|
||||||
out << " // enum " << nested_obj->_itype.get_scoped_name() << ";\n";
|
out << " // enum " << nested_obj->_itype.get_scoped_name() << ";\n";
|
||||||
|
@ -306,11 +306,39 @@ PyObject *_Dtool_Return(PyObject *value) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PY_VERSION_HEX < 0x03040000
|
||||||
|
static PyObject *Dtool_EnumType_Str(PyObject *self) {
|
||||||
|
PyObject *name = PyObject_GetAttrString(self, "name");
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
PyObject *repr = PyUnicode_FromFormat("%s.%s", Py_TYPE(self)->tp_name, PyString_AS_STRING(name));
|
||||||
|
#else
|
||||||
|
PyObject *repr = PyString_FromFormat("%s.%s", Py_TYPE(self)->tp_name, PyString_AS_STRING(name));
|
||||||
|
#endif
|
||||||
|
Py_DECREF(name);
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *Dtool_EnumType_Repr(PyObject *self) {
|
||||||
|
PyObject *name = PyObject_GetAttrString(self, "name");
|
||||||
|
PyObject *value = PyObject_GetAttrString(self, "value");
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
PyObject *repr = PyUnicode_FromFormat("<%s.%s: %ld>", Py_TYPE(self)->tp_name, PyString_AS_STRING(name), PyLongOrInt_AS_LONG(value));
|
||||||
|
#else
|
||||||
|
PyObject *repr = PyString_FromFormat("<%s.%s: %ld>", Py_TYPE(self)->tp_name, PyString_AS_STRING(name), PyLongOrInt_AS_LONG(value));
|
||||||
|
#endif
|
||||||
|
Py_DECREF(name);
|
||||||
|
Py_DECREF(value);
|
||||||
|
return repr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Python 3.4-style enum type. Steals reference to 'names'.
|
* Creates a Python 3.4-style enum type. Steals reference to 'names', which
|
||||||
|
* should be a tuple of (name, value) pairs.
|
||||||
*/
|
*/
|
||||||
PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) {
|
PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) {
|
||||||
static PyObject *enum_class = nullptr;
|
static PyObject *enum_class = nullptr;
|
||||||
|
#if PY_VERSION_HEX >= 0x03040000
|
||||||
static PyObject *enum_meta = nullptr;
|
static PyObject *enum_meta = nullptr;
|
||||||
static PyObject *enum_create = nullptr;
|
static PyObject *enum_create = nullptr;
|
||||||
if (enum_meta == nullptr) {
|
if (enum_meta == nullptr) {
|
||||||
@ -325,6 +353,62 @@ PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const cha
|
|||||||
|
|
||||||
PyObject *result = PyObject_CallFunction(enum_create, (char *)"OsN", enum_class, name, names);
|
PyObject *result = PyObject_CallFunction(enum_create, (char *)"OsN", enum_class, name, names);
|
||||||
nassertr(result != nullptr, nullptr);
|
nassertr(result != nullptr, nullptr);
|
||||||
|
#else
|
||||||
|
static PyObject *name_str;
|
||||||
|
static PyObject *name_sunder_str;
|
||||||
|
static PyObject *value_str;
|
||||||
|
static PyObject *value_sunder_str;
|
||||||
|
// Emulate something vaguely like the enum module.
|
||||||
|
if (enum_class == nullptr) {
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
name_str = PyUnicode_InternFromString("name");
|
||||||
|
value_str = PyUnicode_InternFromString("value");
|
||||||
|
name_sunder_str = PyUnicode_InternFromString("_name_");
|
||||||
|
value_sunder_str = PyUnicode_InternFromString("_value_");
|
||||||
|
#else
|
||||||
|
name_str = PyString_InternFromString("name");
|
||||||
|
value_str = PyString_InternFromString("value");
|
||||||
|
name_sunder_str = PyString_InternFromString("_name_");
|
||||||
|
value_sunder_str = PyString_InternFromString("_value_");
|
||||||
|
#endif
|
||||||
|
PyObject *name_value_tuple = PyTuple_New(4);
|
||||||
|
PyTuple_SET_ITEM(name_value_tuple, 0, name_str);
|
||||||
|
PyTuple_SET_ITEM(name_value_tuple, 1, value_str);
|
||||||
|
PyTuple_SET_ITEM(name_value_tuple, 2, name_sunder_str);
|
||||||
|
PyTuple_SET_ITEM(name_value_tuple, 3, value_sunder_str);
|
||||||
|
Py_INCREF(name_str);
|
||||||
|
Py_INCREF(value_str);
|
||||||
|
|
||||||
|
PyObject *slots_dict = PyDict_New();
|
||||||
|
PyDict_SetItemString(slots_dict, "__slots__", name_value_tuple);
|
||||||
|
Py_DECREF(name_value_tuple);
|
||||||
|
|
||||||
|
enum_class = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s()N", "Enum", slots_dict);
|
||||||
|
nassertr(enum_class != nullptr, nullptr);
|
||||||
|
}
|
||||||
|
PyObject *result = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s(O)N", name, enum_class, PyDict_New());
|
||||||
|
nassertr(result != nullptr, nullptr);
|
||||||
|
|
||||||
|
((PyTypeObject *)result)->tp_str = Dtool_EnumType_Str;
|
||||||
|
((PyTypeObject *)result)->tp_repr = Dtool_EnumType_Repr;
|
||||||
|
|
||||||
|
// Copy the names as instances of the above to the class dict.
|
||||||
|
Py_ssize_t size = PyTuple_GET_SIZE(names);
|
||||||
|
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||||
|
PyObject *item = PyTuple_GET_ITEM(names, i);
|
||||||
|
PyObject *name = PyTuple_GET_ITEM(item, 0);
|
||||||
|
PyObject *value = PyTuple_GET_ITEM(item, 1);
|
||||||
|
PyObject *member = _PyObject_CallNoArg(result);
|
||||||
|
PyObject_SetAttr(member, name_str, name);
|
||||||
|
PyObject_SetAttr(member, name_sunder_str, name);
|
||||||
|
PyObject_SetAttr(member, value_str, value);
|
||||||
|
PyObject_SetAttr(member, value_sunder_str, value);
|
||||||
|
PyObject_SetAttr(result, name, member);
|
||||||
|
Py_DECREF(member);
|
||||||
|
}
|
||||||
|
Py_DECREF(names);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (module != nullptr) {
|
if (module != nullptr) {
|
||||||
PyObject *modstr = PyUnicode_FromString(module);
|
PyObject *modstr = PyUnicode_FromString(module);
|
||||||
PyObject_SetAttrString(result, "__module__", modstr);
|
PyObject_SetAttrString(result, "__module__", modstr);
|
||||||
|
@ -121,6 +121,7 @@ extern "C" {
|
|||||||
EXPCL_PYSTUB int PyObject_Repr(...);
|
EXPCL_PYSTUB int PyObject_Repr(...);
|
||||||
EXPCL_PYSTUB int PyObject_RichCompareBool(...);
|
EXPCL_PYSTUB int PyObject_RichCompareBool(...);
|
||||||
EXPCL_PYSTUB int PyObject_SelfIter(...);
|
EXPCL_PYSTUB int PyObject_SelfIter(...);
|
||||||
|
EXPCL_PYSTUB int PyObject_SetAttr(...);
|
||||||
EXPCL_PYSTUB int PyObject_SetAttrString(...);
|
EXPCL_PYSTUB int PyObject_SetAttrString(...);
|
||||||
EXPCL_PYSTUB int PyObject_Str(...);
|
EXPCL_PYSTUB int PyObject_Str(...);
|
||||||
EXPCL_PYSTUB int PyObject_Type(...);
|
EXPCL_PYSTUB int PyObject_Type(...);
|
||||||
@ -351,6 +352,7 @@ int PyObject_Malloc(...) { return 0; }
|
|||||||
int PyObject_Repr(...) { return 0; }
|
int PyObject_Repr(...) { return 0; }
|
||||||
int PyObject_RichCompareBool(...) { return 0; }
|
int PyObject_RichCompareBool(...) { return 0; }
|
||||||
int PyObject_SelfIter(...) { return 0; }
|
int PyObject_SelfIter(...) { return 0; }
|
||||||
|
int PyObject_SetAttr(...) { return 0; }
|
||||||
int PyObject_SetAttrString(...) { return 0; }
|
int PyObject_SetAttrString(...) { return 0; }
|
||||||
int PyObject_Str(...) { return 0; }
|
int PyObject_Str(...) { return 0; }
|
||||||
int PyObject_Type(...) { return 0; }
|
int PyObject_Type(...) { return 0; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user