Last active
June 18, 2025 13:05
-
-
Save RezSat/af3158ac13c36b98a0b8194c24a75773 to your computer and use it in GitHub Desktop.
To illustrate the fundamental PyObject structure and its accessible fields, consider the following C extension. This example creates a Python integer object and then inspects its internal ob_refcnt and ob_type->tp_name fields using the CPython API macros. C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define PY_SSIZE_T_CLEAN | |
#include <Python.h> | |
#include <stdio.h> // For PySys_WriteStdout | |
// Define a simple C function that creates a Python integer | |
// and prints its ob_refcnt and ob_type->tp_name | |
static PyObject* | |
inspect_int_object(PyObject *self, PyObject *args) { | |
PyObject *py_int_obj; | |
long value; | |
// Parse arguments: expect a single long integer | |
if (!PyArg_ParseTuple(args, "l", &value)) { | |
return NULL; // Error occurred | |
} | |
// Create a Python integer object | |
py_int_obj = PyLong_FromLong(value); | |
if (py_int_obj == NULL) { | |
return NULL; // Error creating object | |
} | |
// Access ob_refcnt and ob_type using macros | |
Py_ssize_t ref_count = Py_REFCNT(py_int_obj); | |
PyTypeObject *type_obj = Py_TYPE(py_int_obj); | |
const char *type_name = type_obj->tp_name; | |
// Print the information | |
PySys_WriteStdout("Object: %ld\n", value); | |
PySys_WriteStdout(" Reference Count: %zd\n", ref_count); | |
PySys_WriteStdout(" Type Name: %s\n", type_name); | |
// Decrement the reference count for the object we created | |
// This is crucial for proper memory management. | |
Py_DECREF(py_int_obj); | |
Py_RETURN_NONE; // Return None (increments its refcount) | |
} | |
// --- | |
// Corrected Module method definitions | |
// Declare MyInspectMethods as an ARRAY of PyMethodDef | |
static PyMethodDef MyInspectMethods[] = { | |
{"inspect_int", inspect_int_object, METH_VARARGS, | |
"Inspects a Python integer object's internal PyObject fields."}, | |
{NULL, NULL, 0, NULL} // Sentinel | |
}; | |
// --- | |
// Module definition structure for Python 3 | |
static struct PyModuleDef inspectmodule = { | |
PyModuleDef_HEAD_INIT, | |
"inspect_internals", // Module name | |
"A module to inspect CPython object internals.", // Module docstring | |
-1, // Size of per-interpreter state of the module, -1 means global state | |
MyInspectMethods // Module methods (now correctly a pointer to the array) | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment