Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #197798
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Newsgroups | comp.lang.python |
| Subject | PyObjects From Python Via ctypes |
| Date | 2026-06-11 07:41 +0000 |
| Organization | A noiseless patient Spider |
| Message-ID | <110doqv$19tv7$1@dont-email.me> (permalink) |
I see ctypes has a py_object type, but you can’t seem to do much with
it. The following might be more useful:
---- file: pyobjhack.py
import ctypes as ct
def _init_hack() :
# works out the values of TRACE_REFS and PYOBJECT_HEADER_SIZE.
global TRACE_REFS, PYOBJECT_HEADER_SIZE
o = object()
# CPython implementation detail: “id()” function returns address of object header
if ct.c_size_t.from_address(id(o)).value == 1 :
TRACE_REFS = False
PYOBJECT_HEADER_SIZE = 2
elif ct.c_size_t.from_address(id(o) + 2 * ct.sizeof(ct.c_void_p)).value == 1 :
TRACE_REFS = True
PYOBJECT_HEADER_SIZE = 4
else :
raise RuntimeError("cannot determine pyobject header size")
#end if
# header of every PyObject has ob_refcnt (type ssize_t) followed by ob_type (type pointer),
# but these might be preceded by a pair of next/prev pointers if Py_TRACE_REFS is defined.
# Only way I can figure out to determine which is the case is to construct an object
# with a known refcount of 1, and see if I can find the value 1 at the start.
# Confirm that the refcount field behaves as expected:
o2 = o
assert ct.c_size_t.from_address(id(o) + (PYOBJECT_HEADER_SIZE - 2) * ct.sizeof(ct.c_void_p)).value == 2
del o2
assert ct.c_size_t.from_address(id(o) + (PYOBJECT_HEADER_SIZE - 2) * ct.sizeof(ct.c_void_p)).value == 1
#end _init_hack
_init_hack()
del _init_hack
class PyObject(ct.Structure) :
"header part of a PyObject structure."
_fields_ = \
(
(
[],
[
("_ob_next", ct.c_void_p),
("_ob_prev", ct.c_void_p),
],
)[TRACE_REFS]
+
[
("ob_refcnt", ct.c_ssize_t),
("ob_type", ct.c_void_p),
]
)
@classmethod
def from_obj(celf, obj) :
"aliases the object header to a PyObject struct."
return \
celf.from_address(id(obj))
#end from_obj
#end PyObject
Back to comp.lang.python | Previous | Next — Next in thread | Find similar | Unroll thread
PyObjects From Python Via ctypes Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-11 07:41 +0000 Re: PyObjects From Python Via ctypes Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-11 07:44 +0000
csiph-web