def __dir__(self):
def get_attrs(obj):
import types
if not hasattr(obj, '__dict__'):
return [] # slots only
if not isinstance(obj.__dict__, (dict, types.DictProxyType)):
raise TypeError("%s.__dict__ is not a dictionary"
"" % obj.__name__)
return obj.__dict__.keys()
def dir2(obj):
attrs = set()
if not hasattr(obj, '__bases__'):
# obj is an instance
if not hasattr(obj, '__class__'):
# slots
return sorted(get_attrs(obj))
klass = obj.__class__
attrs.update(get_attrs(klass))
else:
# obj is a class
klass = obj
for cls in klass.__bases__:
attrs.update(get_attrs(cls))
attrs.update(dir2(cls))
attrs.update(get_attrs(obj))
return list(attrs)
return dir2(self)
python类DictProxyType()的实例源码
def __dir__(self):
def get_attrs(obj):
import types
if not hasattr(obj, '__dict__'):
return []
if not isinstance(obj.__dict__, (dict, types.DictProxyType)):
raise TypeError(
'{0}.__dict__ is not a dictionary'.format(obj.__name__))
return obj.__dict__.keys()
def dir2(obj):
attrs = set()
if not hasattr(obj, '__bases__'):
# obj is an instance
if not hasattr(obj, '__class__'):
# slots
return sorted(get_attrs(obj))
klass = obj.__class__
attrs.update(get_attrs(klass))
else:
# obj is a class
klass = obj
for cls in klass.__bases__:
attrs.update(get_attrs(cls))
attrs.update(dir2(cls))
attrs.update(get_attrs(obj))
return list(attrs)
return dir2(self) + self.keys()
# TODO: Ditch this behavior. (Backwards incompatible change!)
# It's probably that at some point a user is going create a method named
# the same as a key fetched from PIX.
def _get_attrs(obj):
from types import DictProxyType
if not hasattr(obj, '__dict__'): # pragma: no cover
return [] # slots only
if not isinstance(obj.__dict__,
(dict, DictProxyType)): # pragma: no cover
raise TypeError("{}.__dict__ is not a dictionary".format(
obj.__name__))
return obj.__dict__.keys()
# https://stackoverflow.com/questions/
# 15507848/the-correct-way-to-override-the-dir-method-in-python
def test_dictproxy():
# This is the dictproxy constructor itself from the Python API,
DP = ctypes.pythonapi.PyDictProxy_New
DP.argtypes, DP.restype = (ctypes.py_object,), ctypes.py_object
underlying_dict = {}
mp_recursive = DP(underlying_dict)
underlying_dict[0] = mp_recursive
underlying_dict[-3] = underlying_dict
cases = [
(DP({}), "dict_proxy({})"),
(DP({None: DP({})}), "dict_proxy({None: dict_proxy({})})"),
(DP({k: k.lower() for k in string.ascii_uppercase}),
"dict_proxy({'A': 'a',\n"
" 'B': 'b',\n"
" 'C': 'c',\n"
" 'D': 'd',\n"
" 'E': 'e',\n"
" 'F': 'f',\n"
" 'G': 'g',\n"
" 'H': 'h',\n"
" 'I': 'i',\n"
" 'J': 'j',\n"
" 'K': 'k',\n"
" 'L': 'l',\n"
" 'M': 'm',\n"
" 'N': 'n',\n"
" 'O': 'o',\n"
" 'P': 'p',\n"
" 'Q': 'q',\n"
" 'R': 'r',\n"
" 'S': 's',\n"
" 'T': 't',\n"
" 'U': 'u',\n"
" 'V': 'v',\n"
" 'W': 'w',\n"
" 'X': 'x',\n"
" 'Y': 'y',\n"
" 'Z': 'z'})"),
(mp_recursive, "dict_proxy({-3: {-3: {...}, 0: {...}}, 0: {...}})"),
]
for obj, expected in cases:
nt.assert_is_instance(obj, types.DictProxyType) # Meta-test
nt.assert_equal(pretty.pretty(obj), expected)
nt.assert_equal(pretty.pretty(underlying_dict),
"{-3: {...}, 0: dict_proxy({-3: {...}, 0: {...}})}")
def test_dictproxy():
# This is the dictproxy constructor itself from the Python API,
DP = ctypes.pythonapi.PyDictProxy_New
DP.argtypes, DP.restype = (ctypes.py_object,), ctypes.py_object
underlying_dict = {}
mp_recursive = DP(underlying_dict)
underlying_dict[0] = mp_recursive
underlying_dict[-3] = underlying_dict
cases = [
(DP({}), "dict_proxy({})"),
(DP({None: DP({})}), "dict_proxy({None: dict_proxy({})})"),
(DP({k: k.lower() for k in string.ascii_uppercase}),
"dict_proxy({'A': 'a',\n"
" 'B': 'b',\n"
" 'C': 'c',\n"
" 'D': 'd',\n"
" 'E': 'e',\n"
" 'F': 'f',\n"
" 'G': 'g',\n"
" 'H': 'h',\n"
" 'I': 'i',\n"
" 'J': 'j',\n"
" 'K': 'k',\n"
" 'L': 'l',\n"
" 'M': 'm',\n"
" 'N': 'n',\n"
" 'O': 'o',\n"
" 'P': 'p',\n"
" 'Q': 'q',\n"
" 'R': 'r',\n"
" 'S': 's',\n"
" 'T': 't',\n"
" 'U': 'u',\n"
" 'V': 'v',\n"
" 'W': 'w',\n"
" 'X': 'x',\n"
" 'Y': 'y',\n"
" 'Z': 'z'})"),
(mp_recursive, "dict_proxy({-3: {-3: {...}, 0: {...}}, 0: {...}})"),
]
for obj, expected in cases:
nt.assert_is_instance(obj, types.DictProxyType) # Meta-test
nt.assert_equal(pretty.pretty(obj), expected)
nt.assert_equal(pretty.pretty(underlying_dict),
"{-3: {...}, 0: dict_proxy({-3: {...}, 0: {...}})}")