[Jython-checkins] jython: Merged PR #48 github.com/jythontools/jython/pull/48, which fixes issue #2522

stefan.richthofer jython-checkins at python.org
Thu Jan 12 08:08:43 EST 2017


https://hg.python.org/jython/rev/cafb76765c27
changeset:   8005:cafb76765c27
user:        Stefan Richthofer <stefan.richthofer at gmx.de>
date:        Thu Jan 12 14:08:15 2017 +0100
summary:
  Merged PR #48 github.com/jythontools/jython/pull/48, which fixes issue #2522 defaultdict.__getitem__(unhashable) raises KeyError instead of TypeError.

files:
  Lib/test/test_defaultdict_jy.py                        |  18 ++++++++-
  NEWS                                                   |   1 +
  src/org/python/modules/_collections/PyDefaultDict.java |  14 +++++--
  3 files changed, 25 insertions(+), 8 deletions(-)


diff --git a/Lib/test/test_defaultdict_jy.py b/Lib/test/test_defaultdict_jy.py
--- a/Lib/test/test_defaultdict_jy.py
+++ b/Lib/test/test_defaultdict_jy.py
@@ -99,6 +99,16 @@
         for i in xrange(size):
             self.assertEqual(counters[i].get(), i, counters)
 
+
+class UnhashableKeyRaiseTypeErrorTestCase(unittest.TestCase):
+
+    def test_setitem_raises_typeerror(self):
+        self.assertRaises(TypeError, defaultdict(int).__setitem__, {}, 1)
+
+    def test_getitem_raises_typeerror(self):
+        self.assertRaises(TypeError, defaultdict(int).__getitem__, {})
+
+
 class GetVariantsTestCase(unittest.TestCase):
 
     #http://bugs.jython.org/issue2133
@@ -119,7 +129,6 @@
         self.assertEquals(d.items(), [("vivify", [])]) 
 
 
-
 class OverrideMissingTestCase(unittest.TestCase):
     class KeyDefaultDict(defaultdict):
         """defaultdict to pass the requested key to factory function."""
@@ -137,7 +146,8 @@
             return k + k
 
     def setUp(self):
-        self.kdd = OverrideMissingTestCase.KeyDefaultDict(OverrideMissingTestCase.KeyDefaultDict.double)
+        self.kdd = OverrideMissingTestCase.KeyDefaultDict(
+                OverrideMissingTestCase.KeyDefaultDict.double)
 
     def test_dont_call_derived_missing(self):
         self.kdd[3] = 5
@@ -151,7 +161,9 @@
 
 
 def test_main():
-    test_support.run_unittest(PickleTestCase, ThreadSafetyTestCase, GetVariantsTestCase, OverrideMissingTestCase)
+    test_support.run_unittest(PickleTestCase, ThreadSafetyTestCase,
+            UnhashableKeyRaiseTypeErrorTestCase,
+            GetVariantsTestCase, OverrideMissingTestCase)
 
 
 if __name__ == '__main__':
diff --git a/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@
 
 Jython 2.7.1rc1
   Bugs fixed
+    - [ 2522 ] defaultdict.__getitem__(unhashable) raises KeyError instead of TypeError
     - [ 2515 ] typing module doesn't import
     - [ 2538 ] Test failures in test_unittest
     - [ 2293 ] "java.lang.IllegalArgumentException: java.lang.IllegalArgumentException:
diff --git a/src/org/python/modules/_collections/PyDefaultDict.java b/src/org/python/modules/_collections/PyDefaultDict.java
--- a/src/org/python/modules/_collections/PyDefaultDict.java
+++ b/src/org/python/modules/_collections/PyDefaultDict.java
@@ -7,8 +7,10 @@
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
+import org.python.core.BuiltinDocs;
 import org.python.core.Py;
 import org.python.core.PyDictionary;
+import org.python.core.PyException;
 import org.python.core.PyObject;
 import org.python.core.PyTuple;
 import org.python.core.PyType;
@@ -21,11 +23,6 @@
 import org.python.expose.ExposedSet;
 import org.python.expose.ExposedType;
 
-import com.google.common.collect.MapMaker;
-import com.google.common.collect.ComputationException;
-import com.google.common.base.Function;
-import org.python.core.BuiltinDocs;
-
 /**
  * PyDefaultDict - This is a subclass of the builtin dict(PyDictionary) class. It supports
  * one additional method __missing__ and adds one writable instance variable
@@ -165,6 +162,13 @@
     protected final PyObject defaultdict___getitem__(PyObject key) {
         try {
             return backingMap.get(key);
+        } catch (PyException pe) {
+            /* LoadingCache#get() don't throw any PyException itself and it
+             * prevents those raised in CacheLoader#load() to get through
+             * without being wrapped in UncheckedExecutionException, so this
+             * PyException must be from key#hashCode(). We can propagated it to
+             * caller as it is. */
+            throw pe;
         } catch (Exception ex) {
             throw Py.KeyError(key);
         }

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list