File indexing completed on 2025-12-06 09:55:32
0001 #ifndef PODIO_DETAIL_PYTHONIZATIONS_H
0002 #define PODIO_DETAIL_PYTHONIZATIONS_H
0003
0004 #define PY_SSIZE_T_CLEAN
0005 #include <Python.h>
0006 #include <stdexcept>
0007 #include <string>
0008
0009 namespace podio::detail::pythonizations {
0010
0011
0012
0013 static inline PyObject* subscript(PyObject* self, PyObject* index) {
0014 PyObject* result = PyObject_CallMethod(self, "at", "O", index);
0015 if (!result) {
0016 PyObject* exc = PyErr_Occurred();
0017
0018
0019 if (exc && PyObject_HasAttrString(exc, "__name__")) {
0020 PyObject* exc_name = PyObject_GetAttrString(exc, "__name__");
0021 if (exc_name) {
0022 const char* name_cstr = PyUnicode_AsUTF8(exc_name);
0023 if (name_cstr && strcmp(name_cstr, "out_of_range") == 0) {
0024 PyErr_Clear();
0025 PyErr_SetString(PyExc_IndexError, "Index out of range");
0026 }
0027 Py_DECREF(exc_name);
0028 }
0029 }
0030 }
0031 return result;
0032 }
0033
0034
0035 static inline void pythonize_subscript(PyObject* klass, const std::string& name) {
0036 static PyMethodDef ml = {"subscipt_pythonization", subscript, METH_VARARGS, R"(
0037 Raise an `IndexError` exception if an index is invalid.
0038 The `__getitem__` will return immutable datatype objects instead of the mutable ones.
0039 )"};
0040 auto* func = PyCFunction_New(&ml, klass);
0041 if (!func) {
0042 throw std::runtime_error("Failed to create Python subscript function for class " + name);
0043 }
0044 auto* method = PyInstanceMethod_New(func);
0045 if (!method) {
0046 Py_DECREF(func);
0047 throw std::runtime_error("Failed to create Python instance method for subscript for class " + name);
0048 }
0049 if (0 != PyObject_SetAttrString(klass, "__getitem__", method)) {
0050 Py_DECREF(method);
0051 Py_DECREF(func);
0052 throw std::runtime_error("Failed to set __getitem__ attribute on class " + name);
0053 }
0054 Py_DECREF(func);
0055 Py_DECREF(method);
0056 }
0057
0058 }
0059
0060 #endif