Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

pythonic monkey patching built-in types

View python-monkey-patch-built-ins.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
# 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
else:
_Py_ssize_t = ctypes.c_int
 
# regular python
class _PyObject(ctypes.Structure):
pass
_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):
pass
_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 = {}
ctypes.pythonapi.PyDict_SetItem(ctypes.py_object(ns),
ctypes.py_object(None),
dp.dict)
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__':
test()

Sicko.

Cool. But I found this on: http://docs.python.org/3.3/c-api/typeobj.html#PyTypeObject.tp_dict
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.

@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.