Skip to content
Create a gist now

Instantly share code, notes, and snippets.

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
Something went wrong with that request. Please try again.