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

Reply via email to