From c979448507972ddf64d6c4cae24d428c0ac77926 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 28 Jan 2009 23:14:58 +0000 Subject: Issue 4920: Fixed next() vs __next__() issues in the ABCs for Iterator and MutableSet. Also added thorough test for required abstractmethods. --- Lib/_abcoll.py | 4 +-- Lib/test/test_collections.py | 65 ++++++++++++++++++++++++++++++++++++++++++-- Misc/NEWS | 3 ++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/Lib/_abcoll.py b/Lib/_abcoll.py index 38b44a5..36aca95 100644 --- a/Lib/_abcoll.py +++ b/Lib/_abcoll.py @@ -60,7 +60,7 @@ Iterable.register(str) class Iterator(Iterable): @abstractmethod - def __next__(self): + def next(self): raise StopIteration def __iter__(self): @@ -267,7 +267,7 @@ class MutableSet(Set): """Return the popped value. Raise KeyError if empty.""" it = iter(self) try: - value = it.__next__() + value = next(it) except StopIteration: raise KeyError self.discard(value) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 7dffd73..e11d999 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -154,7 +154,24 @@ class TestNamedTuple(unittest.TestCase): self.assertEqual(p, q) self.assertEqual(p._fields, q._fields) -class TestOneTrickPonyABCs(unittest.TestCase): +class ABCTestCase(unittest.TestCase): + + def validate_abstract_methods(self, abc, *names): + methodstubs = dict.fromkeys(names, lambda s, *args: 0) + + # everything should work will all required methods are present + C = type('C', (abc,), methodstubs) + C() + + # instantiation should fail if a required method is missing + for name in names: + stubs = methodstubs.copy() + del stubs[name] + C = type('C', (abc,), stubs) + self.assertRaises(TypeError, C, name) + + +class TestOneTrickPonyABCs(ABCTestCase): def test_Hashable(self): # Check some non-hashables @@ -180,6 +197,7 @@ class TestOneTrickPonyABCs(unittest.TestCase): __eq__ = Hashable.__eq__ # Silence Py3k warning self.assertEqual(hash(H()), 0) self.failIf(issubclass(int, H)) + self.validate_abstract_methods(Hashable, '__hash__') def test_Iterable(self): # Check some non-iterables @@ -203,6 +221,7 @@ class TestOneTrickPonyABCs(unittest.TestCase): return super(I, self).__iter__() self.assertEqual(list(I()), []) self.failIf(issubclass(str, I)) + self.validate_abstract_methods(Iterable, '__iter__') def test_Iterator(self): non_samples = [None, 42, 3.14, 1j, "".encode('ascii'), "", (), [], @@ -221,6 +240,7 @@ class TestOneTrickPonyABCs(unittest.TestCase): for x in samples: self.failUnless(isinstance(x, Iterator), repr(x)) self.failUnless(issubclass(type(x), Iterator), repr(type(x))) + self.validate_abstract_methods(Iterator, 'next') def test_Sized(self): non_samples = [None, 42, 3.14, 1j, @@ -237,6 +257,7 @@ class TestOneTrickPonyABCs(unittest.TestCase): for x in samples: self.failUnless(isinstance(x, Sized), repr(x)) self.failUnless(issubclass(type(x), Sized), repr(type(x))) + self.validate_abstract_methods(Sized, '__len__') def test_Container(self): non_samples = [None, 42, 3.14, 1j, @@ -253,6 +274,7 @@ class TestOneTrickPonyABCs(unittest.TestCase): for x in samples: self.failUnless(isinstance(x, Container), repr(x)) self.failUnless(issubclass(type(x), Container), repr(type(x))) + self.validate_abstract_methods(Container, '__contains__') def test_Callable(self): non_samples = [None, 42, 3.14, 1j, @@ -271,6 +293,7 @@ class TestOneTrickPonyABCs(unittest.TestCase): for x in samples: self.failUnless(isinstance(x, Callable), repr(x)) self.failUnless(issubclass(type(x), Callable), repr(type(x))) + self.validate_abstract_methods(Callable, '__call__') def test_direct_subclassing(self): for B in Hashable, Iterable, Iterator, Sized, Container, Callable: @@ -289,7 +312,7 @@ class TestOneTrickPonyABCs(unittest.TestCase): self.failUnless(issubclass(C, B)) -class TestCollectionABCs(unittest.TestCase): +class TestCollectionABCs(ABCTestCase): # XXX For now, we only test some virtual inheritance properties. # We should also test the proper behavior of the collection ABCs @@ -299,6 +322,7 @@ class TestCollectionABCs(unittest.TestCase): for sample in [set, frozenset]: self.failUnless(isinstance(sample(), Set)) self.failUnless(issubclass(sample, Set)) + self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') def test_hash_Set(self): class OneTwoThreeSet(Set): @@ -320,22 +344,57 @@ class TestCollectionABCs(unittest.TestCase): self.failUnless(issubclass(set, MutableSet)) self.failIf(isinstance(frozenset(), MutableSet)) self.failIf(issubclass(frozenset, MutableSet)) + self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', + 'add', 'discard') + + def test_issue_4920(self): + # MutableSet.pop() method did not work + class MySet(collections.MutableSet): + __slots__=['__s'] + def __init__(self,items=None): + if items is None: + items=[] + self.__s=set(items) + def __contains__(self,v): + return v in self.__s + def __iter__(self): + return iter(self.__s) + def __len__(self): + return len(self.__s) + def add(self,v): + result=v not in self.__s + self.__s.add(v) + return result + def discard(self,v): + result=v in self.__s + self.__s.discard(v) + return result + def __repr__(self): + return "MySet(%s)" % repr(list(self)) + s = MySet([5,43,2,1]) + self.assertEqual(s.pop(), 1) def test_Mapping(self): for sample in [dict]: self.failUnless(isinstance(sample(), Mapping)) self.failUnless(issubclass(sample, Mapping)) + self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', + '__getitem__') def test_MutableMapping(self): for sample in [dict]: self.failUnless(isinstance(sample(), MutableMapping)) self.failUnless(issubclass(sample, MutableMapping)) + self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', + '__getitem__', '__setitem__', '__delitem__') def test_Sequence(self): for sample in [tuple, list, str]: self.failUnless(isinstance(sample(), Sequence)) self.failUnless(issubclass(sample, Sequence)) self.failUnless(issubclass(basestring, Sequence)) + self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', + '__getitem__') def test_MutableSequence(self): for sample in [tuple, str]: @@ -345,6 +404,8 @@ class TestCollectionABCs(unittest.TestCase): self.failUnless(isinstance(sample(), MutableSequence)) self.failUnless(issubclass(sample, MutableSequence)) self.failIf(issubclass(basestring, MutableSequence)) + self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', + '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') import doctest, collections diff --git a/Misc/NEWS b/Misc/NEWS index 1a39f0e..af0a7ff 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -76,6 +76,9 @@ Core and Builtins Library ------- +- Issue 4920: Fixed .next() vs .__next__() issues in the ABCs for + Iterator and MutableSet. + - Issue 5021: doctest.testfile() did not create __name__ and collections.namedtuple() relied on __name__ being defined. -- cgit v0.12 tion value='bug_3606683'>bug_3606683 Tcl is a high-level, general-purpose, interpreted, dynamic programming language. It was designed with the goal of being very simple but powerful.
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2002-08-20 15:33:31 (GMT)
committerdgp <dgp@users.sourceforge.net>2002-08-20 15:33:31 (GMT)
commitd768d45269fd4e4b6012d73d8c27390cd81c84df (patch)
tree8cc82493e4b49455533f5c68616f91ce879a8a31
parent7103d942718e5537c2c81195f0c0949ef529e08f (diff)
downloadtcl-d768d45269fd4e4b6012d73d8c27390cd81c84df.zip
tcl-d768d45269fd4e4b6012d73d8c27390cd81c84df.tar.gz
tcl-d768d45269fd4e4b6012d73d8c27390cd81c84df.tar.bz2
* README: Bumped version number to 8.4b3 to distinguish
* generic/tcl.h: HEAD from the 8.4b2 release. * tools/tcl.wse.in: * unix/configure.in: * unix/tcl.spec: * win/README.binary: * win/configure.in: * unix/configure: autoconf * win/configure: * library/http/http.tcl: Corrected installation directory of * library/msgcat/msgcat.tcl: the package tcltest 2.2. Added * library/opt/optparse.tcl: comments in other packages to remind * library/tcltest/tcltest.tcl: that installation directories need * unix/Makefile.in: updates to match increasing version * win/Makefile.in: numbers. [Bug 597450] * win/makefile.bc: * win/makefile.vc:
-rw-r--r--ChangeLog22
-rw-r--r--README4
-rw-r--r--generic/tcl.h6
-rw-r--r--library/http/http.tcl3
-rw-r--r--library/msgcat/msgcat.tcl4
-rw-r--r--library/opt/optparse.tcl4
-rw-r--r--library/tcltest/tcltest.tcl5
-rw-r--r--tools/tcl.wse.in2
-rw-r--r--unix/Makefile.in8
-rwxr-xr-xunix/configure2
-rw-r--r--unix/configure.in4
-rw-r--r--unix/tcl.spec4
-rw-r--r--win/Makefile.in8
-rw-r--r--win/README.binary4
-rwxr-xr-xwin/configure2
-rw-r--r--win/configure.in4
-rw-r--r--win/makefile.bc8
-rw-r--r--win/makefile.vc6
18 files changed, 65 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 1eeff6f..e391f93 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2002-08-20 Don Porter <dgp@users.sourceforge.net>
+
+ * README: Bumped version number to 8.4b3 to distinguish
+ * generic/tcl.h: HEAD from the 8.4b2 release.
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/README.binary:
+ * win/configure.in:
+
+ * unix/configure: autoconf
+ * win/configure:
+
+ * library/http/http.tcl: Corrected installation directory of
+ * library/msgcat/msgcat.tcl: the package tcltest 2.2. Added
+ * library/opt/optparse.tcl: comments in other packages to remind
+ * library/tcltest/tcltest.tcl: that installation directories need
+ * unix/Makefile.in: updates to match increasing version
+ * win/Makefile.in: numbers. [Bug 597450]
+ * win/makefile.bc:
+ * win/makefile.vc:
+
2002-08-19 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* unix/tclUnixTest.c (TestfilehandlerCmd): Changed
diff --git a/README b/README
index 903b8f8..912cf3a 100644
--- a/README
+++ b/README
@@ -1,11 +1,11 @@
README: Tcl
- This is the Tcl 8.4b2 source distribution.
+ This is the Tcl 8.4b3 source distribution.
Tcl/Tk is also available through NetCVS:
http://tcl.sourceforge.net/
You can get any source release of Tcl from the file distributions
link at the above URL.
-RCS: @(#) $Id: README,v 1.43 2002/07/14 17:29:01 dgp Exp $
+RCS: @(#) $Id: README,v 1.44 2002/08/20 15:33:32 dgp Exp $
Contents
--------
diff --git a/generic/tcl.h b/generic/tcl.h
index 3bf2ae0..8de3c7e 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tcl.h,v 1.139 2002/08/05 03:24:40 dgp Exp $
+ * RCS: @(#) $Id: tcl.h,v 1.140 2002/08/20 15:33:32 dgp Exp $
*/
#ifndef _TCL
@@ -57,10 +57,10 @@ extern "C" {
#define TCL_MAJOR_VERSION 8
#define TCL_MINOR_VERSION 4
#define TCL_RELEASE_LEVEL TCL_BETA_RELEASE
-#define TCL_RELEASE_SERIAL 2
+#define TCL_RELEASE_SERIAL 3
#define TCL_VERSION "8.4"
-#define TCL_PATCH_LEVEL "8.4b2"
+#define TCL_PATCH_LEVEL "8.4b3"
/*
* The following definitions set up the proper options for Windows
diff --git a/library/http/http.tcl b/library/http/http.tcl
index 3cc0640..ed64ac9 100644
--- a/library/http/http.tcl
+++ b/library/http/http.tcl
@@ -9,7 +9,7 @@
# See the file "license.terms" for information on usage and
# redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: http.tcl,v 1.41 2002/02/05 17:08:04 dgp Exp $
+# RCS: @(#) $Id: http.tcl,v 1.42 2002/08/20 15:33:32 dgp Exp $
# Rough version history:
# 1.0 Old http_get interface
@@ -24,6 +24,7 @@
package require Tcl 8.2
# keep this in sync with pkgIndex.tcl
+# and with the install directories in Makefiles
package provide http 2.4.2
namespace eval http {
diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl
index 771511f..13bf10d 100644
--- a/library/msgcat/msgcat.tcl
+++ b/library/msgcat/msgcat.tcl
@@ -10,9 +10,11 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: msgcat.tcl,v 1.16 2002/07/17 19:14:52 drh Exp $
+# RCS: @(#) $Id: msgcat.tcl,v 1.17 2002/08/20 15:33:32 dgp Exp $
package require Tcl 8.2
+# When the version number changes, be sure to update the pkgIndex.tcl file,
+# and the installation directory in the Makefiles.
package provide msgcat 1.3
namespace eval msgcat {
diff --git a/library/opt/optparse.tcl b/library/opt/optparse.tcl
index e710008..b329190 100644
--- a/library/opt/optparse.tcl
+++ b/library/opt/optparse.tcl
@@ -8,9 +8,11 @@
# on it. If your code does rely on this package you
# may directly incorporate this code into your application.
#
-# RCS: @(#) $Id: optparse.tcl,v 1.6 2001/08/09 01:06:42 dgp Exp $
+# RCS: @(#) $Id: optparse.tcl,v 1.7 2002/08/20 15:33:32 dgp Exp $
package require Tcl 8
+# When this version number changes, update the pkgIndex.tcl file
+# and the install directory in the Makefiles.
package provide opt 0.4.3
namespace eval ::tcl {
diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl