You can forcefully deallocate an object by using the C memory de/allocation functions, for example via ctypes
.
t = (1, 2)
print(id(t))
print(id((1, 2)))
pyc = ctypes.CDLL(None) # system dependent – should work on Unix
pyc.PyMem_Free(id(t))
print(id((1, 2)))
Notably, on "Python 3.9.5 (default, May 4 2021, 03:29:30) [Clang 11.0.0 (clang-1100.0.33.17)] on darwin" (likely any other recent CPython) this causes a segfault – we just blew a hole into the memory managed by the interpreter, and removed an object it was still expecting to use.
$ python so_testbed.py
4493301568
4493301568
[1] 47059 segmentation fault python so_testbed.py
Keep in mind that the interpreter has a reason to keep things around.
For example, literals used in the same compilation unit may be deduplicated
# so_testbed.py
def foo():
t = (1, 2)
print(id(t)) # 4434270720
print(id((1, 2))) # 4434270720
foo()
whereas they are distinct when part of separate code, such as separate input statements in the shell
>>> t = (1, 2)
>>> print(id(t))
4484905536
>>> print(id((1, 2)))
4485748416
These optimisation have been carefully chosen to conservatively improve code execution, and are deeply ingrained in the interpreter – this includes not being harmful in practice. You cannot easily switch them off, nor should you.