Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
pythonic monkey patching built-in types
# found this from Armin R. on Twitter, what a beautiful gem ;)
import ctypes
from types import DictProxyType, MethodType
# figure out side of _Py_ssize_t
if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'):
_Py_ssize_t = ctypes.c_int64
_Py_ssize_t = ctypes.c_int
# regular python
class _PyObject(ctypes.Structure):
_PyObject._fields_ = [
('ob_refcnt', _Py_ssize_t),
('ob_type', ctypes.POINTER(_PyObject))
# python with trace
if object.__basicsize__ != ctypes.sizeof(_PyObject):
class _PyObject(ctypes.Structure):
_PyObject._fields_ = [
('_ob_next', ctypes.POINTER(_PyObject)),
('_ob_prev', ctypes.POINTER(_PyObject)),
('ob_refcnt', _Py_ssize_t),
('ob_type', ctypes.POINTER(_PyObject))
class _DictProxy(_PyObject):
_fields_ = [('dict', ctypes.POINTER(_PyObject))]
def reveal_dict(proxy):
if not isinstance(proxy, DictProxyType):
raise TypeError('dictproxy expected')
dp = _DictProxy.from_address(id(proxy))
ns = {}
return ns[None]
def get_class_dict(cls):
d = getattr(cls, '__dict__', None)
if d is None:
raise TypeError('given class does not have a dictionary')
if isinstance(d, DictProxyType):
return reveal_dict(d)
return d
def test():
from random import choice
d = get_class_dict(str)
d['foo'] = lambda x: ''.join(choice((c.upper, c.lower))() for c in x)
print "and this is monkey patching str".foo()
if __name__ == '__main__':


Cool. But I found this on:
Warning It is not safe to use PyDict_SetItem() on or otherwise modify tp_dict with the dictionary C-API.

I was looking for it. Thanks.

thedrow commented Jun 21, 2013

@pawelgalazka What exactly do you mean by unsafe?


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