[Jython-checkins] jython: Fixed issue 2336.
stefan.richthofer
jython-checkins at python.org
Tue May 12 18:10:42 CEST 2015
https://hg.python.org/jython/rev/bfa13b3a5553
changeset: 7706:bfa13b3a5553
user: Stefan Richthofer <stefan.richthofer at gmx.de>
date: Tue May 12 18:10:07 2015 +0200
summary:
Fixed issue 2336.
files:
Lib/test/test_gc_jy.py | 31 ++++++++++++++-
src/org/python/modules/gc.java | 45 +++++++++++++++++----
2 files changed, 64 insertions(+), 12 deletions(-)
diff --git a/Lib/test/test_gc_jy.py b/Lib/test/test_gc_jy.py
--- a/Lib/test/test_gc_jy.py
+++ b/Lib/test/test_gc_jy.py
@@ -14,7 +14,7 @@
from Queue import Queue
try:
- from java.lang import System, Runnable
+ from java.lang import System, Runnable, Class
from javatests import GCTestHelper
except ImportError:
#i.e. not Jython is running
@@ -746,9 +746,15 @@
del prt
self.assertEqual(gc.collect(), 0)
+
+ at unittest.skipUnless(test_support.is_jython,
+ '''
+ The test involves Jython-specifics and is thus not supported by
+ non-Jython interpreters.
+ ''')
class GCTests_Misc(unittest.TestCase):
- #Test for issue 2337
+ # Test for issue 2337
def test_queue(self):
class X(object):
def __init__(self, q):
@@ -757,6 +763,27 @@
gc.monitorObject(x)
gc.collect()
+ # Test for issue 2336
+ def test_gc_null(self):
+ WeakReferenceGC = Class.forName('org.python.modules.gc$WeakReferenceGC')
+ # We have to actually construct the right type, the constructor is protected
+ # and Jython doesn't expose that to us; we'd get a plain WeakReference
+ # if we tried WeakReferenceGC()
+ con = WeakReferenceGC.getDeclaredConstructors()[0]
+ con.setAccessible(True)
+ x = object()
+ ref = con.newInstance(x)
+ # It works to start with
+ self.assertTrue(ref == ref)
+ self.assertTrue(ref.get() is x)
+ # Now clean up the referent
+ del x
+ while ref.get():
+ gc.collect()
+ self.assertIsNone(ref.get())
+ # Boom!
+ self.assertTrue(ref == ref)
+
if __name__ == "__main__":
unittest.main()
diff --git a/src/org/python/modules/gc.java b/src/org/python/modules/gc.java
--- a/src/org/python/modules/gc.java
+++ b/src/org/python/modules/gc.java
@@ -641,7 +641,7 @@
}
private static class WeakReferenceGC extends WeakReference<PyObject> {
- int hashCode;
+ int hashCode = 0;
public String str = null, inst_str = null;
public String cls;
boolean isInstance;
@@ -705,12 +705,32 @@
}
public boolean equals(Object ob) {
+ Object ownReferent = get();
if (ob instanceof WeakReferenceGC) {
- return ((WeakReferenceGC) ob).get().equals(get())
- && ((WeakReferenceGC) ob).hashCode() == hashCode();
+ Object otherReferent = ((WeakReferenceGC) ob).get();
+ if (ownReferent == null || otherReferent == null) {
+ return ownReferent == otherReferent &&
+ //We compare the cached hash-codes in order to get an idea
+ //whether in the both-null-case the referent was equal once.
+ hashCode == ((WeakReferenceGC) ob).hashCode;
+ } else {
+ return otherReferent.equals(ownReferent)
+ //Here the hash-codes are only compared as a consistency check.
+ && ((WeakReferenceGC) ob).hashCode == hashCode;
+ }
} else if (ob instanceof WeakrefGCCompareDummy) {
- return ((WeakrefGCCompareDummy) ob).compare != null
- && ((WeakrefGCCompareDummy) ob).compare.equals(get());
+ if (ownReferent == null ||
+ ((WeakrefGCCompareDummy) ob).compare == null) {
+ return ownReferent ==
+ ((WeakrefGCCompareDummy) ob).compare &&
+ //We compare the cached hash-codes in order to get an idea
+ //whether in the both-null-case the referent was equal once.
+ hashCode == ((WeakrefGCCompareDummy) ob).hashCode;
+ } else {
+ return ownReferent.equals(((WeakrefGCCompareDummy) ob).compare)
+ //Here the hash-codes are only compared as a consistency check.
+ && hashCode == ((WeakrefGCCompareDummy) ob).hashCode;
+ }
} else {
return false;
}
@@ -720,14 +740,19 @@
private static class WeakrefGCCompareDummy {
public static WeakrefGCCompareDummy defaultInstance =
new WeakrefGCCompareDummy();
- PyObject compare;
- int hashCode;
+ protected PyObject compare;
+ int hashCode = 0;
public void setCompare(PyObject compare) {
this.compare = compare;
hashCode = System.identityHashCode(compare);
}
-
+
+ public void clearCompare() {
+ compare = null;
+ hashCode = 0;
+ }
+
public int hashCode() {
return hashCode;
}
@@ -1430,7 +1455,7 @@
WeakrefGCCompareDummy.defaultInstance.setCompare(ob);
boolean result = monitoredObjects.contains(
WeakrefGCCompareDummy.defaultInstance);
- WeakrefGCCompareDummy.defaultInstance.compare = null;
+ WeakrefGCCompareDummy.defaultInstance.clearCompare();
return result;
}
} catch (NullPointerException npe) {
@@ -1448,7 +1473,7 @@
}
boolean result = monitoredObjects.remove(
WeakrefGCCompareDummy.defaultInstance);
- WeakrefGCCompareDummy.defaultInstance.compare = null;
+ WeakrefGCCompareDummy.defaultInstance.clearCompare();
JyAttribute.delAttr(ob, JyAttribute.GC_CYCLE_MARK_ATTR);
FinalizeTrigger ft = (FinalizeTrigger)
JyAttribute.getAttr(ob, JyAttribute.FINALIZE_TRIGGER_ATTR);
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list