|
| 1 | +class modify_tuple: |
| 2 | + from ctypes import c_long, c_size_t, py_object, pythonapi |
| 3 | + |
| 4 | + pythonapi.PyTuple_SetItem.argtypes = (py_object, c_size_t, py_object) |
| 5 | + |
| 6 | + def __new__(cls, tup: tuple, idx: int, newval) -> tuple: |
| 7 | + # TYPE ERRORS |
| 8 | + if type(tup) is not tuple: |
| 9 | + raise TypeError(f"{tup} is not a tuple") |
| 10 | + if idx not in range(len(tup)): |
| 11 | + raise IndexError(f"{idx} is a bad index for {tup}") |
| 12 | + # ACTUAL CODE |
| 13 | + cls.pythonapi.Py_IncRef(newval) |
| 14 | + tupobj = cls.py_object(tup) |
| 15 | + reference_pointer = cls.c_long.from_address(id(tup)) |
| 16 | + original_refcount = reference_pointer.value |
| 17 | + reference_pointer.value = 1 |
| 18 | + cls.pythonapi.PyTuple_SetItem(tupobj, idx, newval) |
| 19 | + reference_pointer.value = original_refcount |
| 20 | + return tup |
| 21 | + |
| 22 | +class modify_string: |
| 23 | + from ctypes import memmove |
| 24 | + from sys import getsizeof |
| 25 | + |
| 26 | + offset = getsizeof("") - 1 |
| 27 | + |
| 28 | + def __new__(cls, text: str, start: int, newtext: str) -> str: |
| 29 | + # TYPE ERRORS |
| 30 | + if type(text) is not str or type(newtext) is not str: |
| 31 | + raise TypeError("got non string arguments") |
| 32 | + if len(newtext) + start > len(text): |
| 33 | + raise IndexError("Can't go over the length of the string") |
| 34 | + # ACTUAL CODE |
| 35 | + cls.memmove(id(text) + cls.offset + start, id(newtext) + cls.offset, len(newtext)) |
| 36 | + return text |
| 37 | + |
| 38 | +class modify_float: |
| 39 | + from ctypes import memmove |
| 40 | + from struct import pack |
| 41 | + from sys import getsizeof |
| 42 | + |
| 43 | + offset = getsizeof(float(0)) - len(pack("@d", 0)) |
| 44 | + |
| 45 | + def __new__(cls, old: float, new: float) -> float: |
| 46 | + if type(old) is not float or type(new) is not float: |
| 47 | + raise TypeError("got non float arguments") |
| 48 | + new_data = cls.pack("@d", new) |
| 49 | + cls.memmove(id(old) + cls.offset, new_data, len(new_data)) |
| 50 | + return old |
| 51 | + |
| 52 | +my_tuple = (1, 2, 3) |
| 53 | +print(my_tuple, id(my_tuple)) |
| 54 | +modify_tuple(my_tuple, 1, "hello") |
| 55 | +print(my_tuple, id(my_tuple), (1, 2, 3), (*range(1,4),)) |
| 56 | + |
| 57 | +my_string = "very cool python code" |
| 58 | +print(my_string, id(my_tuple)) |
| 59 | +modify_string(my_string, 10, "ctype stuff") |
| 60 | +print(my_string, id(my_tuple), "very cool python code", "a " + "very cool python code") |
| 61 | + |
| 62 | +my_float = 1.1 |
| 63 | +modify_float(my_float, 0.1) |
| 64 | +print(my_float, 1.1, my_float + 0.5, 1.1 + 0.5) |
0 commit comments