Skip to content

ctypesgen: Leave c_void_p alone in the generated POINTER wrapper - #8113

Open
alteralto wants to merge 1 commit into
OSGeo:mainfrom
alteralto:fix-2109-void-pointer
Open

alteralto wants to merge 1 commit into
OSGeo:mainfrom
alteralto:fix-2109-void-pointer

Conversation

@alteralto

@alteralto alteralto commented Oct 26, 2026 •

Copy link
Copy Markdown

On Windows, g.gui.timeline and g.gui.tplot fail when matplotlib formats a date: dateutil's tzres.load_name calls LoadStringW and gets OverflowError: int too long to convert. I traced this to the preamble ctypesgen generates for grass.lib.

Its POINTER() wrapper replaces from_param on the pointer type to turn None into NULL. ctypes.POINTER(None) is ctypes.c_void_p itself, so importing grass.lib replaces from_param on the c_void_p the whole process shares. The replacement returns integers unchanged, and ctypes passes them as a C long: 64 bits on Linux and macOS, so nothing shows there, 32 bits on Windows. There, any void * argument declared after the import fails for a 64-bit address or handle, dateutil's LoadStringW and msvcrt.memmove alike.

c_void_p's own from_param already turns None into NULL, so the wrapper now returns it unchanged.

The new test in lib/gis/tests checks that c_void_p still converts an integer after import grass.lib.gis, and on Windows that a memmove declared after the import takes 64-bit addresses.

Tested on Windows 11 (GRASS 8.5.0 from conda-forge, preamble regenerated from this printer.py) with a dataset registered as in the issue: before, the new tests fail and both tools exit with the traceback before showing a window; after, the tests pass and both draw (screenshots below). In the osgeo/grass-gis:main-alpine image, pytest over lib and python/grass/pygrass and the pygrass testsuites with the North Carolina data give the same results before and after, apart from the new test. I haven't tried the OSGeo4W or standalone builds.

Diagnosed and implemented with the help of Claude Code.

Fixes #2109

timeline-after tplot-after

After the fix, Windows 11

ctypes.POINTER(None) returns ctypes.c_void_p itself, so the wrapper in the
generated preamble replaced from_param on the c_void_p type the whole
process shares. The replacement returns integers unchanged, and ctypes then
passes them as a C long. On Windows that is 32 bits, so any void pointer
argument declared after grass.lib is imported fails for a 64-bit address,
for example LoadStringW in dateutil, which breaks matplotlib date axes in
g.gui.timeline and g.gui.tplot.

c_void_p's own from_param already turns None into NULL, so the wrapper now
returns it unchanged.

Fixes OSGeo#2109
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libraries Python Related code is in Python tests Related to Test Suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] g.gui.timeline fails with ctypes.OverflowError on Windows

1 participant