If DictMixin is gone, is UserDict worth even keeping? UserDict.UserDict seemed only useful back before types could not be subclassed. And every time I suggested removing UserDict and friends people always pointed to the mixin classes as reasons for keeping them around.
-Brett On Feb 4, 2008 2:07 PM, raymond.hettinger <[email protected]> wrote: > Author: raymond.hettinger > Date: Mon Feb 4 23:07:15 2008 > New Revision: 60577 > > Modified: > python/branches/py3k/Doc/library/userdict.rst > python/branches/py3k/Lib/UserDict.py > python/branches/py3k/Lib/bsddb/dbshelve.py > python/branches/py3k/Lib/test/test_shelve.py > python/branches/py3k/Lib/test/test_userdict.py > python/branches/py3k/Misc/NEWS > Log: > Remove DictMixin which is superceded by collections.MutableMapping > > Modified: python/branches/py3k/Doc/library/userdict.rst > ============================================================================== > --- python/branches/py3k/Doc/library/userdict.rst (original) > +++ python/branches/py3k/Doc/library/userdict.rst Mon Feb 4 23:07:15 > 2008 > @@ -52,24 +52,6 @@ > A real dictionary used to store the contents of the :class:`UserDict` > class. > > > -.. class:: DictMixin() > - > - Mixin defining all dictionary methods for classes that already have a > minimum > - dictionary interface including :meth:`__getitem__`, :meth:`__setitem__`, > - :meth:`__delitem__`, and :meth:`keys`. > - > - This mixin should be used as a superclass. Adding each of the above > methods > - adds progressively more functionality. For instance, defining all but > - :meth:`__delitem__` will preclude only :meth:`pop` and :meth:`popitem` > from the > - full interface. > - > - In addition to the four base methods, progressively more efficiency comes > - with defining :meth:`__contains__` and :meth:`__iter__`. > - > - Since the mixin has no knowledge of the subclass constructor, it does not > define > - :meth:`__init__` or :meth:`copy`. > - > - > :mod:`UserList` --- Class wrapper for list objects > ================================================== > > > Modified: python/branches/py3k/Lib/UserDict.py > ============================================================================== > --- python/branches/py3k/Lib/UserDict.py (original) > +++ python/branches/py3k/Lib/UserDict.py Mon Feb 4 23:07:15 2008 > @@ -79,103 +79,3 @@ > class IterableUserDict(UserDict): > def __iter__(self): > return iter(self.data) > - > -class DictMixin: > - # Mixin defining all dictionary methods for classes that already have > - # a minimum dictionary interface including getitem, setitem, delitem, > - # and keys. Without knowledge of the subclass constructor, the mixin > - # does not define __init__() or copy(). In addition to the four base > - # methods, progressively more efficiency comes with defining > - # __contains__(), __iter__(), and iteritems(). > - > - # XXX It would make more sense to expect __iter__ to be primitive. > - > - # second level definitions support higher levels > - def __iter__(self): > - for k in self.keys(): > - yield k > - def __contains__(self, key): > - try: > - value = self[key] > - except KeyError: > - return False > - return True > - > - # third level takes advantage of second level definitions > - def iterkeys(self): > - return self.__iter__() > - def iteritems(self): > - for k in self: > - yield (k, self[k]) > - > - # fourth level uses definitions from lower levels > - def itervalues(self): > - for _, v in self.iteritems(): > - yield v > - def values(self): > - return [v for _, v in self.iteritems()] > - def items(self): > - return list(self.iteritems()) > - def clear(self): > - for key in list(self.iterkeys()): > - del self[key] > - def setdefault(self, key, default=None): > - try: > - return self[key] > - except KeyError: > - self[key] = default > - return default > - def pop(self, key, *args): > - if len(args) > 1: > - raise TypeError("pop expected at most 2 arguments, got " > - + repr(1 + len(args))) > - try: > - value = self[key] > - except KeyError: > - if args: > - return args[0] > - raise > - del self[key] > - return value > - def popitem(self): > - try: > - k, v = next(self.iteritems()) > - except StopIteration: > - raise KeyError('container is empty') > - del self[k] > - return (k, v) > - def update(self, other=None, **kwargs): > - # Make progressively weaker assumptions about "other" > - if other is None: > - pass > - elif hasattr(other, 'iteritems'): # iteritems saves memory and > lookups > - for k, v in other.iteritems(): > - self[k] = v > - elif hasattr(other, 'items'): # items may also save memory and > lookups > - for k, v in other.items(): > - self[k] = v > - elif hasattr(other, 'keys'): > - for k in other.keys(): > - self[k] = other[k] > - else: > - for k, v in other: > - self[k] = v > - if kwargs: > - self.update(kwargs) > - def get(self, key, default=None): > - try: > - return self[key] > - except KeyError: > - return default > - def __repr__(self): > - return repr(dict(self.iteritems())) > - def __eq__(self, other): > - if isinstance(other, DictMixin): > - other = dict(other.iteritems()) > - return dict(self.iteritems()) == other > - def __ne__(self, other): > - if isinstance(other, DictMixin): > - other = dict(other.iteritems()) > - return dict(self.iteritems()) != other > - def __len__(self): > - return len(self.keys()) > > Modified: python/branches/py3k/Lib/bsddb/dbshelve.py > ============================================================================== > --- python/branches/py3k/Lib/bsddb/dbshelve.py (original) > +++ python/branches/py3k/Lib/bsddb/dbshelve.py Mon Feb 4 23:07:15 2008 > @@ -32,8 +32,7 @@ > import pickle > import sys > > -#At version 2.3 cPickle switched to using protocol instead of bin and > -#DictMixin was added > +#At version 2.3 cPickle switched to using protocol instead of bin > if sys.version_info[:3] >= (2, 3, 0): > HIGHEST_PROTOCOL = pickle.HIGHEST_PROTOCOL > def _dumps(object, protocol): > > Modified: python/branches/py3k/Lib/test/test_shelve.py > ============================================================================== > --- python/branches/py3k/Lib/test/test_shelve.py (original) > +++ python/branches/py3k/Lib/test/test_shelve.py Mon Feb 4 23:07:15 > 2008 > @@ -2,13 +2,13 @@ > import shelve > import glob > from test import test_support > -from UserDict import DictMixin > +from collections import MutableMapping > from test.test_anydbm import dbm_iterator > > def L1(s): > return s.decode("latin-1") > > -class byteskeydict(DictMixin): > +class byteskeydict(MutableMapping): > "Mapping that supports bytes keys" > > def __init__(self): > @@ -23,10 +23,15 @@ > def __delitem__(self, key): > del self.d[L1(key)] > > + def __len__(self): > + return len(self.d) > + > def iterkeys(self): > for k in self.d.keys(): > yield k.encode("latin-1") > > + __iter__ = iterkeys > + > def keys(self): > return list(self.iterkeys()) > > > Modified: python/branches/py3k/Lib/test/test_userdict.py > ============================================================================== > --- python/branches/py3k/Lib/test/test_userdict.py (original) > +++ python/branches/py3k/Lib/test/test_userdict.py Mon Feb 4 23:07:15 > 2008 > @@ -194,150 +194,11 @@ > else: > self.fail("g[42] didn't raise KeyError") > > -########################## > -# Test Dict Mixin > > -class SeqDict(UserDict.DictMixin): > - """Dictionary lookalike implemented with lists. > - > - Used to test and demonstrate DictMixin > - """ > - def __init__(self, other=None, **kwargs): > - self.keylist = [] > - self.valuelist = [] > - if other is not None: > - for (key, value) in other: > - self[key] = value > - for (key, value) in kwargs.items(): > - self[key] = value > - def __getitem__(self, key): > - try: > - i = self.keylist.index(key) > - except ValueError: > - raise KeyError > - return self.valuelist[i] > - def __setitem__(self, key, value): > - try: > - i = self.keylist.index(key) > - self.valuelist[i] = value > - except ValueError: > - self.keylist.append(key) > - self.valuelist.append(value) > - def __delitem__(self, key): > - try: > - i = self.keylist.index(key) > - except ValueError: > - raise KeyError > - self.keylist.pop(i) > - self.valuelist.pop(i) > - def keys(self): > - return list(self.keylist) > - def copy(self): > - d = self.__class__() > - for key, value in self.items(): > - d[key] = value > - return d > - @classmethod > - def fromkeys(cls, keys, value=None): > - d = cls() > - for key in keys: > - d[key] = value > - return d > - > -class UserDictMixinTest(mapping_tests.TestMappingProtocol): > - type2test = SeqDict > - > - def test_all(self): > - ## Setup test and verify working of the test class > - > - # check init > - s = SeqDict() > - > - # exercise setitem > - s[10] = 'ten' > - s[20] = 'twenty' > - s[30] = 'thirty' > - > - # exercise delitem > - del s[20] > - # check getitem and setitem > - self.assertEqual(s[10], 'ten') > - # check keys() and delitem > - self.assertEqual(s.keys(), [10, 30]) > - > - ## Now, test the DictMixin methods one by one > - > - # __contains__ > - self.assert_(10 in s) > - self.assert_(20 not in s) > - > - # __iter__ > - self.assertEqual([k for k in s], [10, 30]) > - > - # __len__ > - self.assertEqual(len(s), 2) > - > - # iteritems > - self.assertEqual(list(s.items()), [(10,'ten'), (30, 'thirty')]) > - > - # iterkeys > - self.assertEqual(list(s.keys()), [10, 30]) > - > - # itervalues > - self.assertEqual(list(s.values()), ['ten', 'thirty']) > - > - # values > - self.assertEqual(s.values(), ['ten', 'thirty']) > - > - # items > - self.assertEqual(s.items(), [(10,'ten'), (30, 'thirty')]) > - > - # get > - self.assertEqual(s.get(10), 'ten') > - self.assertEqual(s.get(15,'fifteen'), 'fifteen') > - self.assertEqual(s.get(15), None) > - > - # setdefault > - self.assertEqual(s.setdefault(40, 'forty'), 'forty') > - self.assertEqual(s.setdefault(10, 'null'), 'ten') > - del s[40] > - > - # pop > - self.assertEqual(s.pop(10), 'ten') > - self.assert_(10 not in s) > - s[10] = 'ten' > - self.assertEqual(s.pop("x", 1), 1) > - s["x"] = 42 > - self.assertEqual(s.pop("x", 1), 42) > - > - # popitem > - k, v = s.popitem() > - self.assert_(k not in s) > - s[k] = v > - > - # clear > - s.clear() > - self.assertEqual(len(s), 0) > - > - # empty popitem > - self.assertRaises(KeyError, s.popitem) > - > - # update > - s.update({10: 'ten', 20:'twenty'}) > - self.assertEqual(s[10], 'ten') > - self.assertEqual(s[20], 'twenty') > - > - # cmp > - self.assertEqual(s, {10: 'ten', 20:'twenty'}) > - t = SeqDict() > - t[20] = 'twenty' > - t[10] = 'ten' > - self.assertEqual(s, t) > > def test_main(): > test_support.run_unittest( > UserDictTest, > - UserDictMixinTest > ) > > if __name__ == "__main__": > > Modified: python/branches/py3k/Misc/NEWS > ============================================================================== > --- python/branches/py3k/Misc/NEWS (original) > +++ python/branches/py3k/Misc/NEWS Mon Feb 4 23:07:15 2008 > @@ -70,6 +70,8 @@ > Library > ------- > > +- Removed UserDict.DictMixin. Replaced all its uses with > collections.MutableMapping. > + > - Issue #1703: getpass() should flush after writing prompt. > > - Issue #1585: IDLE uses non-existent xrange() function. > _______________________________________________ > Python-3000-checkins mailing list > [email protected] > http://mail.python.org/mailman/listinfo/python-3000-checkins > _______________________________________________ Python-3000-checkins mailing list [email protected] http://mail.python.org/mailman/listinfo/python-3000-checkins
