Before carrying on any further, I am aware that one should never do this. This question is purely for educational purposes; I undertook this exercise as a means of better understanding python's internals, the ctypes
, and how they work.
I am aware that it is relatively easy to change the value of integers in python. Actually, there's a whole lot you can do by messing with the internals. From the C API reference,
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)
Considering the value of 1 is cached by CPython, it should be relatively easy (or, at least possible) to do this. After a little digging around, I found ctypes
was the way to go. However, most of what I try results in a segfault. I got close by changing the value of 2.
import ctypes
def deref(addr, typ):
return ctypes.cast(addr, ctypes.POINTER(typ))
deref(id(2), ctypes.c_int)[6] = 1
1 + 1 now gives incorrect results (a step in the right direction), but I cannot get it to evaluate to "3":
>>> 1 + 1
1
>>> 1 + 2
1
>>> 1 + 3
[1] 61014 segmentation fault python3.6
I have tried similar things ending in failure with abarnert's internals
module. Is there any way to have 1 + 1
evaluate to 3
in python? Or is "1" so all important that there is no way of making this work without segfaulting my interpreter?