Author bup
Recipients bup, cheryl.sabella, eric.snow, python-dev, rhettinger, serhiy.storchaka
Date 2018-11-04.09:11:37
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1541322698.24.0.788709270274.issue25410@psf.upfronthosting.co.za>
In-reply-to
Content
It might be more appropriate to start a new issue for this, but I'll leave that decision to somehow who would know for sure. Anyway, basically the entire dict/PyDictObject api functions do not appear work at all with OrderedDict. Or rather, OrderedDict doesn't seem to be able to recognize the changes the dict api makes to an object. This is present in both 3.6.0 and 3.7.0 by the way.

	from operator import setitem
	from collections import OrderedDict
	from pprint import pprint
	class thing:
		def __init__(self):
			ns = OrderedDict(a='od.__init__')
			vars(__class__)['__dict__'].__set__(self, ns)
			dict.__setitem__(ns, 'b', 'dict.__setitem__')
			self.c = 'PyObject_SetAttr'
			OrderedDict.__setitem__(ns, 'd', 'od.__setitem__')
			ns.update(e='od.update')
			object.__setattr__(self, 'f', 'PyObject_GenericSetAttr')
			setattr(self, 'f', 'PyObject_SetAttr')
			setitem(ns, 'g', 'od.__setitem__')
			dict.update(ns, h='dict.update')
			dict.setdefault(ns, 'i', 'i')
	self    = thing()
	ns      = self.__dict__
	real_ns = {**ns}
	missing = {k: ns[k] for k in real_ns.keys() - ns.keys()}
	pprint(ns)
	pprint(missing, width=len(f'{missing}')-1)
	print(f'"b" in {ns.keys()} == {"b" in ns.keys()}')
	print(f'"b" in {*ns.keys(),} == {"b" in [*ns.keys()]}')
	del ns['a']
	del ns['b']
	print(f"ns.get('c', KeyError('c')) == {ns.get('c', KeyError('c'))}")
	print(f"ns.pop('c', KeyError('c')) == {ns.pop('c', KeyError('c'))!r}")
	ns.get('i')
	ns.pop('i')

Maybe it's considered undefined behavior for a subclass to use 
 a method of one of its bases which it has overriden. That's fair enough, but as this example demonstrates, the silence and arbitrariness of the errors is a real problem when OrderedDict is used as a namespace, since it's a complete coin toss on whether one of the many internal API function will set an attribute or name via PyDict_SetItem or PyObject_SetItem. Only the former can invoke the methods OrderedDict overrides and there isn't any easy-to-find on the subject as far as I know.
History
Date User Action Args
2018-11-04 09:11:38bupsetrecipients: + bup, rhettinger, python-dev, eric.snow, serhiy.storchaka, cheryl.sabella
2018-11-04 09:11:38bupsetmessageid: <1541322698.24.0.788709270274.issue25410@psf.upfronthosting.co.za>
2018-11-04 09:11:38buplinkissue25410 messages
2018-11-04 09:11:37bupcreate