From jython-checkins at python.org Thu Sep 4 06:35:34 2014 From: jython-checkins at python.org (jim.baker) Date: Thu, 4 Sep 2014 06:35:34 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fixed_issue_1057=2E_In_this?= =?utf-8?q?_patch_I_propose_to_forbid_Java-style_finalizers_for?= Message-ID: <3hpTj26LW3z7Ljn@mail.python.org> http://hg.python.org/jython/rev/288366399aed changeset: 7360:288366399aed parent: 7348:2c45f75a5406 user: Stefan Richthofer date: Mon Aug 18 12:23:58 2014 +0200 summary: Fixed issue 1057. In this patch I propose to forbid Java-style finalizers for PyObject subclasses. However there is an easy fix available for usecases where it is needed. If the impact of this decision for third party custom types should be too high, one could make it a compiler warning instead and undetake the obligatory change for Jython 3 or so. files: Lib/test/test_finalizers.py | 403 ++++++++++ src/org/python/antlr/ast/AssertDerived.java | 26 +- src/org/python/antlr/ast/AssignDerived.java | 26 +- src/org/python/antlr/ast/AttributeDerived.java | 26 +- src/org/python/antlr/ast/AugAssignDerived.java | 26 +- src/org/python/antlr/ast/BinOpDerived.java | 26 +- src/org/python/antlr/ast/BoolOpDerived.java | 26 +- src/org/python/antlr/ast/BreakDerived.java | 26 +- src/org/python/antlr/ast/CallDerived.java | 26 +- src/org/python/antlr/ast/ClassDefDerived.java | 26 +- src/org/python/antlr/ast/CompareDerived.java | 26 +- src/org/python/antlr/ast/ContinueDerived.java | 26 +- src/org/python/antlr/ast/DeleteDerived.java | 26 +- src/org/python/antlr/ast/DictDerived.java | 26 +- src/org/python/antlr/ast/EllipsisDerived.java | 26 +- src/org/python/antlr/ast/ExceptHandlerDerived.java | 26 +- src/org/python/antlr/ast/ExecDerived.java | 26 +- src/org/python/antlr/ast/ExprDerived.java | 26 +- src/org/python/antlr/ast/ExpressionDerived.java | 26 +- src/org/python/antlr/ast/ExtSliceDerived.java | 26 +- src/org/python/antlr/ast/ForDerived.java | 26 +- src/org/python/antlr/ast/FunctionDefDerived.java | 26 +- src/org/python/antlr/ast/GeneratorExpDerived.java | 26 +- src/org/python/antlr/ast/GlobalDerived.java | 26 +- src/org/python/antlr/ast/IfDerived.java | 26 +- src/org/python/antlr/ast/IfExpDerived.java | 26 +- src/org/python/antlr/ast/ImportDerived.java | 26 +- src/org/python/antlr/ast/ImportFromDerived.java | 26 +- src/org/python/antlr/ast/IndexDerived.java | 26 +- src/org/python/antlr/ast/InteractiveDerived.java | 26 +- src/org/python/antlr/ast/LambdaDerived.java | 26 +- src/org/python/antlr/ast/ListCompDerived.java | 26 +- src/org/python/antlr/ast/ListDerived.java | 26 +- src/org/python/antlr/ast/ModuleDerived.java | 26 +- src/org/python/antlr/ast/NameDerived.java | 26 +- src/org/python/antlr/ast/NumDerived.java | 26 +- src/org/python/antlr/ast/PassDerived.java | 26 +- src/org/python/antlr/ast/PrintDerived.java | 26 +- src/org/python/antlr/ast/RaiseDerived.java | 26 +- src/org/python/antlr/ast/ReprDerived.java | 26 +- src/org/python/antlr/ast/ReturnDerived.java | 26 +- src/org/python/antlr/ast/SliceDerived.java | 26 +- src/org/python/antlr/ast/StrDerived.java | 26 +- src/org/python/antlr/ast/SubscriptDerived.java | 26 +- src/org/python/antlr/ast/SuiteDerived.java | 26 +- src/org/python/antlr/ast/TryExceptDerived.java | 26 +- src/org/python/antlr/ast/TryFinallyDerived.java | 26 +- src/org/python/antlr/ast/TupleDerived.java | 26 +- src/org/python/antlr/ast/UnaryOpDerived.java | 26 +- src/org/python/antlr/ast/WhileDerived.java | 26 +- src/org/python/antlr/ast/WithDerived.java | 26 +- src/org/python/antlr/ast/YieldDerived.java | 26 +- src/org/python/antlr/ast/aliasDerived.java | 26 +- src/org/python/antlr/ast/argumentsDerived.java | 26 +- src/org/python/antlr/ast/comprehensionDerived.java | 26 +- src/org/python/antlr/ast/keywordDerived.java | 26 +- src/org/python/antlr/op/AddDerived.java | 26 +- src/org/python/antlr/op/AndDerived.java | 26 +- src/org/python/antlr/op/AugLoadDerived.java | 26 +- src/org/python/antlr/op/AugStoreDerived.java | 26 +- src/org/python/antlr/op/BitAndDerived.java | 26 +- src/org/python/antlr/op/BitOrDerived.java | 26 +- src/org/python/antlr/op/BitXorDerived.java | 26 +- src/org/python/antlr/op/DelDerived.java | 26 +- src/org/python/antlr/op/DivDerived.java | 26 +- src/org/python/antlr/op/EqDerived.java | 26 +- src/org/python/antlr/op/FloorDivDerived.java | 26 +- src/org/python/antlr/op/GtDerived.java | 26 +- src/org/python/antlr/op/GtEDerived.java | 26 +- src/org/python/antlr/op/InDerived.java | 26 +- src/org/python/antlr/op/InvertDerived.java | 26 +- src/org/python/antlr/op/IsDerived.java | 26 +- src/org/python/antlr/op/IsNotDerived.java | 26 +- src/org/python/antlr/op/LShiftDerived.java | 26 +- src/org/python/antlr/op/LoadDerived.java | 26 +- src/org/python/antlr/op/LtDerived.java | 26 +- src/org/python/antlr/op/LtEDerived.java | 26 +- src/org/python/antlr/op/ModDerived.java | 26 +- src/org/python/antlr/op/MultDerived.java | 26 +- src/org/python/antlr/op/NotDerived.java | 26 +- src/org/python/antlr/op/NotEqDerived.java | 26 +- src/org/python/antlr/op/NotInDerived.java | 26 +- src/org/python/antlr/op/OrDerived.java | 26 +- src/org/python/antlr/op/ParamDerived.java | 26 +- src/org/python/antlr/op/PowDerived.java | 26 +- src/org/python/antlr/op/RShiftDerived.java | 26 +- src/org/python/antlr/op/StoreDerived.java | 26 +- src/org/python/antlr/op/SubDerived.java | 26 +- src/org/python/antlr/op/UAddDerived.java | 26 +- src/org/python/antlr/op/USubDerived.java | 26 +- src/org/python/core/ClasspathPyImporterDerived.java | 23 +- src/org/python/core/PyArrayDerived.java | 26 +- src/org/python/core/PyBaseExceptionDerived.java | 23 +- src/org/python/core/PyByteArrayDerived.java | 26 +- src/org/python/core/PyClass.java | 15 +- src/org/python/core/PyClassMethodDerived.java | 26 +- src/org/python/core/PyComplexDerived.java | 26 +- src/org/python/core/PyDictionaryDerived.java | 26 +- src/org/python/core/PyEnumerateDerived.java | 26 +- src/org/python/core/PyFile.java | 16 +- src/org/python/core/PyFileDerived.java | 26 +- src/org/python/core/PyFinalizableInstance.java | 37 - src/org/python/core/PyFloatDerived.java | 26 +- src/org/python/core/PyFrozenSetDerived.java | 26 +- src/org/python/core/PyGenerator.java | 13 +- src/org/python/core/PyInstance.java | 53 +- src/org/python/core/PyIntegerDerived.java | 26 +- src/org/python/core/PyListDerived.java | 26 +- src/org/python/core/PyLongDerived.java | 26 +- src/org/python/core/PyModuleDerived.java | 23 +- src/org/python/core/PyObject.java | 15 + src/org/python/core/PyObjectDerived.java | 26 +- src/org/python/core/PyPropertyDerived.java | 26 +- src/org/python/core/PySetDerived.java | 26 +- src/org/python/core/PyStringDerived.java | 26 +- src/org/python/core/PySuperDerived.java | 26 +- src/org/python/core/PyTupleDerived.java | 26 +- src/org/python/core/PyType.java | 22 +- src/org/python/core/PyTypeDerived.java | 23 +- src/org/python/core/PyUnicodeDerived.java | 26 +- src/org/python/core/finalization/FinalizableBuiltin.java | 18 + src/org/python/core/finalization/FinalizablePyObject.java | 90 ++ src/org/python/core/finalization/FinalizablePyObjectDerived.java | 23 + src/org/python/core/finalization/FinalizeTrigger.java | 138 +++ src/org/python/core/finalization/FinalizeTriggerFactory.java | 6 + src/org/python/core/finalization/HasFinalizeTrigger.java | 13 + src/org/python/core/finalization/PyFinalizableObject.java | 17 + src/org/python/modules/PyStructDerived.java | 26 +- src/org/python/modules/_collections/PyDefaultDictDerived.java | 26 +- src/org/python/modules/_collections/PyDequeDerived.java | 26 +- src/org/python/modules/_csv/PyDialectDerived.java | 23 +- src/org/python/modules/_functools/PyPartialDerived.java | 26 +- src/org/python/modules/_io/PyFileIODerived.java | 23 +- src/org/python/modules/_io/PyIOBase.java | 11 +- src/org/python/modules/_io/PyIOBaseDerived.java | 23 +- src/org/python/modules/_io/PyRawIOBaseDerived.java | 23 +- src/org/python/modules/_weakref/ReferenceTypeDerived.java | 26 +- src/org/python/modules/bz2/PyBZ2CompressorDerived.java | 26 +- src/org/python/modules/bz2/PyBZ2DecompressorDerived.java | 26 +- src/org/python/modules/bz2/PyBZ2File.java | 13 +- src/org/python/modules/bz2/PyBZ2FileDerived.java | 26 +- src/org/python/modules/itertools/PyTeeIteratorDerived.java | 26 +- src/org/python/modules/itertools/chainDerived.java | 26 +- src/org/python/modules/itertools/combinationsDerived.java | 26 +- src/org/python/modules/itertools/combinationsWithReplacementDerived.java | 26 +- src/org/python/modules/itertools/compressDerived.java | 26 +- src/org/python/modules/itertools/countDerived.java | 26 +- src/org/python/modules/itertools/cycleDerived.java | 26 +- src/org/python/modules/itertools/dropwhileDerived.java | 26 +- src/org/python/modules/itertools/groupbyDerived.java | 26 +- src/org/python/modules/itertools/ifilterDerived.java | 26 +- src/org/python/modules/itertools/ifilterfalseDerived.java | 26 +- src/org/python/modules/itertools/isliceDerived.java | 26 +- src/org/python/modules/itertools/izipDerived.java | 26 +- src/org/python/modules/itertools/izipLongestDerived.java | 26 +- src/org/python/modules/itertools/permutationsDerived.java | 26 +- src/org/python/modules/itertools/productDerived.java | 26 +- src/org/python/modules/itertools/repeatDerived.java | 26 +- src/org/python/modules/itertools/starmapDerived.java | 26 +- src/org/python/modules/itertools/takewhileDerived.java | 26 +- src/org/python/modules/random/PyRandomDerived.java | 26 +- src/org/python/modules/thread/PyLocalDerived.java | 23 +- src/org/python/modules/zipimport/zipimporterDerived.java | 26 +- src/templates/gderived-defs | 26 +- src/templates/gderived.py | 125 +- src/templates/object.derived | 2 + 166 files changed, 4556 insertions(+), 269 deletions(-) diff --git a/Lib/test/test_finalizers.py b/Lib/test/test_finalizers.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_finalizers.py @@ -0,0 +1,403 @@ +''' +Created on 06.08.2014 +''' + +import platform +import unittest +import types +import time +if platform.system() == "Java": + from java.lang import System + from org.python.core.finalization import FinalizeTrigger + +class GCDetector(): + gcIndex = 0 + + def __del__(self): + GCDetector.gcIndex += 1 + +maxGCRun = 10 + +def runGCIfJython(): + if platform.system() == "Java": + currentIndex = GCDetector.gcIndex + gcCount = 0 + detector = GCDetector() + detector = None + while currentIndex == GCDetector.gcIndex and gcCount < maxGCRun: + System.gc() + gcCount += 1 + time.sleep(0.1) + +finalizeMsgList = [] +verbose = False +resurrectedObject_I = None +resurrectedObject_J = None +resurrectedObject_K = None +resurrectedObject_L = None +resurrectedObject_M = None +resurrectedObject_N = None + +class ResurrectableDummyClass(): + + def __init__(self, name): + self.name = name + self.doResurrection = True + + def __str__(self): + return self.name + + +class ResurrectableDummyClassNew(object): + + def __init__(self, name): + self.name = name + self.doResurrection = True + + def __str__(self): + return self.name + + +def __del__I(self): + global resurrectedObject_I + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_I = self + +def __del__J(self): + global resurrectedObject_J + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_J = self + +def __del__K(self): + global resurrectedObject_K + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_K = self + +def __del__L(self): + global resurrectedObject_L + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_L = self + +def __del__M(self): + global resurrectedObject_M + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_M = self + +def __del__N(self): + global resurrectedObject_N + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_N = self + +delI = __del__I +delJ = __del__J +delK = __del__K +delL = __del__L +delM = __del__M +delN = __del__N + + +class DummyClass(): + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + +class DummyClassDel(): + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyClassDel)") + if verbose: + print str(self)+" finalized (DummyClassDel)" + + +class DummyClassNew(object): + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + +class DummyClassDelNew(object): + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyClassDelNew)") + if verbose: + print str(self)+" finalized (DummyClassDelNew)" + +class DummyFileClassNew(file): + + def __init__(self, name): + self.name0 = name + + def __str__(self): + return self.name0 + + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyFileClassNew)") + if verbose: + print str(self)+" finalized (DummyFileClassNew)" + + +def __del__class(self): + finalizeMsgList.append(str(self)+" finalized (acquired by class)") + if verbose: + print str(self)+" finalized (acquired by class)" + +def __del__object(self): + finalizeMsgList.append(str(self)+" finalized (acquired by object)") + if verbose: + print str(self)+" finalized (acquired by object)" + +def __del__object0(): + finalizeMsgList.append("_ finalized (acquired by object)") + if verbose: + print "_ finalized (acquired by object)" + +delClass = __del__class +delObject = __del__object +delObject0 = __del__object0 + +class TestFinalizers(unittest.TestCase): + def test_finalizer_builtin_oldStyleClass(self): + A = DummyClassDel("A") + A = None + runGCIfJython() + assert("A finalized (DummyClassDel)" in finalizeMsgList) + + def test_classAcquiresFinalizer_beforeInstanciation_oldStyleClass(self): + DummyClass.__del__ = delClass + B = DummyClass("B") + B = None + runGCIfJython() + assert("B finalized (acquired by class)" in finalizeMsgList) + del DummyClass.__del__ + + def test_classAcquiresFinalizer_afterInstanciation_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer call + C = DummyClass("C") + DummyClass.__del__ = delClass + if platform.system() == "Java": + FinalizeTrigger.ensureFinalizer(C) + C = None + runGCIfJython() + assert("C finalized (acquired by class)" in finalizeMsgList) + del DummyClass.__del__ + + def test_instanceAcquiresFinalizer_bound_oldStyleClass(self): + D = DummyClassDel("D") + dl = types.MethodType(delObject, D.name) + D.__del__ = dl + D = None + runGCIfJython() + assert("D finalized (DummyClassDel)" not in finalizeMsgList) + assert("D finalized (acquired by object)" in finalizeMsgList) + + def test_finalizer_builtin_newStyleClass(self): + E = DummyClassDelNew("E") + E = None + runGCIfJython() + assert("E finalized (DummyClassDelNew)" in finalizeMsgList) + + def test_classAcquiresFinalizer_beforeInstanciation_newStyleClass(self): + DummyClassNew.__del__ = delClass + F = DummyClassNew("F") + F = None + runGCIfJython() + assert("F finalized (acquired by class)" in finalizeMsgList) + del DummyClassNew.__del__ + + def test_classAcquiresFinalizer_afterInstanciation_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer call + G = DummyClassNew("G") + DummyClassNew.__del__ = delClass + if platform.system() == "Java": + FinalizeTrigger.ensureFinalizer(G) + G = None + runGCIfJython() + assert("G finalized (acquired by class)" in finalizeMsgList) + del DummyClassNew.__del__ + + def test_instanceAcquiresFinalizer_bound_newStyleClass(self): + """ + It seems, CPython prohibits new style instances from acquiring a finalizer. + """ + H = DummyClassDelNew("H") + H.__del__ = types.MethodType(delObject, H.name) + H = None + runGCIfJython() + assert("H finalized (DummyClassDelNew)" in finalizeMsgList) + assert("H finalized (acquired by object)" not in finalizeMsgList) + + def test_instanceAcquiresFinalizer_bound_newStyleClass2(self): + """ + It seems, CPython prohibits new style instances from acquiring a finalizer. + If one calls the instance-acquired __del__ manually, it works, but the gc + will still call the old one. + """ + H = DummyClassDelNew("H2") + H.__del__ = types.MethodType(delObject, H.name) + H.__del__() + H = None + runGCIfJython() + assert("H2 finalized (DummyClassDelNew)" in finalizeMsgList) + assert("H2 finalized (acquired by object)" in finalizeMsgList) + + def test_objectResurrection_oldStyleClass(self): + ResurrectableDummyClass.__del__ = delI + I = ResurrectableDummyClass("I") + I = None + runGCIfJython() + assert("I finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_I) == "I") + + def test_objectDoubleResurrection_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClass.__del__ = delJ + J = ResurrectableDummyClass("J") + J = None + + runGCIfJython() + assert("J finalized (ResurrectableDummyClass)" in finalizeMsgList) + global resurrectedObject_J + assert(str(resurrectedObject_J) == "J") + J = resurrectedObject_J + resurrectedObject_J = None + assert(resurrectedObject_J is None) + if platform.system() == "Java": + #For Jython one can restore the finalizer manually. + #This is offered as an easy fix if the CPython behavior + #in this test should be needed for some reason. + FinalizeTrigger.ensureFinalizer(J) + J = None + + runGCIfJython() + assert(str(resurrectedObject_J) == "J") + resurrectedObject_J.doResurrection = False + if platform.system() == "Java": + #again... + FinalizeTrigger.ensureFinalizer(resurrectedObject_J) + resurrectedObject_J = None + + runGCIfJython() + assert(resurrectedObject_J is None) + + + def test_objectDoubleResurrectionAndFinalize_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClass.__del__ = delK + K = ResurrectableDummyClass("K") + K = None + + runGCIfJython() + assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) + finalizeMsgList.remove("K finalized (ResurrectableDummyClass)") + assert("K finalized (ResurrectableDummyClass)" not in finalizeMsgList) + global resurrectedObject_K + assert(str(resurrectedObject_K) == "K") + K = resurrectedObject_K + resurrectedObject_K = None + assert(resurrectedObject_K is None) + if platform.system() == "Java": + FinalizeTrigger.ensureFinalizer(K) + K = None + + runGCIfJython() + assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_K) == "K") + + def test_objectResurrection_newStyleClass(self): + ResurrectableDummyClassNew.__del__ = delL + L = ResurrectableDummyClassNew("L") + L = None + runGCIfJython() + assert("L finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_L) == "L") + + def test_objectDoubleResurrection_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClassNew.__del__ = delM + M = ResurrectableDummyClassNew("M") + M = None + + runGCIfJython() + assert("M finalized (ResurrectableDummyClass)" in finalizeMsgList) + global resurrectedObject_M + assert(str(resurrectedObject_M) == "M") + M = resurrectedObject_M + resurrectedObject_M = None + assert(resurrectedObject_M is None) + if platform.system() == "Java": + FinalizeTrigger.ensureFinalizer(M) + M = None + + runGCIfJython() + assert(str(resurrectedObject_M) == "M") + + def test_objectDoubleResurrectionAndFinalize_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClassNew.__del__ = delN + N = ResurrectableDummyClassNew("N") + N = None + + runGCIfJython() + assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) + finalizeMsgList.remove("N finalized (ResurrectableDummyClass)") + assert("N finalized (ResurrectableDummyClass)" not in finalizeMsgList) + global resurrectedObject_N + assert(str(resurrectedObject_N) == "N") + N = resurrectedObject_N + resurrectedObject_N = None + assert(resurrectedObject_N is None) + if platform.system() == "Java": + FinalizeTrigger.ensureFinalizer(N) + N = None + + runGCIfJython() + assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_N) == "N") + + def test_file_overwrite_del(self): + O = DummyFileClassNew("O") + O = None + + runGCIfJython() + assert("O finalized (DummyFileClassNew)" in finalizeMsgList) + + +if __name__ == '__main__': + unittest.main() + diff --git a/src/org/python/antlr/ast/AssertDerived.java b/src/org/python/antlr/ast/AssertDerived.java --- a/src/org/python/antlr/ast/AssertDerived.java +++ b/src/org/python/antlr/ast/AssertDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AssertDerived extends Assert implements Slotted { +public class AssertDerived extends Assert implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/AssignDerived.java b/src/org/python/antlr/ast/AssignDerived.java --- a/src/org/python/antlr/ast/AssignDerived.java +++ b/src/org/python/antlr/ast/AssignDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AssignDerived extends Assign implements Slotted { +public class AssignDerived extends Assign implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/AttributeDerived.java b/src/org/python/antlr/ast/AttributeDerived.java --- a/src/org/python/antlr/ast/AttributeDerived.java +++ b/src/org/python/antlr/ast/AttributeDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AttributeDerived extends Attribute implements Slotted { +public class AttributeDerived extends Attribute implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/AugAssignDerived.java b/src/org/python/antlr/ast/AugAssignDerived.java --- a/src/org/python/antlr/ast/AugAssignDerived.java +++ b/src/org/python/antlr/ast/AugAssignDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AugAssignDerived extends AugAssign implements Slotted { +public class AugAssignDerived extends AugAssign implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/BinOpDerived.java b/src/org/python/antlr/ast/BinOpDerived.java --- a/src/org/python/antlr/ast/BinOpDerived.java +++ b/src/org/python/antlr/ast/BinOpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BinOpDerived extends BinOp implements Slotted { +public class BinOpDerived extends BinOp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/BoolOpDerived.java b/src/org/python/antlr/ast/BoolOpDerived.java --- a/src/org/python/antlr/ast/BoolOpDerived.java +++ b/src/org/python/antlr/ast/BoolOpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BoolOpDerived extends BoolOp implements Slotted { +public class BoolOpDerived extends BoolOp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/BreakDerived.java b/src/org/python/antlr/ast/BreakDerived.java --- a/src/org/python/antlr/ast/BreakDerived.java +++ b/src/org/python/antlr/ast/BreakDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BreakDerived extends Break implements Slotted { +public class BreakDerived extends Break implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/CallDerived.java b/src/org/python/antlr/ast/CallDerived.java --- a/src/org/python/antlr/ast/CallDerived.java +++ b/src/org/python/antlr/ast/CallDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class CallDerived extends Call implements Slotted { +public class CallDerived extends Call implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ClassDefDerived.java b/src/org/python/antlr/ast/ClassDefDerived.java --- a/src/org/python/antlr/ast/ClassDefDerived.java +++ b/src/org/python/antlr/ast/ClassDefDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ClassDefDerived extends ClassDef implements Slotted { +public class ClassDefDerived extends ClassDef implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/CompareDerived.java b/src/org/python/antlr/ast/CompareDerived.java --- a/src/org/python/antlr/ast/CompareDerived.java +++ b/src/org/python/antlr/ast/CompareDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class CompareDerived extends Compare implements Slotted { +public class CompareDerived extends Compare implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ContinueDerived.java b/src/org/python/antlr/ast/ContinueDerived.java --- a/src/org/python/antlr/ast/ContinueDerived.java +++ b/src/org/python/antlr/ast/ContinueDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ContinueDerived extends Continue implements Slotted { +public class ContinueDerived extends Continue implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/DeleteDerived.java b/src/org/python/antlr/ast/DeleteDerived.java --- a/src/org/python/antlr/ast/DeleteDerived.java +++ b/src/org/python/antlr/ast/DeleteDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class DeleteDerived extends Delete implements Slotted { +public class DeleteDerived extends Delete implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/DictDerived.java b/src/org/python/antlr/ast/DictDerived.java --- a/src/org/python/antlr/ast/DictDerived.java +++ b/src/org/python/antlr/ast/DictDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class DictDerived extends Dict implements Slotted { +public class DictDerived extends Dict implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/EllipsisDerived.java b/src/org/python/antlr/ast/EllipsisDerived.java --- a/src/org/python/antlr/ast/EllipsisDerived.java +++ b/src/org/python/antlr/ast/EllipsisDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class EllipsisDerived extends Ellipsis implements Slotted { +public class EllipsisDerived extends Ellipsis implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExceptHandlerDerived.java b/src/org/python/antlr/ast/ExceptHandlerDerived.java --- a/src/org/python/antlr/ast/ExceptHandlerDerived.java +++ b/src/org/python/antlr/ast/ExceptHandlerDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExceptHandlerDerived extends ExceptHandler implements Slotted { +public class ExceptHandlerDerived extends ExceptHandler implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExecDerived.java b/src/org/python/antlr/ast/ExecDerived.java --- a/src/org/python/antlr/ast/ExecDerived.java +++ b/src/org/python/antlr/ast/ExecDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExecDerived extends Exec implements Slotted { +public class ExecDerived extends Exec implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExprDerived.java b/src/org/python/antlr/ast/ExprDerived.java --- a/src/org/python/antlr/ast/ExprDerived.java +++ b/src/org/python/antlr/ast/ExprDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExprDerived extends Expr implements Slotted { +public class ExprDerived extends Expr implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExpressionDerived.java b/src/org/python/antlr/ast/ExpressionDerived.java --- a/src/org/python/antlr/ast/ExpressionDerived.java +++ b/src/org/python/antlr/ast/ExpressionDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExpressionDerived extends Expression implements Slotted { +public class ExpressionDerived extends Expression implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExtSliceDerived.java b/src/org/python/antlr/ast/ExtSliceDerived.java --- a/src/org/python/antlr/ast/ExtSliceDerived.java +++ b/src/org/python/antlr/ast/ExtSliceDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExtSliceDerived extends ExtSlice implements Slotted { +public class ExtSliceDerived extends ExtSlice implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ForDerived.java b/src/org/python/antlr/ast/ForDerived.java --- a/src/org/python/antlr/ast/ForDerived.java +++ b/src/org/python/antlr/ast/ForDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ForDerived extends For implements Slotted { +public class ForDerived extends For implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/FunctionDefDerived.java b/src/org/python/antlr/ast/FunctionDefDerived.java --- a/src/org/python/antlr/ast/FunctionDefDerived.java +++ b/src/org/python/antlr/ast/FunctionDefDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class FunctionDefDerived extends FunctionDef implements Slotted { +public class FunctionDefDerived extends FunctionDef implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/GeneratorExpDerived.java b/src/org/python/antlr/ast/GeneratorExpDerived.java --- a/src/org/python/antlr/ast/GeneratorExpDerived.java +++ b/src/org/python/antlr/ast/GeneratorExpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class GeneratorExpDerived extends GeneratorExp implements Slotted { +public class GeneratorExpDerived extends GeneratorExp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/GlobalDerived.java b/src/org/python/antlr/ast/GlobalDerived.java --- a/src/org/python/antlr/ast/GlobalDerived.java +++ b/src/org/python/antlr/ast/GlobalDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class GlobalDerived extends Global implements Slotted { +public class GlobalDerived extends Global implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/IfDerived.java b/src/org/python/antlr/ast/IfDerived.java --- a/src/org/python/antlr/ast/IfDerived.java +++ b/src/org/python/antlr/ast/IfDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IfDerived extends If implements Slotted { +public class IfDerived extends If implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/IfExpDerived.java b/src/org/python/antlr/ast/IfExpDerived.java --- a/src/org/python/antlr/ast/IfExpDerived.java +++ b/src/org/python/antlr/ast/IfExpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IfExpDerived extends IfExp implements Slotted { +public class IfExpDerived extends IfExp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ImportDerived.java b/src/org/python/antlr/ast/ImportDerived.java --- a/src/org/python/antlr/ast/ImportDerived.java +++ b/src/org/python/antlr/ast/ImportDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ImportDerived extends Import implements Slotted { +public class ImportDerived extends Import implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ImportFromDerived.java b/src/org/python/antlr/ast/ImportFromDerived.java --- a/src/org/python/antlr/ast/ImportFromDerived.java +++ b/src/org/python/antlr/ast/ImportFromDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ImportFromDerived extends ImportFrom implements Slotted { +public class ImportFromDerived extends ImportFrom implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/IndexDerived.java b/src/org/python/antlr/ast/IndexDerived.java --- a/src/org/python/antlr/ast/IndexDerived.java +++ b/src/org/python/antlr/ast/IndexDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IndexDerived extends Index implements Slotted { +public class IndexDerived extends Index implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/InteractiveDerived.java b/src/org/python/antlr/ast/InteractiveDerived.java --- a/src/org/python/antlr/ast/InteractiveDerived.java +++ b/src/org/python/antlr/ast/InteractiveDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class InteractiveDerived extends Interactive implements Slotted { +public class InteractiveDerived extends Interactive implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/LambdaDerived.java b/src/org/python/antlr/ast/LambdaDerived.java --- a/src/org/python/antlr/ast/LambdaDerived.java +++ b/src/org/python/antlr/ast/LambdaDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LambdaDerived extends Lambda implements Slotted { +public class LambdaDerived extends Lambda implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ListCompDerived.java b/src/org/python/antlr/ast/ListCompDerived.java --- a/src/org/python/antlr/ast/ListCompDerived.java +++ b/src/org/python/antlr/ast/ListCompDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ListCompDerived extends ListComp implements Slotted { +public class ListCompDerived extends ListComp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ListDerived.java b/src/org/python/antlr/ast/ListDerived.java --- a/src/org/python/antlr/ast/ListDerived.java +++ b/src/org/python/antlr/ast/ListDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ListDerived extends List implements Slotted { +public class ListDerived extends List implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ModuleDerived.java b/src/org/python/antlr/ast/ModuleDerived.java --- a/src/org/python/antlr/ast/ModuleDerived.java +++ b/src/org/python/antlr/ast/ModuleDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ModuleDerived extends Module implements Slotted { +public class ModuleDerived extends Module implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/NameDerived.java b/src/org/python/antlr/ast/NameDerived.java --- a/src/org/python/antlr/ast/NameDerived.java +++ b/src/org/python/antlr/ast/NameDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NameDerived extends Name implements Slotted { +public class NameDerived extends Name implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/NumDerived.java b/src/org/python/antlr/ast/NumDerived.java --- a/src/org/python/antlr/ast/NumDerived.java +++ b/src/org/python/antlr/ast/NumDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NumDerived extends Num implements Slotted { +public class NumDerived extends Num implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/PassDerived.java b/src/org/python/antlr/ast/PassDerived.java --- a/src/org/python/antlr/ast/PassDerived.java +++ b/src/org/python/antlr/ast/PassDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PassDerived extends Pass implements Slotted { +public class PassDerived extends Pass implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/PrintDerived.java b/src/org/python/antlr/ast/PrintDerived.java --- a/src/org/python/antlr/ast/PrintDerived.java +++ b/src/org/python/antlr/ast/PrintDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PrintDerived extends Print implements Slotted { +public class PrintDerived extends Print implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/RaiseDerived.java b/src/org/python/antlr/ast/RaiseDerived.java --- a/src/org/python/antlr/ast/RaiseDerived.java +++ b/src/org/python/antlr/ast/RaiseDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class RaiseDerived extends Raise implements Slotted { +public class RaiseDerived extends Raise implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ReprDerived.java b/src/org/python/antlr/ast/ReprDerived.java --- a/src/org/python/antlr/ast/ReprDerived.java +++ b/src/org/python/antlr/ast/ReprDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ReprDerived extends Repr implements Slotted { +public class ReprDerived extends Repr implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ReturnDerived.java b/src/org/python/antlr/ast/ReturnDerived.java --- a/src/org/python/antlr/ast/ReturnDerived.java +++ b/src/org/python/antlr/ast/ReturnDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ReturnDerived extends Return implements Slotted { +public class ReturnDerived extends Return implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/SliceDerived.java b/src/org/python/antlr/ast/SliceDerived.java --- a/src/org/python/antlr/ast/SliceDerived.java +++ b/src/org/python/antlr/ast/SliceDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class SliceDerived extends Slice implements Slotted { +public class SliceDerived extends Slice implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/StrDerived.java b/src/org/python/antlr/ast/StrDerived.java --- a/src/org/python/antlr/ast/StrDerived.java +++ b/src/org/python/antlr/ast/StrDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class StrDerived extends Str implements Slotted { +public class StrDerived extends Str implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/SubscriptDerived.java b/src/org/python/antlr/ast/SubscriptDerived.java --- a/src/org/python/antlr/ast/SubscriptDerived.java +++ b/src/org/python/antlr/ast/SubscriptDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class SubscriptDerived extends Subscript implements Slotted { +public class SubscriptDerived extends Subscript implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/SuiteDerived.java b/src/org/python/antlr/ast/SuiteDerived.java --- a/src/org/python/antlr/ast/SuiteDerived.java +++ b/src/org/python/antlr/ast/SuiteDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class SuiteDerived extends Suite implements Slotted { +public class SuiteDerived extends Suite implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/TryExceptDerived.java b/src/org/python/antlr/ast/TryExceptDerived.java --- a/src/org/python/antlr/ast/TryExceptDerived.java +++ b/src/org/python/antlr/ast/TryExceptDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class TryExceptDerived extends TryExcept implements Slotted { +public class TryExceptDerived extends TryExcept implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/TryFinallyDerived.java b/src/org/python/antlr/ast/TryFinallyDerived.java --- a/src/org/python/antlr/ast/TryFinallyDerived.java +++ b/src/org/python/antlr/ast/TryFinallyDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class TryFinallyDerived extends TryFinally implements Slotted { +public class TryFinallyDerived extends TryFinally implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/TupleDerived.java b/src/org/python/antlr/ast/TupleDerived.java --- a/src/org/python/antlr/ast/TupleDerived.java +++ b/src/org/python/antlr/ast/TupleDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class TupleDerived extends Tuple implements Slotted { +public class TupleDerived extends Tuple implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/UnaryOpDerived.java b/src/org/python/antlr/ast/UnaryOpDerived.java --- a/src/org/python/antlr/ast/UnaryOpDerived.java +++ b/src/org/python/antlr/ast/UnaryOpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class UnaryOpDerived extends UnaryOp implements Slotted { +public class UnaryOpDerived extends UnaryOp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/WhileDerived.java b/src/org/python/antlr/ast/WhileDerived.java --- a/src/org/python/antlr/ast/WhileDerived.java +++ b/src/org/python/antlr/ast/WhileDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class WhileDerived extends While implements Slotted { +public class WhileDerived extends While implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/WithDerived.java b/src/org/python/antlr/ast/WithDerived.java --- a/src/org/python/antlr/ast/WithDerived.java +++ b/src/org/python/antlr/ast/WithDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class WithDerived extends With implements Slotted { +public class WithDerived extends With implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/YieldDerived.java b/src/org/python/antlr/ast/YieldDerived.java --- a/src/org/python/antlr/ast/YieldDerived.java +++ b/src/org/python/antlr/ast/YieldDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class YieldDerived extends Yield implements Slotted { +public class YieldDerived extends Yield implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/aliasDerived.java b/src/org/python/antlr/ast/aliasDerived.java --- a/src/org/python/antlr/ast/aliasDerived.java +++ b/src/org/python/antlr/ast/aliasDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class aliasDerived extends alias implements Slotted { +public class aliasDerived extends alias implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/argumentsDerived.java b/src/org/python/antlr/ast/argumentsDerived.java --- a/src/org/python/antlr/ast/argumentsDerived.java +++ b/src/org/python/antlr/ast/argumentsDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class argumentsDerived extends arguments implements Slotted { +public class argumentsDerived extends arguments implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/comprehensionDerived.java b/src/org/python/antlr/ast/comprehensionDerived.java --- a/src/org/python/antlr/ast/comprehensionDerived.java +++ b/src/org/python/antlr/ast/comprehensionDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class comprehensionDerived extends comprehension implements Slotted { +public class comprehensionDerived extends comprehension implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/keywordDerived.java b/src/org/python/antlr/ast/keywordDerived.java --- a/src/org/python/antlr/ast/keywordDerived.java +++ b/src/org/python/antlr/ast/keywordDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class keywordDerived extends keyword implements Slotted { +public class keywordDerived extends keyword implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/AddDerived.java b/src/org/python/antlr/op/AddDerived.java --- a/src/org/python/antlr/op/AddDerived.java +++ b/src/org/python/antlr/op/AddDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AddDerived extends Add implements Slotted { +public class AddDerived extends Add implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/AndDerived.java b/src/org/python/antlr/op/AndDerived.java --- a/src/org/python/antlr/op/AndDerived.java +++ b/src/org/python/antlr/op/AndDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AndDerived extends And implements Slotted { +public class AndDerived extends And implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/AugLoadDerived.java b/src/org/python/antlr/op/AugLoadDerived.java --- a/src/org/python/antlr/op/AugLoadDerived.java +++ b/src/org/python/antlr/op/AugLoadDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AugLoadDerived extends AugLoad implements Slotted { +public class AugLoadDerived extends AugLoad implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/AugStoreDerived.java b/src/org/python/antlr/op/AugStoreDerived.java --- a/src/org/python/antlr/op/AugStoreDerived.java +++ b/src/org/python/antlr/op/AugStoreDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AugStoreDerived extends AugStore implements Slotted { +public class AugStoreDerived extends AugStore implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/BitAndDerived.java b/src/org/python/antlr/op/BitAndDerived.java --- a/src/org/python/antlr/op/BitAndDerived.java +++ b/src/org/python/antlr/op/BitAndDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BitAndDerived extends BitAnd implements Slotted { +public class BitAndDerived extends BitAnd implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/BitOrDerived.java b/src/org/python/antlr/op/BitOrDerived.java --- a/src/org/python/antlr/op/BitOrDerived.java +++ b/src/org/python/antlr/op/BitOrDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BitOrDerived extends BitOr implements Slotted { +public class BitOrDerived extends BitOr implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/BitXorDerived.java b/src/org/python/antlr/op/BitXorDerived.java --- a/src/org/python/antlr/op/BitXorDerived.java +++ b/src/org/python/antlr/op/BitXorDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BitXorDerived extends BitXor implements Slotted { +public class BitXorDerived extends BitXor implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/DelDerived.java b/src/org/python/antlr/op/DelDerived.java --- a/src/org/python/antlr/op/DelDerived.java +++ b/src/org/python/antlr/op/DelDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class DelDerived extends Del implements Slotted { +public class DelDerived extends Del implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/DivDerived.java b/src/org/python/antlr/op/DivDerived.java --- a/src/org/python/antlr/op/DivDerived.java +++ b/src/org/python/antlr/op/DivDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class DivDerived extends Div implements Slotted { +public class DivDerived extends Div implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/EqDerived.java b/src/org/python/antlr/op/EqDerived.java --- a/src/org/python/antlr/op/EqDerived.java +++ b/src/org/python/antlr/op/EqDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class EqDerived extends Eq implements Slotted { +public class EqDerived extends Eq implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/FloorDivDerived.java b/src/org/python/antlr/op/FloorDivDerived.java --- a/src/org/python/antlr/op/FloorDivDerived.java +++ b/src/org/python/antlr/op/FloorDivDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class FloorDivDerived extends FloorDiv implements Slotted { +public class FloorDivDerived extends FloorDiv implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/GtDerived.java b/src/org/python/antlr/op/GtDerived.java --- a/src/org/python/antlr/op/GtDerived.java +++ b/src/org/python/antlr/op/GtDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class GtDerived extends Gt implements Slotted { +public class GtDerived extends Gt implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/GtEDerived.java b/src/org/python/antlr/op/GtEDerived.java --- a/src/org/python/antlr/op/GtEDerived.java +++ b/src/org/python/antlr/op/GtEDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class GtEDerived extends GtE implements Slotted { +public class GtEDerived extends GtE implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/InDerived.java b/src/org/python/antlr/op/InDerived.java --- a/src/org/python/antlr/op/InDerived.java +++ b/src/org/python/antlr/op/InDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class InDerived extends In implements Slotted { +public class InDerived extends In implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/InvertDerived.java b/src/org/python/antlr/op/InvertDerived.java --- a/src/org/python/antlr/op/InvertDerived.java +++ b/src/org/python/antlr/op/InvertDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class InvertDerived extends Invert implements Slotted { +public class InvertDerived extends Invert implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/IsDerived.java b/src/org/python/antlr/op/IsDerived.java --- a/src/org/python/antlr/op/IsDerived.java +++ b/src/org/python/antlr/op/IsDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IsDerived extends Is implements Slotted { +public class IsDerived extends Is implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/IsNotDerived.java b/src/org/python/antlr/op/IsNotDerived.java --- a/src/org/python/antlr/op/IsNotDerived.java +++ b/src/org/python/antlr/op/IsNotDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IsNotDerived extends IsNot implements Slotted { +public class IsNotDerived extends IsNot implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/LShiftDerived.java b/src/org/python/antlr/op/LShiftDerived.java --- a/src/org/python/antlr/op/LShiftDerived.java +++ b/src/org/python/antlr/op/LShiftDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LShiftDerived extends LShift implements Slotted { +public class LShiftDerived extends LShift implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/LoadDerived.java b/src/org/python/antlr/op/LoadDerived.java --- a/src/org/python/antlr/op/LoadDerived.java +++ b/src/org/python/antlr/op/LoadDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LoadDerived extends Load implements Slotted { +public class LoadDerived extends Load implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/LtDerived.java b/src/org/python/antlr/op/LtDerived.java --- a/src/org/python/antlr/op/LtDerived.java +++ b/src/org/python/antlr/op/LtDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LtDerived extends Lt implements Slotted { +public class LtDerived extends Lt implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/LtEDerived.java b/src/org/python/antlr/op/LtEDerived.java --- a/src/org/python/antlr/op/LtEDerived.java +++ b/src/org/python/antlr/op/LtEDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LtEDerived extends LtE implements Slotted { +public class LtEDerived extends LtE implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/ModDerived.java b/src/org/python/antlr/op/ModDerived.java --- a/src/org/python/antlr/op/ModDerived.java +++ b/src/org/python/antlr/op/ModDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ModDerived extends Mod implements Slotted { +public class ModDerived extends Mod implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/MultDerived.java b/src/org/python/antlr/op/MultDerived.java --- a/src/org/python/antlr/op/MultDerived.java +++ b/src/org/python/antlr/op/MultDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class MultDerived extends Mult implements Slotted { +public class MultDerived extends Mult implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/NotDerived.java b/src/org/python/antlr/op/NotDerived.java --- a/src/org/python/antlr/op/NotDerived.java +++ b/src/org/python/antlr/op/NotDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NotDerived extends Not implements Slotted { +public class NotDerived extends Not implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/NotEqDerived.java b/src/org/python/antlr/op/NotEqDerived.java --- a/src/org/python/antlr/op/NotEqDerived.java +++ b/src/org/python/antlr/op/NotEqDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NotEqDerived extends NotEq implements Slotted { +public class NotEqDerived extends NotEq implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/NotInDerived.java b/src/org/python/antlr/op/NotInDerived.java --- a/src/org/python/antlr/op/NotInDerived.java +++ b/src/org/python/antlr/op/NotInDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NotInDerived extends NotIn implements Slotted { +public class NotInDerived extends NotIn implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/OrDerived.java b/src/org/python/antlr/op/OrDerived.java --- a/src/org/python/antlr/op/OrDerived.java +++ b/src/org/python/antlr/op/OrDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class OrDerived extends Or implements Slotted { +public class OrDerived extends Or implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/ParamDerived.java b/src/org/python/antlr/op/ParamDerived.java --- a/src/org/python/antlr/op/ParamDerived.java +++ b/src/org/python/antlr/op/ParamDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ParamDerived extends Param implements Slotted { +public class ParamDerived extends Param implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/PowDerived.java b/src/org/python/antlr/op/PowDerived.java --- a/src/org/python/antlr/op/PowDerived.java +++ b/src/org/python/antlr/op/PowDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PowDerived extends Pow implements Slotted { +public class PowDerived extends Pow implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/RShiftDerived.java b/src/org/python/antlr/op/RShiftDerived.java --- a/src/org/python/antlr/op/RShiftDerived.java +++ b/src/org/python/antlr/op/RShiftDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class RShiftDerived extends RShift implements Slotted { +public class RShiftDerived extends RShift implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/StoreDerived.java b/src/org/python/antlr/op/StoreDerived.java --- a/src/org/python/antlr/op/StoreDerived.java +++ b/src/org/python/antlr/op/StoreDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class StoreDerived extends Store implements Slotted { +public class StoreDerived extends Store implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/SubDerived.java b/src/org/python/antlr/op/SubDerived.java --- a/src/org/python/antlr/op/SubDerived.java +++ b/src/org/python/antlr/op/SubDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class SubDerived extends Sub implements Slotted { +public class SubDerived extends Sub implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/UAddDerived.java b/src/org/python/antlr/op/UAddDerived.java --- a/src/org/python/antlr/op/UAddDerived.java +++ b/src/org/python/antlr/op/UAddDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class UAddDerived extends UAdd implements Slotted { +public class UAddDerived extends UAdd implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/USubDerived.java b/src/org/python/antlr/op/USubDerived.java --- a/src/org/python/antlr/op/USubDerived.java +++ b/src/org/python/antlr/op/USubDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class USubDerived extends USub implements Slotted { +public class USubDerived extends USub implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/ClasspathPyImporterDerived.java b/src/org/python/core/ClasspathPyImporterDerived.java --- a/src/org/python/core/ClasspathPyImporterDerived.java +++ b/src/org/python/core/ClasspathPyImporterDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ClasspathPyImporterDerived extends ClasspathPyImporter implements Slotted { +public class ClasspathPyImporterDerived extends ClasspathPyImporter implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,9 +19,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public ClasspathPyImporterDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -978,6 +997,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyArrayDerived.java b/src/org/python/core/PyArrayDerived.java --- a/src/org/python/core/PyArrayDerived.java +++ b/src/org/python/core/PyArrayDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyArrayDerived extends PyArray implements Slotted { +public class PyArrayDerived extends PyArray implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyBaseExceptionDerived.java b/src/org/python/core/PyBaseExceptionDerived.java --- a/src/org/python/core/PyBaseExceptionDerived.java +++ b/src/org/python/core/PyBaseExceptionDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyBaseExceptionDerived extends PyBaseException implements Slotted { +public class PyBaseExceptionDerived extends PyBaseException implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,9 +19,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyBaseExceptionDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -978,6 +997,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyByteArrayDerived.java b/src/org/python/core/PyByteArrayDerived.java --- a/src/org/python/core/PyByteArrayDerived.java +++ b/src/org/python/core/PyByteArrayDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyByteArrayDerived extends PyByteArray implements Slotted { +public class PyByteArrayDerived extends PyByteArray implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyClass.java b/src/org/python/core/PyClass.java --- a/src/org/python/core/PyClass.java +++ b/src/org/python/core/PyClass.java @@ -3,6 +3,7 @@ import org.python.expose.ExposedNew; import org.python.expose.ExposedType; +import org.python.core.finalization.FinalizeTrigger; /** * The classic Python class. @@ -185,12 +186,16 @@ @Override public PyObject __call__(PyObject[] args, String[] keywords) { PyInstance inst; - if (__del__ == null) { - inst = new PyInstance(this); - } else { - // the class defined a __del__ method - inst = new PyFinalizableInstance(this); + inst = new PyInstance(this); + if (__del__ != null) { + inst.finalizeTrigger = FinalizeTrigger.makeTrigger(inst); } +// if (__del__ == null) { +// inst = new PyInstance(this); +// } else { +// // the class defined a __del__ method +// inst = new PyFinalizableInstance(this); +// } inst.__init__(args, keywords); return inst; } diff --git a/src/org/python/core/PyClassMethodDerived.java b/src/org/python/core/PyClassMethodDerived.java --- a/src/org/python/core/PyClassMethodDerived.java +++ b/src/org/python/core/PyClassMethodDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyClassMethodDerived extends PyClassMethod implements Slotted { +public class PyClassMethodDerived extends PyClassMethod implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyComplexDerived.java b/src/org/python/core/PyComplexDerived.java --- a/src/org/python/core/PyComplexDerived.java +++ b/src/org/python/core/PyComplexDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyComplexDerived extends PyComplex implements Slotted { +public class PyComplexDerived extends PyComplex implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,real,imaginary); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyDictionaryDerived.java b/src/org/python/core/PyDictionaryDerived.java --- a/src/org/python/core/PyDictionaryDerived.java +++ b/src/org/python/core/PyDictionaryDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyDictionaryDerived extends PyDictionary implements Slotted { +public class PyDictionaryDerived extends PyDictionary implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyEnumerateDerived.java b/src/org/python/core/PyEnumerateDerived.java --- a/src/org/python/core/PyEnumerateDerived.java +++ b/src/org/python/core/PyEnumerateDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyEnumerateDerived extends PyEnumerate implements Slotted { +public class PyEnumerateDerived extends PyEnumerate implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,seq,start); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyFile.java b/src/org/python/core/PyFile.java --- a/src/org/python/core/PyFile.java +++ b/src/org/python/core/PyFile.java @@ -8,6 +8,8 @@ import java.io.OutputStream; import java.util.concurrent.Callable; +import org.python.core.finalization.FinalizableBuiltin; +import org.python.core.finalization.FinalizeTrigger; import org.python.core.io.BinaryIOWrapper; import org.python.core.io.BufferedIOBase; import org.python.core.io.BufferedRandom; @@ -33,7 +35,7 @@ * The Python file type. Wraps an {@link TextIOBase} object. */ @ExposedType(name = "file", doc = BuiltinDocs.file_doc) -public class PyFile extends PyObject { +public class PyFile extends PyObject implements FinalizableBuiltin { public static final PyType TYPE = PyType.fromClass(PyFile.class); @@ -80,21 +82,26 @@ /** The file's closer object; ensures the file is closed at * shutdown */ private Closer closer; + + public FinalizeTrigger finalizeTrigger; - public PyFile() {} + public PyFile() {finalizeTrigger = FinalizeTrigger.makeTrigger(this);} public PyFile(PyType subType) { super(subType); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } public PyFile(RawIOBase raw, String name, String mode, int bufsize) { parseMode(mode); file___init__(raw, name, mode, bufsize); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } public PyFile(InputStream istream, String name, String mode, int bufsize, boolean closefd) { parseMode(mode); file___init__(new StreamIO(istream, closefd), name, mode, bufsize); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } /** @@ -126,6 +133,7 @@ public PyFile(OutputStream ostream, String name, String mode, int bufsize, boolean closefd) { parseMode(mode); file___init__(new StreamIO(ostream, closefd), name, mode, bufsize); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } /** @@ -153,6 +161,7 @@ public PyFile(String name, String mode, int bufsize) { file___init__(new FileIO(name, parseMode(mode)), name, mode, bufsize); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } @ExposedNew @@ -674,8 +683,7 @@ } @Override - protected void finalize() throws Throwable { - super.finalize(); + public void __del__Builtin() { if (closer != null) { closer.close(); } diff --git a/src/org/python/core/PyFileDerived.java b/src/org/python/core/PyFileDerived.java --- a/src/org/python/core/PyFileDerived.java +++ b/src/org/python/core/PyFileDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyFileDerived extends PyFile implements Slotted { +public class PyFileDerived extends PyFile implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyFinalizableInstance.java b/src/org/python/core/PyFinalizableInstance.java deleted file mode 100644 --- a/src/org/python/core/PyFinalizableInstance.java +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Corporation for National Research Initiatives -// These are just like normal instances, except that their classes included -// a definition for __del__(), i.e. Python's finalizer. These two instance -// types have to be separated due to Java performance issues. - -package org.python.core; - - -/** - * A python class instance with __del__ defined. - *

- * This is a special class due to performance. Defining - * finalize() on a class, makes the class a lot slower. - */ -public class PyFinalizableInstance extends PyInstance { - - public PyFinalizableInstance(PyClass iclass) { - super(iclass); - } - - // __del__ method is invoked upon object finalization. - @Override - protected void finalize() { - try { - instclass.__del__.__call__(this); - } catch (PyException exc) { - // Try to get the right method description. - PyObject method = instclass.__del__; - try { - method = __findattr__("__del__"); - } catch (PyException e) { - // nothing we can do - } - Py.writeUnraisable(exc, method); - } - } -} diff --git a/src/org/python/core/PyFloatDerived.java b/src/org/python/core/PyFloatDerived.java --- a/src/org/python/core/PyFloatDerived.java +++ b/src/org/python/core/PyFloatDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyFloatDerived extends PyFloat implements Slotted { +public class PyFloatDerived extends PyFloat implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,v); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyFrozenSetDerived.java b/src/org/python/core/PyFrozenSetDerived.java --- a/src/org/python/core/PyFrozenSetDerived.java +++ b/src/org/python/core/PyFrozenSetDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyFrozenSetDerived extends PyFrozenSet implements Slotted { +public class PyFrozenSetDerived extends PyFrozenSet implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,data); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyGenerator.java b/src/org/python/core/PyGenerator.java --- a/src/org/python/core/PyGenerator.java +++ b/src/org/python/core/PyGenerator.java @@ -1,12 +1,14 @@ /* Copyright (c) Jython Developers */ package org.python.core; +import org.python.core.finalization.FinalizableBuiltin; +import org.python.core.finalization.FinalizeTrigger; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedType; @ExposedType(name = "generator", base = PyObject.class, isBaseType = false) -public class PyGenerator extends PyIterator { +public class PyGenerator extends PyIterator implements FinalizableBuiltin { public static final PyType TYPE = PyType.fromClass(PyGenerator.class); @@ -20,6 +22,8 @@ protected boolean gi_running; private PyObject closure; + + public FinalizeTrigger finalizeTrigger; public PyGenerator(PyFrame frame, PyObject closure) { super(TYPE); @@ -28,6 +32,7 @@ gi_code = gi_frame.f_code; } this.closure = closure; + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } public PyObject send(PyObject value) { @@ -105,9 +110,9 @@ gi_frame.setGeneratorInput(ex); return next(); } - + @Override - protected void finalize() throws Throwable { + public void __del__Builtin() { if (gi_frame == null || gi_frame.f_lasti == -1) { return; } @@ -127,8 +132,6 @@ } catch (Throwable t) { // but we currently ignore any Java exception completely. perhaps we // can also output something meaningful too? - } finally { - super.finalize(); } } diff --git a/src/org/python/core/PyInstance.java b/src/org/python/core/PyInstance.java --- a/src/org/python/core/PyInstance.java +++ b/src/org/python/core/PyInstance.java @@ -6,14 +6,19 @@ import org.python.expose.ExposedType; import org.python.expose.MethodType; +import org.python.core.finalization.FinalizablePyObject; +import org.python.core.finalization.FinalizeTrigger; + /** * An instance of a classic Python class. */ @ExposedType(name = "instance", isBaseType = false) -public class PyInstance extends PyObject { +public class PyInstance extends PyObject implements FinalizablePyObject { public static final PyType TYPE = PyType.fromClass(PyInstance.class); + public FinalizeTrigger finalizeTrigger; + // xxx doc, final name public transient PyClass instclass; @@ -24,6 +29,9 @@ public PyInstance() { super(TYPE); +// if (TYPE.needsFinalizer()) { +// finalizeTrigger = FinalizeTrigger.makeTrigger(this); +// } } public PyInstance(PyClass iclass, PyObject dict) { @@ -33,10 +41,16 @@ dict = new PyStringMap(); } __dict__ = dict; +// if (TYPE.needsFinalizer()) { +// finalizeTrigger = FinalizeTrigger.makeTrigger(this); +// } } public PyInstance(PyClass iclass) { this(iclass, null); +// if (TYPE.needsFinalizer()) { +// finalizeTrigger = FinalizeTrigger.makeTrigger(this); +// } } @ExposedNew @@ -263,6 +277,9 @@ if (name == "__class__") { if (value instanceof PyClass) { instclass = (PyClass) value; + if (instclass.__del__ != null && finalizeTrigger == null) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__class__ must be set to a class"); } @@ -278,6 +295,9 @@ } else { __dict__.__setitem__(name, value); } + if (name == "__del__" && finalizeTrigger == null) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } protected void noField(String name, PyObject value) { @@ -1909,4 +1929,35 @@ return super.__ixor__(o); } + /* + public void ensureFinalizer() + { + instance_ensureFinalizer(); + } + + public void instance_ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + */ + + @Override + public void __del__() { + try { + PyObject method = __findattr__("__del__"); + if (method != null) { + method.__call__(); + } else if (instclass.__del__ != null) { + instclass.__del__.__call__(this); + } + } catch (PyException exc) { + // Try to get the right method description. + PyObject method = instclass.__del__; + try { + method = __findattr__("__del__"); + } catch (PyException e) { + // nothing we can do + } + Py.writeUnraisable(exc, method); + } + } } diff --git a/src/org/python/core/PyIntegerDerived.java b/src/org/python/core/PyIntegerDerived.java --- a/src/org/python/core/PyIntegerDerived.java +++ b/src/org/python/core/PyIntegerDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyIntegerDerived extends PyInteger implements Slotted { +public class PyIntegerDerived extends PyInteger implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,v); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyListDerived.java b/src/org/python/core/PyListDerived.java --- a/src/org/python/core/PyListDerived.java +++ b/src/org/python/core/PyListDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyListDerived extends PyList implements Slotted { +public class PyListDerived extends PyList implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyLongDerived.java b/src/org/python/core/PyLongDerived.java --- a/src/org/python/core/PyLongDerived.java +++ b/src/org/python/core/PyLongDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyLongDerived extends PyLong implements Slotted { +public class PyLongDerived extends PyLong implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,v); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyModuleDerived.java b/src/org/python/core/PyModuleDerived.java --- a/src/org/python/core/PyModuleDerived.java +++ b/src/org/python/core/PyModuleDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyModuleDerived extends PyModule implements Slotted { +public class PyModuleDerived extends PyModule implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,9 +19,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyModuleDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -978,6 +997,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyObject.java b/src/org/python/core/PyObject.java --- a/src/org/python/core/PyObject.java +++ b/src/org/python/core/PyObject.java @@ -99,6 +99,21 @@ return new_.for_type == subtype ? new PyObject() : new PyObjectDerived(subtype); } + /** + *

+ * From Jython 2.7 on, {@code PyObject}s must not have finalizers directly. + * If a finalizer, a.k.a. {@code __del__} is needed, follow the instructions in the + * documentation of {@link org.python.core.finalization.FinalizablePyObject}. + *

+ *

+ * Note that this empty finalizer implementation is optimized away by the JVM + * (See {@link http://www.javaspecialists.eu/archive/Issue170.html}). + * So {@code PyObject}s are not expensively treaded as finalizable objects by the + * GC. Its only intention is to prevent subclasses from having Java-style finalizers. + *

+ */ + protected final void finalize() throws Throwable {} + @ExposedMethod(doc = BuiltinDocs.object___init___doc) final void object___init__(PyObject[] args, String[] keywords) { } diff --git a/src/org/python/core/PyObjectDerived.java b/src/org/python/core/PyObjectDerived.java --- a/src/org/python/core/PyObjectDerived.java +++ b/src/org/python/core/PyObjectDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyObjectDerived extends PyObject implements Slotted { +public class PyObjectDerived extends PyObject implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyPropertyDerived.java b/src/org/python/core/PyPropertyDerived.java --- a/src/org/python/core/PyPropertyDerived.java +++ b/src/org/python/core/PyPropertyDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyPropertyDerived extends PyProperty implements Slotted { +public class PyPropertyDerived extends PyProperty implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PySetDerived.java b/src/org/python/core/PySetDerived.java --- a/src/org/python/core/PySetDerived.java +++ b/src/org/python/core/PySetDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PySetDerived extends PySet implements Slotted { +public class PySetDerived extends PySet implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyStringDerived.java b/src/org/python/core/PyStringDerived.java --- a/src/org/python/core/PyStringDerived.java +++ b/src/org/python/core/PyStringDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyStringDerived extends PyString implements Slotted { +public class PyStringDerived extends PyString implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,v); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PySuperDerived.java b/src/org/python/core/PySuperDerived.java --- a/src/org/python/core/PySuperDerived.java +++ b/src/org/python/core/PySuperDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PySuperDerived extends PySuper implements Slotted { +public class PySuperDerived extends PySuper implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyTupleDerived.java b/src/org/python/core/PyTupleDerived.java --- a/src/org/python/core/PyTupleDerived.java +++ b/src/org/python/core/PyTupleDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyTupleDerived extends PyTuple implements Slotted { +public class PyTupleDerived extends PyTuple implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,elements); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyType.java b/src/org/python/core/PyType.java --- a/src/org/python/core/PyType.java +++ b/src/org/python/core/PyType.java @@ -82,7 +82,7 @@ protected boolean needs_weakref; /** Whether finalization is required for this type's instances (implements __del__). */ - private boolean needs_finalizer; + protected boolean needs_finalizer; /** Whether this type's __getattribute__ is object.__getattribute__. */ private volatile boolean usesObjectGetattribute; @@ -310,7 +310,7 @@ if (wantWeak) { createWeakrefSlot(); } - needs_finalizer = lookup_mro("__del__") != null; + needs_finalizer = needsFinalizer(); } /** @@ -568,6 +568,24 @@ } /** + * Offers public read-only access to the protected field needs_finalizer. + * + * @return a boolean indicating whether the type implements __del__ + */ + public final boolean needsFinalizer() { + //It might be sluggish to assume that if a finalizer was needed + //once, this would never change. However since an expensive + //FinalizeTrigger was created anyway, it won't hurt to keep it. + //Whether there actually is a __del__ in the dict will be checked + //again when the finalizer runs. + if (needs_finalizer) return true; + else { + needs_finalizer = lookup_mro("__del__") != null; + return needs_finalizer; + } + } + + /** * Ensures that the physical layout between this type and other are compatible. * Raises a TypeError if not. */ diff --git a/src/org/python/core/PyTypeDerived.java b/src/org/python/core/PyTypeDerived.java --- a/src/org/python/core/PyTypeDerived.java +++ b/src/org/python/core/PyTypeDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyTypeDerived extends PyType implements Slotted { +public class PyTypeDerived extends PyType implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,9 +19,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyTypeDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -978,6 +997,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyUnicodeDerived.java b/src/org/python/core/PyUnicodeDerived.java --- a/src/org/python/core/PyUnicodeDerived.java +++ b/src/org/python/core/PyUnicodeDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyUnicodeDerived extends PyUnicode implements Slotted { +public class PyUnicodeDerived extends PyUnicode implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,string); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/finalization/FinalizableBuiltin.java b/src/org/python/core/finalization/FinalizableBuiltin.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizableBuiltin.java @@ -0,0 +1,18 @@ +package org.python.core.finalization; + +/** + * See documentation of {@link FinalizablePyObject}. + */ + +public interface FinalizableBuiltin extends HasFinalizeTrigger { + /** + * {@code __del__Builtin} is the built-in's own finalizer, while + * {@code __del__Derived} refers to an instance's in-dict {@code __del__}. + * A FinalizeTrigger calls {@code __del__Derived} first and + * - if existent - {@code __del__Builtin} after that. A plain {@code __del__} + * would behave as overwritten by {@code __del__Derived}, i.e. won't be called + * if the type implements {@code FinalizablePyObjectDerived} while + * {@code __del__Builtin} is called in any case. + */ + public void __del__Builtin(); +} diff --git a/src/org/python/core/finalization/FinalizablePyObject.java b/src/org/python/core/finalization/FinalizablePyObject.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizablePyObject.java @@ -0,0 +1,90 @@ +package org.python.core.finalization; + +/** + *

+ * This interface allows {@code PyObject}s to have finalizers. + * Alternatively one can use + * {@link org.python.core.finalization.FinalizableBuiltin}. + *

+ *

+ * The difference is that {@code __del__} can be overwritten by a + * new-style subclass's {@code __del__}-method on Python-side, while + * {@code __del__Builtin} is always called. If a Python-side + * finalizer exists, {@code __del__Builtin} will be called after the + * Python-side finalizer has been processed. + *

+ *

+ * One can even implement both interfaces. + * If both interfaces are implemented, the {@code FinalizeTrigger} will + * call {@code __del__} first and then {@code __del__Builtin}. If a + * new-style subclass has an own, Python-side {@code __del__}-method, this + * overwrites the Java-implemented {@code __del__}, but not + * {@code __del__Builtin}, which will be called after the Python-side + * finalizer. + *

+ *

+ * If you are writing a custom built-in that shall directly + * extend {@link org.python.core.PyObject} and have a finalizer, you can simply + * extend {@link org.python.core.finalization.PyFinalizableObject} + * and overwrite its {@code __del__}-method. + * Follow the instructions below, starting at 4). + *

+ *

+ * If you want to extend some subclass of PyObject that does not yet implement + * this interface, you have to take care of the following steps: + *

    + *
  1. + * Let your subclass implement {@code FinalizablePyObject} + * (or {@link org.python.core.finalization.FinalizableBuiltin}). + *
  2. + *
  3. + * Let it have a member
    + * {@code public FinalizeTrigger finalizeTrigger;}
    + * Other scopes also work, but might fail with security managers. + *
  4. + *
  5. + * In every constructor initialize this member via
    + * {@code finalizeTrigger = FinalizeTrigger.makeTrigger(this);}
    + * or
    + * {@code FinalizeTrigger.ensureFinalizer(this);}
    + * The latter is a better abstraction, but slightly less performant, + * since it uses reflection. + *
  6. + *
  7. + * Write your {@code __del__}-method however you intend it. + * (or {@code __del__Builtin} if + * {@link org.python.core.finalization.FinalizableBuiltin} was used) + *
  8. + *
  9. + * (optional)
    + * If your finalizer resurrects the object (Python allows this) and you wish the + * finalizer to run again on next collection of the object:
    + * In the block where the resurrection occurs, let your {@code __del__}- or + * {@code __del__Builtin}-method call
    + * {@code FinalizeTrigger.ensureFinalizer(this);}. + *
  10. + *
+ *

+ *

+ * Note: Regarding to object resurrection, Jython currently behaves like CPython >= 3.4. + * That means the finalizer {@code __del__} or {@code __del__Builtin} is called only the + * first time an object gets gc'ed. If pre 3.4. behavior is required for some reason (i.e. + * have the finalizer called repeatedly on every collection after a resurrection), one can + * achieve this manually via step 5). + *

+ *

+ * It is possible to switch finalization on and off at any desired time for a certain object. + * This can be helpful if it is only necessary to have {@code __del__} or + * {@code __del__Builtin} called for certain configurations of an object. + *

+ *

+ * To turn off the finalizer, call
+ * {@code finalizeTrigger.clear();}
+ * To turn it on again, call
+ * {@code finalizeTrigger.trigger(this);} + *

+ */ + +public interface FinalizablePyObject extends HasFinalizeTrigger { + public void __del__(); +} diff --git a/src/org/python/core/finalization/FinalizablePyObjectDerived.java b/src/org/python/core/finalization/FinalizablePyObjectDerived.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizablePyObjectDerived.java @@ -0,0 +1,23 @@ +package org.python.core.finalization; + +/** + * This interface should never be used directly in any hand-written code. + * It should only appear in automatically generated {@code fooDerived}-classes. + * + * To use finalizers in hand-written classes read the instructions at + * {@link org.python.core.finalization.FinalizablePyObject}. + * + */ +public interface FinalizablePyObjectDerived extends HasFinalizeTrigger { + + /** + * {@code __del__Builtin} is the built-in's own finalizer, while + * {@code __del__Derived} refers to an instance's in-dict {@code __del__}. + * A FinalizeTrigger calls {@code __del__Derived} first and + * - if existent - {@code __del__Builtin} after that. A plain {@code __del__} + * would behave as overwritten by {@code __del__Derived}, i.e. won't be called + * if the type implements {@code FinalizablePyObjectDerived} while + * {@code __del__Builtin} is called in any case. + */ + public void __del__Derived(); +} diff --git a/src/org/python/core/finalization/FinalizeTrigger.java b/src/org/python/core/finalization/FinalizeTrigger.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizeTrigger.java @@ -0,0 +1,138 @@ +package org.python.core.finalization; + +import java.lang.reflect.Field; +import java.lang.ref.WeakReference; +import java.lang.ref.SoftReference; +import java.lang.ref.Reference; +import org.python.core.PyObject; + +/** + * To use finalizers on {@code PyObject}s, read the documentation of + * {@link org.python.core.finalization.FinalizablePyObject}. + */ +public class FinalizeTrigger { + + /** + * This optional factory hook allows to replace the + * default {@code FinalizeTrigger}. It is f.i. needed by JyNI. + */ + public static FinalizeTriggerFactory factory; + + public static FinalizeTrigger makeTrigger(HasFinalizeTrigger toFinalize) { + if (factory != null) { + return factory.makeTrigger(toFinalize); + } else { + return new FinalizeTrigger(toFinalize); + } + } + + /* + public static FinalizeTrigger makeTriggerDerived(FinalizablePyObjectDerived toFinalize) { + if (factory != null) { + return factory.makeTriggerDerived(toFinalize); + } else { + return new FinalizeTriggerDerived(toFinalize); + } + } + */ + + /** + * Recreates the {@code FinalizeTrigger} of the given object. This makes sure that + * once the resurrected object is gc'ed again, its {@code __del__}-method will be + * called again. + */ + public static void ensureFinalizer(HasFinalizeTrigger resurrect) { + FinalizeTrigger trigger = makeTrigger(resurrect); + setFinalizeTrigger(resurrect, trigger); + } + + /* + public static void ensureFinalizerDerived(FinalizablePyObjectDerived resurrect) { + setFinalizeTrigger(resurrect, makeTriggerDerived(resurrect)); + } + */ + + public static void setFinalizeTrigger(HasFinalizeTrigger toFinalize, FinalizeTrigger trigger) { + Field triggerField; + try { + triggerField = toFinalize.getClass().getDeclaredField("finalizeTrigger"); + } catch (NoSuchFieldException nfe) { + throw new IllegalArgumentException(toFinalize.getClass()+" must have a field finalizeTrigger."); + } + try { + triggerField.set(toFinalize, trigger); + } catch (IllegalAccessException iae) { + try { + triggerField.setAccessible(true); + triggerField.set(toFinalize, trigger); + } catch (Exception e) { + throw new IllegalArgumentException("finalizeTrigger in "+toFinalize.getClass()+" must be accessible."); + } + } + } + + public static FinalizeTrigger getFinalizeTrigger(HasFinalizeTrigger toFinalize) { + Field triggerField; + try { + triggerField = toFinalize.getClass().getDeclaredField("finalizeTrigger"); + } catch (NoSuchFieldException nfe) { + throw new IllegalArgumentException(toFinalize.getClass()+" must have a field finalizeTrigger."); + } + try { + return (FinalizeTrigger) triggerField.get(toFinalize); + } catch (IllegalAccessException iae) { + try { + triggerField.setAccessible(true); + return (FinalizeTrigger) triggerField.get(toFinalize); + } catch (Exception e) { + throw new IllegalArgumentException("finalizeTrigger in "+toFinalize.getClass()+" must be accessible."); + } + } + } + + + protected HasFinalizeTrigger toFinalize; + public void clear() { + toFinalize = null; + } + + public void trigger(HasFinalizeTrigger toFinalize) + { + this.toFinalize = toFinalize; + } + + protected FinalizeTrigger(HasFinalizeTrigger toFinalize) { + this.toFinalize = toFinalize; + } + + protected void finalize() throws Throwable { + if (toFinalize != null) { + if (toFinalize instanceof FinalizablePyObjectDerived) { + ((FinalizablePyObjectDerived) toFinalize).__del__Derived(); + } else if (toFinalize instanceof FinalizablePyObject) { + ((FinalizablePyObject) toFinalize).__del__(); + } + if (toFinalize instanceof FinalizableBuiltin) { + ((FinalizableBuiltin) toFinalize).__del__Builtin(); + } + } + } + + + /* + * A FinalizeTrigger variant that only calls __del__Derived, but not the + * built-in's finalizer __del__. It can be used to control finalization + * behavior of resurrected objects in more detail. + */ + /*protected static class FinalizeTriggerDerived extends FinalizeTrigger { + protected FinalizeTriggerDerived(FinalizablePyObjectDerived toFinalize) { + super(toFinalize); + } + + protected void finalize() throws Throwable { + if (toFinalize != null) { + ((FinalizablePyObjectDerived) toFinalize).__del__Derived(); + } + } + }*/ +} diff --git a/src/org/python/core/finalization/FinalizeTriggerFactory.java b/src/org/python/core/finalization/FinalizeTriggerFactory.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizeTriggerFactory.java @@ -0,0 +1,6 @@ +package org.python.core.finalization; + +public interface FinalizeTriggerFactory { + + public FinalizeTrigger makeTrigger(HasFinalizeTrigger toFinalize); +} diff --git a/src/org/python/core/finalization/HasFinalizeTrigger.java b/src/org/python/core/finalization/HasFinalizeTrigger.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/HasFinalizeTrigger.java @@ -0,0 +1,13 @@ +package org.python.core.finalization; + +/** + * This is a pure marker-interface to indicate that a + * {@link org.python.core.PyObject} has a field declaration + * {@code FinalizeTrigger finalizeTrigger;} + * and thus can be treated by Jython's finalization API. + * + * For detailed instructions how to use finalizers in Jython, see + * {@link org.python.core.finalization.FinalizablePyObject}. + */ +public interface HasFinalizeTrigger { +} diff --git a/src/org/python/core/finalization/PyFinalizableObject.java b/src/org/python/core/finalization/PyFinalizableObject.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/PyFinalizableObject.java @@ -0,0 +1,17 @@ +package org.python.core.finalization; + +import org.python.core.PyObject;; + +/** + * For detailed intructions how to use finalizers on PyObjects, + * read the documentation of {@link org.python.core.finalization.FinalizablePyObject}. + */ +public abstract class PyFinalizableObject extends PyObject implements FinalizablePyObject { + + public FinalizeTrigger finalizeTrigger; + + public PyFinalizableObject() { + super(); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } +} diff --git a/src/org/python/modules/PyStructDerived.java b/src/org/python/modules/PyStructDerived.java --- a/src/org/python/modules/PyStructDerived.java +++ b/src/org/python/modules/PyStructDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyStructDerived extends PyStruct implements Slotted { +public class PyStructDerived extends PyStruct implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype,format); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_collections/PyDefaultDictDerived.java b/src/org/python/modules/_collections/PyDefaultDictDerived.java --- a/src/org/python/modules/_collections/PyDefaultDictDerived.java +++ b/src/org/python/modules/_collections/PyDefaultDictDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyDefaultDictDerived extends PyDefaultDict implements Slotted { +public class PyDefaultDictDerived extends PyDefaultDict implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_collections/PyDequeDerived.java b/src/org/python/modules/_collections/PyDequeDerived.java --- a/src/org/python/modules/_collections/PyDequeDerived.java +++ b/src/org/python/modules/_collections/PyDequeDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyDequeDerived extends PyDeque implements Slotted { +public class PyDequeDerived extends PyDeque implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_csv/PyDialectDerived.java b/src/org/python/modules/_csv/PyDialectDerived.java --- a/src/org/python/modules/_csv/PyDialectDerived.java +++ b/src/org/python/modules/_csv/PyDialectDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyDialectDerived extends PyDialect implements Slotted { +public class PyDialectDerived extends PyDialect implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyDialectDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_functools/PyPartialDerived.java b/src/org/python/modules/_functools/PyPartialDerived.java --- a/src/org/python/modules/_functools/PyPartialDerived.java +++ b/src/org/python/modules/_functools/PyPartialDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyPartialDerived extends PyPartial implements Slotted { +public class PyPartialDerived extends PyPartial implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_io/PyFileIODerived.java b/src/org/python/modules/_io/PyFileIODerived.java --- a/src/org/python/modules/_io/PyFileIODerived.java +++ b/src/org/python/modules/_io/PyFileIODerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyFileIODerived extends PyFileIO implements Slotted { +public class PyFileIODerived extends PyFileIO implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyFileIODerived(PyType subtype,PyObject file,OpenMode mode,boolean closefd) { super(subtype,file,mode,closefd); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_io/PyIOBase.java b/src/org/python/modules/_io/PyIOBase.java --- a/src/org/python/modules/_io/PyIOBase.java +++ b/src/org/python/modules/_io/PyIOBase.java @@ -16,6 +16,8 @@ import org.python.core.PyType; import org.python.core.PyUnicode; import org.python.core.buffer.SimpleStringBuffer; +import org.python.core.finalization.FinalizableBuiltin; +import org.python.core.finalization.FinalizeTrigger; import org.python.core.io.FileIO; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; @@ -38,20 +40,24 @@ * in Python. */ @ExposedType(name = "_io._IOBase", doc = PyIOBase.doc) -public class PyIOBase extends PyObject { +public class PyIOBase extends PyObject implements FinalizableBuiltin { public static final PyType TYPE = PyType.fromClass(PyIOBase.class); /** The ioDelegate's closer object; ensures the stream is closed at shutdown */ private Closer closer; + + public FinalizeTrigger finalizeTrigger; protected PyIOBase() { this(TYPE); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } protected PyIOBase(PyType subtype) { super(subtype); closer = new Closer(this, Py.getSystemState()); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } /** @@ -726,10 +732,9 @@ } @Override - protected void finalize() throws Throwable { + public void __del__Builtin() { closer.dismiss(); invoke("close"); - super.finalize(); } /** Convenience method providing the exception in the _checkWhatever() methods. */ diff --git a/src/org/python/modules/_io/PyIOBaseDerived.java b/src/org/python/modules/_io/PyIOBaseDerived.java --- a/src/org/python/modules/_io/PyIOBaseDerived.java +++ b/src/org/python/modules/_io/PyIOBaseDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyIOBaseDerived extends PyIOBase implements Slotted { +public class PyIOBaseDerived extends PyIOBase implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyIOBaseDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_io/PyRawIOBaseDerived.java b/src/org/python/modules/_io/PyRawIOBaseDerived.java --- a/src/org/python/modules/_io/PyRawIOBaseDerived.java +++ b/src/org/python/modules/_io/PyRawIOBaseDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyRawIOBaseDerived extends PyRawIOBase implements Slotted { +public class PyRawIOBaseDerived extends PyRawIOBase implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyRawIOBaseDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_weakref/ReferenceTypeDerived.java b/src/org/python/modules/_weakref/ReferenceTypeDerived.java --- a/src/org/python/modules/_weakref/ReferenceTypeDerived.java +++ b/src/org/python/modules/_weakref/ReferenceTypeDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ReferenceTypeDerived extends ReferenceType implements Slotted { +public class ReferenceTypeDerived extends ReferenceType implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype,gref,callback); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyBZ2CompressorDerived extends PyBZ2Compressor implements Slotted { +public class PyBZ2CompressorDerived extends PyBZ2Compressor implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyBZ2DecompressorDerived extends PyBZ2Decompressor implements Slotted { +public class PyBZ2DecompressorDerived extends PyBZ2Decompressor implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/bz2/PyBZ2File.java b/src/org/python/modules/bz2/PyBZ2File.java --- a/src/org/python/modules/bz2/PyBZ2File.java +++ b/src/org/python/modules/bz2/PyBZ2File.java @@ -24,6 +24,9 @@ import org.python.core.PySequence; import org.python.core.PyString; import org.python.core.PyType; +import org.python.core.finalization.FinalizablePyObject; +import org.python.core.finalization.FinalizableBuiltin; +import org.python.core.finalization.FinalizeTrigger; import org.python.core.io.BinaryIOWrapper; import org.python.core.io.BufferedReader; import org.python.core.io.BufferedWriter; @@ -37,7 +40,7 @@ import org.python.expose.ExposedType; @ExposedType(name = "bz2.BZ2File") -public class PyBZ2File extends PyObject { +public class PyBZ2File extends PyObject implements FinalizablePyObject, FinalizableBuiltin { public static final PyType TYPE = PyType.fromClass(PyBZ2File.class); private int buffering; @@ -58,20 +61,23 @@ private boolean needReadBufferInit = false; private boolean inReadMode = false; private boolean inWriteMode = false; + + public FinalizeTrigger finalizeTrigger; public PyBZ2File() { super(TYPE); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } public PyBZ2File(PyType subType) { super(subType); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } @Override - protected void finalize() throws Throwable { + public void __del__Builtin() { BZ2File_close(); - super.finalize(); } @ExposedNew @@ -151,6 +157,7 @@ } } + @Override @ExposedMethod public void __del__() { BZ2File_close(); diff --git a/src/org/python/modules/bz2/PyBZ2FileDerived.java b/src/org/python/modules/bz2/PyBZ2FileDerived.java --- a/src/org/python/modules/bz2/PyBZ2FileDerived.java +++ b/src/org/python/modules/bz2/PyBZ2FileDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyBZ2FileDerived extends PyBZ2File implements Slotted { +public class PyBZ2FileDerived extends PyBZ2File implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/PyTeeIteratorDerived.java b/src/org/python/modules/itertools/PyTeeIteratorDerived.java --- a/src/org/python/modules/itertools/PyTeeIteratorDerived.java +++ b/src/org/python/modules/itertools/PyTeeIteratorDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyTeeIteratorDerived extends PyTeeIterator implements Slotted { +public class PyTeeIteratorDerived extends PyTeeIterator implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/chainDerived.java b/src/org/python/modules/itertools/chainDerived.java --- a/src/org/python/modules/itertools/chainDerived.java +++ b/src/org/python/modules/itertools/chainDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class chainDerived extends chain implements Slotted { +public class chainDerived extends chain implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/combinationsDerived.java b/src/org/python/modules/itertools/combinationsDerived.java --- a/src/org/python/modules/itertools/combinationsDerived.java +++ b/src/org/python/modules/itertools/combinationsDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class combinationsDerived extends combinations implements Slotted { +public class combinationsDerived extends combinations implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java --- a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java +++ b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class combinationsWithReplacementDerived extends combinationsWithReplacement implements Slotted { +public class combinationsWithReplacementDerived extends combinationsWithReplacement implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/compressDerived.java b/src/org/python/modules/itertools/compressDerived.java --- a/src/org/python/modules/itertools/compressDerived.java +++ b/src/org/python/modules/itertools/compressDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class compressDerived extends compress implements Slotted { +public class compressDerived extends compress implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/countDerived.java b/src/org/python/modules/itertools/countDerived.java --- a/src/org/python/modules/itertools/countDerived.java +++ b/src/org/python/modules/itertools/countDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class countDerived extends count implements Slotted { +public class countDerived extends count implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/cycleDerived.java b/src/org/python/modules/itertools/cycleDerived.java --- a/src/org/python/modules/itertools/cycleDerived.java +++ b/src/org/python/modules/itertools/cycleDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class cycleDerived extends cycle implements Slotted { +public class cycleDerived extends cycle implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/dropwhileDerived.java b/src/org/python/modules/itertools/dropwhileDerived.java --- a/src/org/python/modules/itertools/dropwhileDerived.java +++ b/src/org/python/modules/itertools/dropwhileDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class dropwhileDerived extends dropwhile implements Slotted { +public class dropwhileDerived extends dropwhile implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/groupbyDerived.java b/src/org/python/modules/itertools/groupbyDerived.java --- a/src/org/python/modules/itertools/groupbyDerived.java +++ b/src/org/python/modules/itertools/groupbyDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class groupbyDerived extends groupby implements Slotted { +public class groupbyDerived extends groupby implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/ifilterDerived.java b/src/org/python/modules/itertools/ifilterDerived.java --- a/src/org/python/modules/itertools/ifilterDerived.java +++ b/src/org/python/modules/itertools/ifilterDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ifilterDerived extends ifilter implements Slotted { +public class ifilterDerived extends ifilter implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/ifilterfalseDerived.java b/src/org/python/modules/itertools/ifilterfalseDerived.java --- a/src/org/python/modules/itertools/ifilterfalseDerived.java +++ b/src/org/python/modules/itertools/ifilterfalseDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ifilterfalseDerived extends ifilterfalse implements Slotted { +public class ifilterfalseDerived extends ifilterfalse implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/isliceDerived.java b/src/org/python/modules/itertools/isliceDerived.java --- a/src/org/python/modules/itertools/isliceDerived.java +++ b/src/org/python/modules/itertools/isliceDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class isliceDerived extends islice implements Slotted { +public class isliceDerived extends islice implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/izipDerived.java b/src/org/python/modules/itertools/izipDerived.java --- a/src/org/python/modules/itertools/izipDerived.java +++ b/src/org/python/modules/itertools/izipDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class izipDerived extends izip implements Slotted { +public class izipDerived extends izip implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/izipLongestDerived.java b/src/org/python/modules/itertools/izipLongestDerived.java --- a/src/org/python/modules/itertools/izipLongestDerived.java +++ b/src/org/python/modules/itertools/izipLongestDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class izipLongestDerived extends izipLongest implements Slotted { +public class izipLongestDerived extends izipLongest implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/permutationsDerived.java b/src/org/python/modules/itertools/permutationsDerived.java --- a/src/org/python/modules/itertools/permutationsDerived.java +++ b/src/org/python/modules/itertools/permutationsDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class permutationsDerived extends permutations implements Slotted { +public class permutationsDerived extends permutations implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/productDerived.java b/src/org/python/modules/itertools/productDerived.java --- a/src/org/python/modules/itertools/productDerived.java +++ b/src/org/python/modules/itertools/productDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class productDerived extends product implements Slotted { +public class productDerived extends product implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/repeatDerived.java b/src/org/python/modules/itertools/repeatDerived.java --- a/src/org/python/modules/itertools/repeatDerived.java +++ b/src/org/python/modules/itertools/repeatDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class repeatDerived extends repeat implements Slotted { +public class repeatDerived extends repeat implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/starmapDerived.java b/src/org/python/modules/itertools/starmapDerived.java --- a/src/org/python/modules/itertools/starmapDerived.java +++ b/src/org/python/modules/itertools/starmapDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class starmapDerived extends starmap implements Slotted { +public class starmapDerived extends starmap implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/takewhileDerived.java b/src/org/python/modules/itertools/takewhileDerived.java --- a/src/org/python/modules/itertools/takewhileDerived.java +++ b/src/org/python/modules/itertools/takewhileDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class takewhileDerived extends takewhile implements Slotted { +public class takewhileDerived extends takewhile implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/random/PyRandomDerived.java b/src/org/python/modules/random/PyRandomDerived.java --- a/src/org/python/modules/random/PyRandomDerived.java +++ b/src/org/python/modules/random/PyRandomDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyRandomDerived extends PyRandom implements Slotted { +public class PyRandomDerived extends PyRandom implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/thread/PyLocalDerived.java b/src/org/python/modules/thread/PyLocalDerived.java --- a/src/org/python/modules/thread/PyLocalDerived.java +++ b/src/org/python/modules/thread/PyLocalDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyLocalDerived extends PyLocal implements Slotted { +public class PyLocalDerived extends PyLocal implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyLocalDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/zipimport/zipimporterDerived.java b/src/org/python/modules/zipimport/zipimporterDerived.java --- a/src/org/python/modules/zipimport/zipimporterDerived.java +++ b/src/org/python/modules/zipimport/zipimporterDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class zipimporterDerived extends zipimporter implements Slotted { +public class zipimporterDerived extends zipimporter implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del__Derived() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/templates/gderived-defs b/src/templates/gderived-defs --- a/src/templates/gderived-defs +++ b/src/templates/gderived-defs @@ -4,8 +4,11 @@ package org.python.core; import java.io.Serializable; + import org.python.core.finalization.FinalizeTrigger; + import org.python.core.finalization.FinalizablePyObjectDerived; - public class `concat`(`base,Derived) extends `base implements Slotted { + public class `concat`(`base,Derived) extends `base implements Slotted, FinalizablePyObjectDerived { + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +19,18 @@ } private PyObject[] slots; + + public void __del__Derived() { + PyType self_type = getType(); + PyObject impl = self_type.lookup("__del__"); + if (impl != null) { + impl.__get__(this, self_type).__call__(); + } + } + + public void ensureFinalizer() { + FinalizeTrigger.ensureFinalizer(this); + } `decls; } @@ -81,6 +96,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap || newDict instanceof PyDictionary ) { dict = newDict; + if (dict.__finditem__(PyString.fromInterned("__del__")) != null && finalizeTrigger == null) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary " + newDict.getClass().getName()); @@ -96,6 +114,9 @@ public `concat`(`base,Derived)(PyType subtype,`extraargs) { super(subtype,`extra); slots = new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } define: (ClassBodyDeclarations)ctr_userdict @@ -103,6 +124,9 @@ super(subtype,`extra); slots = new PyObject[subtype.getNumSlots()]; dict = subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } define: (ClassBodyDeclarations)toString diff --git a/src/templates/gderived.py b/src/templates/gderived.py --- a/src/templates/gderived.py +++ b/src/templates/gderived.py @@ -8,7 +8,7 @@ import directives import java_parser import java_templating -from java_templating import JavaTemplate,jast_make,jast +from java_templating import JavaTemplate, jast_make, jast org_python_dir = os.path.join(os.path.dirname(os.path.abspath(scriptdir)), 'org', 'python') @@ -19,22 +19,24 @@ package org.python.%s; import java.io.Serializable; -import org.python.core.*;""" +import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived;""" modif_re = re.compile(r"(?:\((\w+)\))?(\w+)") # os.path.samefile unavailable on Windows before Python v3.2 -if hasattr(os.path,"samefile"): +if hasattr(os.path, "samefile"): # Good: available on this platform os_path_samefile = os.path.samefile else: - def os_path_samefile(a,b): + def os_path_samefile(a, b): 'Files are considered the same if their absolute paths are equal' return os.path.abspath(a)==os.path.abspath(b) class Gen: - priority_order = ['require','define','base_class', + priority_order = ['require', 'define', 'base_class', 'want_dict', 'ctr', 'incl', @@ -44,7 +46,7 @@ 'no_toString' ] - def __init__(self,bindings=None,priority_order=None): + def __init__(self, bindings=None, priority_order=None): if bindings is None: self.global_bindings = { 'csub': java_templating.csub, 'concat': java_templating.concat, @@ -64,35 +66,35 @@ self.no_toString = False self.ctr_done = 0 - def debug(self,bindings): - for name,val in bindings.items(): - if isinstance(val,JavaTemplate): + def debug(self, bindings): + for name, val in bindings.items(): + if isinstance(val, JavaTemplate): print "%s:" % name print val.texpand({}) - def invalid(self,dire,value): - raise Exception,"invalid '%s': %s" % (dire,value) + def invalid(self, dire, value): + raise Exception,"invalid '%s': %s" % (dire, value) - def get_aux(self,name): + def get_aux(self, name): if self.auxiliary is None: - aux_gen = Gen(priority_order=['require','define']) - directives.execute(directives.load(os.path.join(scriptdir,'gderived-defs')),aux_gen) + aux_gen = Gen(priority_order=['require', 'define']) + directives.execute(directives.load(os.path.join(scriptdir, 'gderived-defs')), aux_gen) self.auxiliary = aux_gen.global_bindings return self.auxiliary[name] - def dire_require(self,name,parm,body): + def dire_require(self, name, parm, body): if body is not None: - self.invalid('require','non-empty body') - sub_gen = Gen(bindings=self.global_bindings, priority__order=['require','define']) - directives.execute(directives.load(parm.strip()),sub_gen) + self.invalid('require', 'non-empty body') + sub_gen = Gen(bindings=self.global_bindings, priority__order=['require', 'define']) + directives.execute(directives.load(parm.strip()), sub_gen) - def dire_define(self,name,parm,body): + def dire_define(self, name, parm, body): parms = parm.split() if not parms: - self.invalid('define',parm) + self.invalid('define', parm) parsed_name = modif_re.match(parms[0]) if not parsed_name: - self.invalid('define',parm) + self.invalid('define', parm) templ_kind = parsed_name.group(1) templ_name = parsed_name.group(2) if templ_kind is None: @@ -104,40 +106,40 @@ start = templ_kind) self.global_bindings[templ_name] = templ - def dire_base_class(self,name,parm,body): + def dire_base_class(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') if self.base_class is None: self.base_class = JavaTemplate(parm.strip()) self.global_bindings['base'] = self.base_class - def dire_want_dict(self,name,parm,body): + def dire_want_dict(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') if self.want_dict is None: self.want_dict = {"true": 1, "false": 0}[parm.strip()] - def dire_no_toString(self,name,parm,body): + def dire_no_toString(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') self.no_toString = True - def dire_incl(self,name,parm,body): + def dire_incl(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') directives.execute(directives.load(parm.strip()+'.derived'),self) - def dire_ctr(self,name,parm,body): + def dire_ctr(self, name, parm, body): if self.ctr_done: return if body is not None: - self.invalid(name,"non-empty body") + self.invalid(name, "non-empty body") if self.want_dict: self.add_decl(self.get_aux('userdict')) ctr = self.get_aux('ctr_userdict') else: ctr = self.get_aux('ctr') - extraargs = JavaTemplate(parm.strip(),start="FormalParameterListOpt") + extraargs = JavaTemplate(parm.strip(), start="FormalParameterListOpt") def visit(node): if isinstance(node, jast.VariableDeclaratorId): yield node.Identifier @@ -145,20 +147,20 @@ for child in node.children: for x in visit(child): yield x - extra = jast_make(jast.Expressions, [jast_make(jast.Primary,Identifier=x,ArgumentsOpt=None) for x in visit(extraargs.fragment)]) + extra = jast_make(jast.Expressions, [jast_make(jast.Primary, Identifier=x, ArgumentsOpt=None) for x in visit(extraargs.fragment)]) extra = JavaTemplate(extra) self.add_decl(ctr.tbind({'base': self.base_class, 'extraargs': extraargs, 'extra': extra})) self.ctr_done = 1 - def add_decl(self,templ): + def add_decl(self, templ): pair = self.get_aux('pair') self.decls = pair.tbind({'trailer': self.decls, 'last': templ}) - def dire_unary1(self,name,parm,body): + def dire_unary1(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') parms = parm.split() - if len(parms) not in (1,2,3): - self.invalid(name,parm) + if len(parms) not in (1, 2, 3): + self.invalid(name, parm) meth_name = parms[0] if len(parms) == 1: unary_body = self.get_aux('unary') @@ -176,28 +178,28 @@ 'rettype': JavaTemplate(rettype_class)})) - def dire_binary(self,name,parm,body): + def dire_binary(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') meth_names = parm.split() binary_body = self.get_aux('binary') for meth_name in meth_names: self.add_decl(binary_body.tbind({'binary': JavaTemplate(meth_name)})) - def dire_ibinary(self,name,parm,body): + def dire_ibinary(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') meth_names = parm.split() binary_body = self.get_aux('ibinary') for meth_name in meth_names: self.add_decl(binary_body.tbind({'binary': JavaTemplate(meth_name)})) - def dire_rest(self,name,parm,body): + def dire_rest(self, name, parm, body): if parm: - self.invalid(name,'non-empty parm') + self.invalid(name, 'non-empty parm') if body is None: return - self.add_decl(JavaTemplate(body,start='ClassBodyDeclarations')) + self.add_decl(JavaTemplate(body, start='ClassBodyDeclarations')) def generate(self): if not self.no_toString: @@ -209,10 +211,10 @@ if (lazy and os.path.exists(outfile) and os.stat(fn).st_mtime < os.stat(outfile).st_mtime): - return + return print 'Processing %s into %s' % (fn, outfile) gen = Gen() - directives.execute(directives.load(fn),gen) + directives.execute(directives.load(fn), gen) result = gen.generate() result = hack_derived_header(outfile, result) print >> open(outfile, 'w'), result @@ -240,30 +242,29 @@ header = DERIVED_HEADER % '.'.join(dirs) result[0:num - 1] = header.splitlines() break + + return '\n'.join(result) - return '\n'.join(result) - + if __name__ == '__main__': from gexpose import load_mappings, usage lazy = False if len(sys.argv) > 4: usage() - sys.exit(1) + sys.exit(1) if len(sys.argv) >= 2: - if '--help' in sys.argv: - usage() - sys.exit(0) - elif '--lazy' in sys.argv: - lazy = True - sys.argv.remove('--lazy') + if '--help' in sys.argv: + usage() + sys.exit(0) + elif '--lazy' in sys.argv: + lazy = True + sys.argv.remove('--lazy') if len(sys.argv) == 1: - for template, mapping in load_mappings().items(): - if template.endswith('derived'): - process(mapping[0], mapping[1], lazy) + for template, mapping in load_mappings().items(): + if template.endswith('derived'): + process(mapping[0], mapping[1], lazy) elif len(sys.argv) == 2: - mapping = load_mappings()[sys.argv[1]] + mapping = load_mappings()[sys.argv[1]] process(mapping[0], mapping[1], lazy) else: process(sys.argv[1], sys.argv[2], lazy) - - diff --git a/src/templates/object.derived b/src/templates/object.derived --- a/src/templates/object.derived +++ b/src/templates/object.derived @@ -318,6 +318,8 @@ PyObject impl = self_type.lookup("__setattr__"); if (impl != null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Thu Sep 4 06:35:37 2014 From: jython-checkins at python.org (jim.baker) Date: Thu, 4 Sep 2014 06:35:37 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Now_one_can_manually_restor?= =?utf-8?q?e_an_object=27s_finalizer_via?= Message-ID: <3hpTj53bMCz7Lk8@mail.python.org> http://hg.python.org/jython/rev/4a04ad5e201b changeset: 7361:4a04ad5e201b user: Stefan Richthofer date: Tue Aug 26 14:21:45 2014 +0200 summary: Now one can manually restore an object's finalizer via someObject.__ensure_finalizer__. Additionally I cleaned up out-commented and dead code and changed the indentation style in test_finalizers.py to comply with Jython's coding guideline. I also refectored the method names __del__Builtin and __del__Derived to __del_builtin__ and __del_derived__. files: Lib/test/test_finalizers.py | 615 +++++---- src/org/python/antlr/ast/AssertDerived.java | 4 +- src/org/python/antlr/ast/AssignDerived.java | 4 +- src/org/python/antlr/ast/AttributeDerived.java | 4 +- src/org/python/antlr/ast/AugAssignDerived.java | 4 +- src/org/python/antlr/ast/BinOpDerived.java | 4 +- src/org/python/antlr/ast/BoolOpDerived.java | 4 +- src/org/python/antlr/ast/BreakDerived.java | 4 +- src/org/python/antlr/ast/CallDerived.java | 4 +- src/org/python/antlr/ast/ClassDefDerived.java | 4 +- src/org/python/antlr/ast/CompareDerived.java | 4 +- src/org/python/antlr/ast/ContinueDerived.java | 4 +- src/org/python/antlr/ast/DeleteDerived.java | 4 +- src/org/python/antlr/ast/DictDerived.java | 4 +- src/org/python/antlr/ast/EllipsisDerived.java | 4 +- src/org/python/antlr/ast/ExceptHandlerDerived.java | 4 +- src/org/python/antlr/ast/ExecDerived.java | 4 +- src/org/python/antlr/ast/ExprDerived.java | 4 +- src/org/python/antlr/ast/ExpressionDerived.java | 4 +- src/org/python/antlr/ast/ExtSliceDerived.java | 4 +- src/org/python/antlr/ast/ForDerived.java | 4 +- src/org/python/antlr/ast/FunctionDefDerived.java | 4 +- src/org/python/antlr/ast/GeneratorExpDerived.java | 4 +- src/org/python/antlr/ast/GlobalDerived.java | 4 +- src/org/python/antlr/ast/IfDerived.java | 4 +- src/org/python/antlr/ast/IfExpDerived.java | 4 +- src/org/python/antlr/ast/ImportDerived.java | 4 +- src/org/python/antlr/ast/ImportFromDerived.java | 4 +- src/org/python/antlr/ast/IndexDerived.java | 4 +- src/org/python/antlr/ast/InteractiveDerived.java | 4 +- src/org/python/antlr/ast/LambdaDerived.java | 4 +- src/org/python/antlr/ast/ListCompDerived.java | 4 +- src/org/python/antlr/ast/ListDerived.java | 4 +- src/org/python/antlr/ast/ModuleDerived.java | 4 +- src/org/python/antlr/ast/NameDerived.java | 4 +- src/org/python/antlr/ast/NumDerived.java | 4 +- src/org/python/antlr/ast/PassDerived.java | 4 +- src/org/python/antlr/ast/PrintDerived.java | 4 +- src/org/python/antlr/ast/RaiseDerived.java | 4 +- src/org/python/antlr/ast/ReprDerived.java | 4 +- src/org/python/antlr/ast/ReturnDerived.java | 4 +- src/org/python/antlr/ast/SliceDerived.java | 4 +- src/org/python/antlr/ast/StrDerived.java | 4 +- src/org/python/antlr/ast/SubscriptDerived.java | 4 +- src/org/python/antlr/ast/SuiteDerived.java | 4 +- src/org/python/antlr/ast/TryExceptDerived.java | 4 +- src/org/python/antlr/ast/TryFinallyDerived.java | 4 +- src/org/python/antlr/ast/TupleDerived.java | 4 +- src/org/python/antlr/ast/UnaryOpDerived.java | 4 +- src/org/python/antlr/ast/WhileDerived.java | 4 +- src/org/python/antlr/ast/WithDerived.java | 4 +- src/org/python/antlr/ast/YieldDerived.java | 4 +- src/org/python/antlr/ast/aliasDerived.java | 4 +- src/org/python/antlr/ast/argumentsDerived.java | 4 +- src/org/python/antlr/ast/comprehensionDerived.java | 4 +- src/org/python/antlr/ast/keywordDerived.java | 4 +- src/org/python/antlr/op/AddDerived.java | 4 +- src/org/python/antlr/op/AndDerived.java | 4 +- src/org/python/antlr/op/AugLoadDerived.java | 4 +- src/org/python/antlr/op/AugStoreDerived.java | 4 +- src/org/python/antlr/op/BitAndDerived.java | 4 +- src/org/python/antlr/op/BitOrDerived.java | 4 +- src/org/python/antlr/op/BitXorDerived.java | 4 +- src/org/python/antlr/op/DelDerived.java | 4 +- src/org/python/antlr/op/DivDerived.java | 4 +- src/org/python/antlr/op/EqDerived.java | 4 +- src/org/python/antlr/op/FloorDivDerived.java | 4 +- src/org/python/antlr/op/GtDerived.java | 4 +- src/org/python/antlr/op/GtEDerived.java | 4 +- src/org/python/antlr/op/InDerived.java | 4 +- src/org/python/antlr/op/InvertDerived.java | 4 +- src/org/python/antlr/op/IsDerived.java | 4 +- src/org/python/antlr/op/IsNotDerived.java | 4 +- src/org/python/antlr/op/LShiftDerived.java | 4 +- src/org/python/antlr/op/LoadDerived.java | 4 +- src/org/python/antlr/op/LtDerived.java | 4 +- src/org/python/antlr/op/LtEDerived.java | 4 +- src/org/python/antlr/op/ModDerived.java | 4 +- src/org/python/antlr/op/MultDerived.java | 4 +- src/org/python/antlr/op/NotDerived.java | 4 +- src/org/python/antlr/op/NotEqDerived.java | 4 +- src/org/python/antlr/op/NotInDerived.java | 4 +- src/org/python/antlr/op/OrDerived.java | 4 +- src/org/python/antlr/op/ParamDerived.java | 4 +- src/org/python/antlr/op/PowDerived.java | 4 +- src/org/python/antlr/op/RShiftDerived.java | 4 +- src/org/python/antlr/op/StoreDerived.java | 4 +- src/org/python/antlr/op/SubDerived.java | 4 +- src/org/python/antlr/op/UAddDerived.java | 4 +- src/org/python/antlr/op/USubDerived.java | 4 +- src/org/python/core/ClasspathPyImporterDerived.java | 4 +- src/org/python/core/Py.java | 3 +- src/org/python/core/PyArrayDerived.java | 4 +- src/org/python/core/PyBaseExceptionDerived.java | 4 +- src/org/python/core/PyByteArrayDerived.java | 4 +- src/org/python/core/PyClass.java | 6 - src/org/python/core/PyClassMethodDerived.java | 4 +- src/org/python/core/PyComplexDerived.java | 4 +- src/org/python/core/PyDictionaryDerived.java | 4 +- src/org/python/core/PyEnumerateDerived.java | 4 +- src/org/python/core/PyFile.java | 2 +- src/org/python/core/PyFileDerived.java | 4 +- src/org/python/core/PyFloatDerived.java | 4 +- src/org/python/core/PyFrozenSetDerived.java | 4 +- src/org/python/core/PyGenerator.java | 2 +- src/org/python/core/PyInstance.java | 39 +- src/org/python/core/PyIntegerDerived.java | 4 +- src/org/python/core/PyListDerived.java | 4 +- src/org/python/core/PyLongDerived.java | 4 +- src/org/python/core/PyModuleDerived.java | 4 +- src/org/python/core/PyObject.java | 7 + src/org/python/core/PyObjectDerived.java | 4 +- src/org/python/core/PyPropertyDerived.java | 4 +- src/org/python/core/PySetDerived.java | 4 +- src/org/python/core/PyStringDerived.java | 4 +- src/org/python/core/PySuperDerived.java | 4 +- src/org/python/core/PyTupleDerived.java | 4 +- src/org/python/core/PyTypeDerived.java | 4 +- src/org/python/core/PyUnicodeDerived.java | 4 +- src/org/python/core/finalization/FinalizableBuiltin.java | 12 +- src/org/python/core/finalization/FinalizablePyObject.java | 14 +- src/org/python/core/finalization/FinalizablePyObjectDerived.java | 14 +- src/org/python/core/finalization/FinalizeTrigger.java | 43 +- src/org/python/modules/PyStructDerived.java | 4 +- src/org/python/modules/_collections/PyDefaultDictDerived.java | 4 +- src/org/python/modules/_collections/PyDequeDerived.java | 4 +- src/org/python/modules/_csv/PyDialectDerived.java | 4 +- src/org/python/modules/_functools/PyPartialDerived.java | 4 +- src/org/python/modules/_io/PyFileIODerived.java | 4 +- src/org/python/modules/_io/PyIOBase.java | 2 +- src/org/python/modules/_io/PyIOBaseDerived.java | 4 +- src/org/python/modules/_io/PyRawIOBaseDerived.java | 4 +- src/org/python/modules/_weakref/ReferenceTypeDerived.java | 4 +- src/org/python/modules/bz2/PyBZ2CompressorDerived.java | 4 +- src/org/python/modules/bz2/PyBZ2DecompressorDerived.java | 4 +- src/org/python/modules/bz2/PyBZ2File.java | 2 +- src/org/python/modules/bz2/PyBZ2FileDerived.java | 4 +- src/org/python/modules/itertools/PyTeeIteratorDerived.java | 4 +- src/org/python/modules/itertools/chainDerived.java | 4 +- src/org/python/modules/itertools/combinationsDerived.java | 4 +- src/org/python/modules/itertools/combinationsWithReplacementDerived.java | 4 +- src/org/python/modules/itertools/compressDerived.java | 4 +- src/org/python/modules/itertools/countDerived.java | 4 +- src/org/python/modules/itertools/cycleDerived.java | 4 +- src/org/python/modules/itertools/dropwhileDerived.java | 4 +- src/org/python/modules/itertools/groupbyDerived.java | 4 +- src/org/python/modules/itertools/ifilterDerived.java | 4 +- src/org/python/modules/itertools/ifilterfalseDerived.java | 4 +- src/org/python/modules/itertools/isliceDerived.java | 4 +- src/org/python/modules/itertools/izipDerived.java | 4 +- src/org/python/modules/itertools/izipLongestDerived.java | 4 +- src/org/python/modules/itertools/permutationsDerived.java | 4 +- src/org/python/modules/itertools/productDerived.java | 4 +- src/org/python/modules/itertools/repeatDerived.java | 4 +- src/org/python/modules/itertools/starmapDerived.java | 4 +- src/org/python/modules/itertools/takewhileDerived.java | 4 +- src/org/python/modules/random/PyRandomDerived.java | 4 +- src/org/python/modules/thread/PyLocalDerived.java | 4 +- src/org/python/modules/zipimport/zipimporterDerived.java | 4 +- src/templates/gderived-defs | 6 +- src/templates/object.derived | 1 - 161 files changed, 665 insertions(+), 687 deletions(-) diff --git a/Lib/test/test_finalizers.py b/Lib/test/test_finalizers.py --- a/Lib/test/test_finalizers.py +++ b/Lib/test/test_finalizers.py @@ -2,32 +2,34 @@ Created on 06.08.2014 ''' -import platform import unittest import types import time -if platform.system() == "Java": - from java.lang import System - from org.python.core.finalization import FinalizeTrigger +try: + from java.lang import System +except: + pass class GCDetector(): - gcIndex = 0 - - def __del__(self): - GCDetector.gcIndex += 1 + gcIndex = 0 + + def __del__(self): + GCDetector.gcIndex += 1 maxGCRun = 10 def runGCIfJython(): - if platform.system() == "Java": - currentIndex = GCDetector.gcIndex - gcCount = 0 - detector = GCDetector() - detector = None - while currentIndex == GCDetector.gcIndex and gcCount < maxGCRun: - System.gc() - gcCount += 1 - time.sleep(0.1) + try: + currentIndex = GCDetector.gcIndex + gcCount = 0 + detector = GCDetector() + detector = None + while currentIndex == GCDetector.gcIndex and gcCount < maxGCRun: + System.gc() + gcCount += 1 + time.sleep(0.1) + except: + pass finalizeMsgList = [] verbose = False @@ -40,71 +42,71 @@ class ResurrectableDummyClass(): - def __init__(self, name): - self.name = name - self.doResurrection = True + def __init__(self, name): + self.name = name + self.doResurrection = True - def __str__(self): - return self.name + def __str__(self): + return self.name class ResurrectableDummyClassNew(object): - def __init__(self, name): - self.name = name - self.doResurrection = True + def __init__(self, name): + self.name = name + self.doResurrection = True - def __str__(self): - return self.name + def __str__(self): + return self.name def __del__I(self): - global resurrectedObject_I - finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") - if verbose: - print str(self)+" finalized (ResurrectableDummyClass)" - if self.doResurrection: - resurrectedObject_I = self + global resurrectedObject_I + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_I = self def __del__J(self): - global resurrectedObject_J - finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") - if verbose: - print str(self)+" finalized (ResurrectableDummyClass)" - if self.doResurrection: - resurrectedObject_J = self + global resurrectedObject_J + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_J = self def __del__K(self): - global resurrectedObject_K - finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") - if verbose: - print str(self)+" finalized (ResurrectableDummyClass)" - if self.doResurrection: - resurrectedObject_K = self + global resurrectedObject_K + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_K = self def __del__L(self): - global resurrectedObject_L - finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") - if verbose: - print str(self)+" finalized (ResurrectableDummyClass)" - if self.doResurrection: - resurrectedObject_L = self + global resurrectedObject_L + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_L = self def __del__M(self): - global resurrectedObject_M - finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") - if verbose: - print str(self)+" finalized (ResurrectableDummyClass)" - if self.doResurrection: - resurrectedObject_M = self + global resurrectedObject_M + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_M = self def __del__N(self): - global resurrectedObject_N - finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") - if verbose: - print str(self)+" finalized (ResurrectableDummyClass)" - if self.doResurrection: - resurrectedObject_N = self + global resurrectedObject_N + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_N = self delI = __del__I delJ = __del__J @@ -115,289 +117,302 @@ class DummyClass(): - - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name class DummyClassDel(): - - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name - - def __del__(self): - finalizeMsgList.append(str(self)+" finalized (DummyClassDel)") - if verbose: - print str(self)+" finalized (DummyClassDel)" + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyClassDel)") + if verbose: + print str(self)+" finalized (DummyClassDel)" class DummyClassNew(object): - - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name class DummyClassDelNew(object): - - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name - - def __del__(self): - finalizeMsgList.append(str(self)+" finalized (DummyClassDelNew)") - if verbose: - print str(self)+" finalized (DummyClassDelNew)" + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyClassDelNew)") + if verbose: + print str(self)+" finalized (DummyClassDelNew)" class DummyFileClassNew(file): - - def __init__(self, name): - self.name0 = name - - def __str__(self): - return self.name0 + + def __init__(self, name): + self.name0 = name + + def __str__(self): + return self.name0 - def __del__(self): - finalizeMsgList.append(str(self)+" finalized (DummyFileClassNew)") - if verbose: - print str(self)+" finalized (DummyFileClassNew)" + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyFileClassNew)") + if verbose: + print str(self)+" finalized (DummyFileClassNew)" def __del__class(self): - finalizeMsgList.append(str(self)+" finalized (acquired by class)") - if verbose: - print str(self)+" finalized (acquired by class)" + finalizeMsgList.append(str(self)+" finalized (acquired by class)") + if verbose: + print str(self)+" finalized (acquired by class)" def __del__object(self): - finalizeMsgList.append(str(self)+" finalized (acquired by object)") - if verbose: - print str(self)+" finalized (acquired by object)" + finalizeMsgList.append(str(self)+" finalized (acquired by object)") + if verbose: + print str(self)+" finalized (acquired by object)" def __del__object0(): - finalizeMsgList.append("_ finalized (acquired by object)") - if verbose: - print "_ finalized (acquired by object)" + finalizeMsgList.append("_ finalized (acquired by object)") + if verbose: + print "_ finalized (acquired by object)" delClass = __del__class delObject = __del__object delObject0 = __del__object0 class TestFinalizers(unittest.TestCase): - def test_finalizer_builtin_oldStyleClass(self): - A = DummyClassDel("A") - A = None - runGCIfJython() - assert("A finalized (DummyClassDel)" in finalizeMsgList) + def test_finalizer_builtin_oldStyleClass(self): + A = DummyClassDel("A") + A = None + runGCIfJython() + assert("A finalized (DummyClassDel)" in finalizeMsgList) - def test_classAcquiresFinalizer_beforeInstanciation_oldStyleClass(self): - DummyClass.__del__ = delClass - B = DummyClass("B") - B = None - runGCIfJython() - assert("B finalized (acquired by class)" in finalizeMsgList) - del DummyClass.__del__ + def test_classAcquiresFinalizer_beforeInstanciation_oldStyleClass(self): + DummyClass.__del__ = delClass + B = DummyClass("B") + B = None + runGCIfJython() + assert("B finalized (acquired by class)" in finalizeMsgList) + del DummyClass.__del__ - def test_classAcquiresFinalizer_afterInstanciation_oldStyleClass(self): - #okay to fail in Jython without the manual ensureFinalizer call - C = DummyClass("C") - DummyClass.__del__ = delClass - if platform.system() == "Java": - FinalizeTrigger.ensureFinalizer(C) - C = None - runGCIfJython() - assert("C finalized (acquired by class)" in finalizeMsgList) - del DummyClass.__del__ + def test_classAcquiresFinalizer_afterInstanciation_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer call + C = DummyClass("C") + DummyClass.__del__ = delClass + try: + C.__ensure_finalizer__() + except: + pass + C = None + runGCIfJython() + assert("C finalized (acquired by class)" in finalizeMsgList) + del DummyClass.__del__ - def test_instanceAcquiresFinalizer_bound_oldStyleClass(self): - D = DummyClassDel("D") - dl = types.MethodType(delObject, D.name) - D.__del__ = dl - D = None - runGCIfJython() - assert("D finalized (DummyClassDel)" not in finalizeMsgList) - assert("D finalized (acquired by object)" in finalizeMsgList) + def test_instanceAcquiresFinalizer_bound_oldStyleClass(self): + D = DummyClassDel("D") + dl = types.MethodType(delObject, D.name) + D.__del__ = dl + D = None + runGCIfJython() + assert("D finalized (DummyClassDel)" not in finalizeMsgList) + assert("D finalized (acquired by object)" in finalizeMsgList) - def test_finalizer_builtin_newStyleClass(self): - E = DummyClassDelNew("E") - E = None - runGCIfJython() - assert("E finalized (DummyClassDelNew)" in finalizeMsgList) + def test_finalizer_builtin_newStyleClass(self): + E = DummyClassDelNew("E") + E = None + runGCIfJython() + assert("E finalized (DummyClassDelNew)" in finalizeMsgList) - def test_classAcquiresFinalizer_beforeInstanciation_newStyleClass(self): - DummyClassNew.__del__ = delClass - F = DummyClassNew("F") - F = None - runGCIfJython() - assert("F finalized (acquired by class)" in finalizeMsgList) - del DummyClassNew.__del__ + def test_classAcquiresFinalizer_beforeInstanciation_newStyleClass(self): + DummyClassNew.__del__ = delClass + F = DummyClassNew("F") + F = None + runGCIfJython() + assert("F finalized (acquired by class)" in finalizeMsgList) + del DummyClassNew.__del__ - def test_classAcquiresFinalizer_afterInstanciation_newStyleClass(self): - #okay to fail in Jython without the manual ensureFinalizer call - G = DummyClassNew("G") - DummyClassNew.__del__ = delClass - if platform.system() == "Java": - FinalizeTrigger.ensureFinalizer(G) - G = None - runGCIfJython() - assert("G finalized (acquired by class)" in finalizeMsgList) - del DummyClassNew.__del__ + def test_classAcquiresFinalizer_afterInstanciation_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer call + G = DummyClassNew("G") + DummyClassNew.__del__ = delClass + try: + G.__ensure_finalizer__() + except: + pass + G = None + runGCIfJython() + assert("G finalized (acquired by class)" in finalizeMsgList) + del DummyClassNew.__del__ - def test_instanceAcquiresFinalizer_bound_newStyleClass(self): - """ - It seems, CPython prohibits new style instances from acquiring a finalizer. - """ - H = DummyClassDelNew("H") - H.__del__ = types.MethodType(delObject, H.name) - H = None - runGCIfJython() - assert("H finalized (DummyClassDelNew)" in finalizeMsgList) - assert("H finalized (acquired by object)" not in finalizeMsgList) + def test_instanceAcquiresFinalizer_bound_newStyleClass(self): + """ + It seems, CPython prohibits new style instances from acquiring a finalizer. + """ + H = DummyClassDelNew("H") + H.__del__ = types.MethodType(delObject, H.name) + H = None + runGCIfJython() + assert("H finalized (DummyClassDelNew)" in finalizeMsgList) + assert("H finalized (acquired by object)" not in finalizeMsgList) - def test_instanceAcquiresFinalizer_bound_newStyleClass2(self): - """ - It seems, CPython prohibits new style instances from acquiring a finalizer. - If one calls the instance-acquired __del__ manually, it works, but the gc - will still call the old one. - """ - H = DummyClassDelNew("H2") - H.__del__ = types.MethodType(delObject, H.name) - H.__del__() - H = None - runGCIfJython() - assert("H2 finalized (DummyClassDelNew)" in finalizeMsgList) - assert("H2 finalized (acquired by object)" in finalizeMsgList) + def test_instanceAcquiresFinalizer_bound_newStyleClass2(self): + """ + It seems, CPython prohibits new style instances from acquiring a finalizer. + If one calls the instance-acquired __del__ manually, it works, but the gc + will still call the old one. + """ + H = DummyClassDelNew("H2") + H.__del__ = types.MethodType(delObject, H.name) + H.__del__() + H = None + runGCIfJython() + assert("H2 finalized (DummyClassDelNew)" in finalizeMsgList) + assert("H2 finalized (acquired by object)" in finalizeMsgList) - def test_objectResurrection_oldStyleClass(self): - ResurrectableDummyClass.__del__ = delI - I = ResurrectableDummyClass("I") - I = None - runGCIfJython() - assert("I finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_I) == "I") + def test_objectResurrection_oldStyleClass(self): + ResurrectableDummyClass.__del__ = delI + I = ResurrectableDummyClass("I") + I = None + runGCIfJython() + assert("I finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_I) == "I") - def test_objectDoubleResurrection_oldStyleClass(self): - #okay to fail in Jython without the manual ensureFinalizer calls - ResurrectableDummyClass.__del__ = delJ - J = ResurrectableDummyClass("J") - J = None - - runGCIfJython() - assert("J finalized (ResurrectableDummyClass)" in finalizeMsgList) - global resurrectedObject_J - assert(str(resurrectedObject_J) == "J") - J = resurrectedObject_J - resurrectedObject_J = None - assert(resurrectedObject_J is None) - if platform.system() == "Java": - #For Jython one can restore the finalizer manually. - #This is offered as an easy fix if the CPython behavior - #in this test should be needed for some reason. - FinalizeTrigger.ensureFinalizer(J) - J = None + def test_objectDoubleResurrection_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClass.__del__ = delJ + J = ResurrectableDummyClass("J") + J = None + + runGCIfJython() + assert("J finalized (ResurrectableDummyClass)" in finalizeMsgList) + global resurrectedObject_J + assert(str(resurrectedObject_J) == "J") + J = resurrectedObject_J + resurrectedObject_J = None + assert(resurrectedObject_J is None) + try: + #For Jython one can restore the finalizer manually. + #This is offered as an easy fix if the CPython behavior + #in this test should be needed for some reason. + J.__ensure_finalizer__() + except: + pass + J = None - runGCIfJython() - assert(str(resurrectedObject_J) == "J") - resurrectedObject_J.doResurrection = False - if platform.system() == "Java": - #again... - FinalizeTrigger.ensureFinalizer(resurrectedObject_J) - resurrectedObject_J = None - - runGCIfJython() - assert(resurrectedObject_J is None) - + runGCIfJython() + assert(str(resurrectedObject_J) == "J") + resurrectedObject_J.doResurrection = False + try: + #again... + resurrectedObject_J.__ensure_finalizer__() + except: + pass + resurrectedObject_J = None + + runGCIfJython() + assert(resurrectedObject_J is None) + - def test_objectDoubleResurrectionAndFinalize_oldStyleClass(self): - #okay to fail in Jython without the manual ensureFinalizer calls - ResurrectableDummyClass.__del__ = delK - K = ResurrectableDummyClass("K") - K = None - - runGCIfJython() - assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) - finalizeMsgList.remove("K finalized (ResurrectableDummyClass)") - assert("K finalized (ResurrectableDummyClass)" not in finalizeMsgList) - global resurrectedObject_K - assert(str(resurrectedObject_K) == "K") - K = resurrectedObject_K - resurrectedObject_K = None - assert(resurrectedObject_K is None) - if platform.system() == "Java": - FinalizeTrigger.ensureFinalizer(K) - K = None - - runGCIfJython() - assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_K) == "K") + def test_objectDoubleResurrectionAndFinalize_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClass.__del__ = delK + K = ResurrectableDummyClass("K") + K = None - def test_objectResurrection_newStyleClass(self): - ResurrectableDummyClassNew.__del__ = delL - L = ResurrectableDummyClassNew("L") - L = None - runGCIfJython() - assert("L finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_L) == "L") + runGCIfJython() + assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) + finalizeMsgList.remove("K finalized (ResurrectableDummyClass)") + assert("K finalized (ResurrectableDummyClass)" not in finalizeMsgList) + global resurrectedObject_K + assert(str(resurrectedObject_K) == "K") + K = resurrectedObject_K + resurrectedObject_K = None + assert(resurrectedObject_K is None) + try: + K.__ensure_finalizer__() + except: + pass + K = None - def test_objectDoubleResurrection_newStyleClass(self): - #okay to fail in Jython without the manual ensureFinalizer calls - ResurrectableDummyClassNew.__del__ = delM - M = ResurrectableDummyClassNew("M") - M = None + runGCIfJython() + assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_K) == "K") - runGCIfJython() - assert("M finalized (ResurrectableDummyClass)" in finalizeMsgList) - global resurrectedObject_M - assert(str(resurrectedObject_M) == "M") - M = resurrectedObject_M - resurrectedObject_M = None - assert(resurrectedObject_M is None) - if platform.system() == "Java": - FinalizeTrigger.ensureFinalizer(M) - M = None + def test_objectResurrection_newStyleClass(self): + ResurrectableDummyClassNew.__del__ = delL + L = ResurrectableDummyClassNew("L") + L = None + runGCIfJython() + assert("L finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_L) == "L") - runGCIfJython() - assert(str(resurrectedObject_M) == "M") + def test_objectDoubleResurrection_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClassNew.__del__ = delM + M = ResurrectableDummyClassNew("M") + M = None - def test_objectDoubleResurrectionAndFinalize_newStyleClass(self): - #okay to fail in Jython without the manual ensureFinalizer calls - ResurrectableDummyClassNew.__del__ = delN - N = ResurrectableDummyClassNew("N") - N = None + runGCIfJython() + assert("M finalized (ResurrectableDummyClass)" in finalizeMsgList) + global resurrectedObject_M + assert(str(resurrectedObject_M) == "M") + M = resurrectedObject_M + resurrectedObject_M = None + assert(resurrectedObject_M is None) + try: + M.__ensure_finalizer__() + except: + pass + M = None - runGCIfJython() - assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) - finalizeMsgList.remove("N finalized (ResurrectableDummyClass)") - assert("N finalized (ResurrectableDummyClass)" not in finalizeMsgList) - global resurrectedObject_N - assert(str(resurrectedObject_N) == "N") - N = resurrectedObject_N - resurrectedObject_N = None - assert(resurrectedObject_N is None) - if platform.system() == "Java": - FinalizeTrigger.ensureFinalizer(N) - N = None + runGCIfJython() + assert(str(resurrectedObject_M) == "M") - runGCIfJython() - assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_N) == "N") + def test_objectDoubleResurrectionAndFinalize_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClassNew.__del__ = delN + N = ResurrectableDummyClassNew("N") + N = None - def test_file_overwrite_del(self): - O = DummyFileClassNew("O") - O = None + runGCIfJython() + assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) + finalizeMsgList.remove("N finalized (ResurrectableDummyClass)") + assert("N finalized (ResurrectableDummyClass)" not in finalizeMsgList) + global resurrectedObject_N + assert(str(resurrectedObject_N) == "N") + N = resurrectedObject_N + resurrectedObject_N = None + assert(resurrectedObject_N is None) + try: + N.__ensure_finalizer__() + except: + pass + N = None - runGCIfJython() - assert("O finalized (DummyFileClassNew)" in finalizeMsgList) + runGCIfJython() + assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_N) == "N") + def test_file_overwrite_del(self): + O = DummyFileClassNew("O") + O = None + + runGCIfJython() + assert("O finalized (DummyFileClassNew)" in finalizeMsgList) if __name__ == '__main__': - unittest.main() + unittest.main() diff --git a/src/org/python/antlr/ast/AssertDerived.java b/src/org/python/antlr/ast/AssertDerived.java --- a/src/org/python/antlr/ast/AssertDerived.java +++ b/src/org/python/antlr/ast/AssertDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/AssignDerived.java b/src/org/python/antlr/ast/AssignDerived.java --- a/src/org/python/antlr/ast/AssignDerived.java +++ b/src/org/python/antlr/ast/AssignDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/AttributeDerived.java b/src/org/python/antlr/ast/AttributeDerived.java --- a/src/org/python/antlr/ast/AttributeDerived.java +++ b/src/org/python/antlr/ast/AttributeDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/AugAssignDerived.java b/src/org/python/antlr/ast/AugAssignDerived.java --- a/src/org/python/antlr/ast/AugAssignDerived.java +++ b/src/org/python/antlr/ast/AugAssignDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/BinOpDerived.java b/src/org/python/antlr/ast/BinOpDerived.java --- a/src/org/python/antlr/ast/BinOpDerived.java +++ b/src/org/python/antlr/ast/BinOpDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/BoolOpDerived.java b/src/org/python/antlr/ast/BoolOpDerived.java --- a/src/org/python/antlr/ast/BoolOpDerived.java +++ b/src/org/python/antlr/ast/BoolOpDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/BreakDerived.java b/src/org/python/antlr/ast/BreakDerived.java --- a/src/org/python/antlr/ast/BreakDerived.java +++ b/src/org/python/antlr/ast/BreakDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/CallDerived.java b/src/org/python/antlr/ast/CallDerived.java --- a/src/org/python/antlr/ast/CallDerived.java +++ b/src/org/python/antlr/ast/CallDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ClassDefDerived.java b/src/org/python/antlr/ast/ClassDefDerived.java --- a/src/org/python/antlr/ast/ClassDefDerived.java +++ b/src/org/python/antlr/ast/ClassDefDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/CompareDerived.java b/src/org/python/antlr/ast/CompareDerived.java --- a/src/org/python/antlr/ast/CompareDerived.java +++ b/src/org/python/antlr/ast/CompareDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ContinueDerived.java b/src/org/python/antlr/ast/ContinueDerived.java --- a/src/org/python/antlr/ast/ContinueDerived.java +++ b/src/org/python/antlr/ast/ContinueDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/DeleteDerived.java b/src/org/python/antlr/ast/DeleteDerived.java --- a/src/org/python/antlr/ast/DeleteDerived.java +++ b/src/org/python/antlr/ast/DeleteDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/DictDerived.java b/src/org/python/antlr/ast/DictDerived.java --- a/src/org/python/antlr/ast/DictDerived.java +++ b/src/org/python/antlr/ast/DictDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/EllipsisDerived.java b/src/org/python/antlr/ast/EllipsisDerived.java --- a/src/org/python/antlr/ast/EllipsisDerived.java +++ b/src/org/python/antlr/ast/EllipsisDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ExceptHandlerDerived.java b/src/org/python/antlr/ast/ExceptHandlerDerived.java --- a/src/org/python/antlr/ast/ExceptHandlerDerived.java +++ b/src/org/python/antlr/ast/ExceptHandlerDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ExecDerived.java b/src/org/python/antlr/ast/ExecDerived.java --- a/src/org/python/antlr/ast/ExecDerived.java +++ b/src/org/python/antlr/ast/ExecDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ExprDerived.java b/src/org/python/antlr/ast/ExprDerived.java --- a/src/org/python/antlr/ast/ExprDerived.java +++ b/src/org/python/antlr/ast/ExprDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ExpressionDerived.java b/src/org/python/antlr/ast/ExpressionDerived.java --- a/src/org/python/antlr/ast/ExpressionDerived.java +++ b/src/org/python/antlr/ast/ExpressionDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ExtSliceDerived.java b/src/org/python/antlr/ast/ExtSliceDerived.java --- a/src/org/python/antlr/ast/ExtSliceDerived.java +++ b/src/org/python/antlr/ast/ExtSliceDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ForDerived.java b/src/org/python/antlr/ast/ForDerived.java --- a/src/org/python/antlr/ast/ForDerived.java +++ b/src/org/python/antlr/ast/ForDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/FunctionDefDerived.java b/src/org/python/antlr/ast/FunctionDefDerived.java --- a/src/org/python/antlr/ast/FunctionDefDerived.java +++ b/src/org/python/antlr/ast/FunctionDefDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/GeneratorExpDerived.java b/src/org/python/antlr/ast/GeneratorExpDerived.java --- a/src/org/python/antlr/ast/GeneratorExpDerived.java +++ b/src/org/python/antlr/ast/GeneratorExpDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/GlobalDerived.java b/src/org/python/antlr/ast/GlobalDerived.java --- a/src/org/python/antlr/ast/GlobalDerived.java +++ b/src/org/python/antlr/ast/GlobalDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/IfDerived.java b/src/org/python/antlr/ast/IfDerived.java --- a/src/org/python/antlr/ast/IfDerived.java +++ b/src/org/python/antlr/ast/IfDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/IfExpDerived.java b/src/org/python/antlr/ast/IfExpDerived.java --- a/src/org/python/antlr/ast/IfExpDerived.java +++ b/src/org/python/antlr/ast/IfExpDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ImportDerived.java b/src/org/python/antlr/ast/ImportDerived.java --- a/src/org/python/antlr/ast/ImportDerived.java +++ b/src/org/python/antlr/ast/ImportDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ImportFromDerived.java b/src/org/python/antlr/ast/ImportFromDerived.java --- a/src/org/python/antlr/ast/ImportFromDerived.java +++ b/src/org/python/antlr/ast/ImportFromDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/IndexDerived.java b/src/org/python/antlr/ast/IndexDerived.java --- a/src/org/python/antlr/ast/IndexDerived.java +++ b/src/org/python/antlr/ast/IndexDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/InteractiveDerived.java b/src/org/python/antlr/ast/InteractiveDerived.java --- a/src/org/python/antlr/ast/InteractiveDerived.java +++ b/src/org/python/antlr/ast/InteractiveDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/LambdaDerived.java b/src/org/python/antlr/ast/LambdaDerived.java --- a/src/org/python/antlr/ast/LambdaDerived.java +++ b/src/org/python/antlr/ast/LambdaDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ListCompDerived.java b/src/org/python/antlr/ast/ListCompDerived.java --- a/src/org/python/antlr/ast/ListCompDerived.java +++ b/src/org/python/antlr/ast/ListCompDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ListDerived.java b/src/org/python/antlr/ast/ListDerived.java --- a/src/org/python/antlr/ast/ListDerived.java +++ b/src/org/python/antlr/ast/ListDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ModuleDerived.java b/src/org/python/antlr/ast/ModuleDerived.java --- a/src/org/python/antlr/ast/ModuleDerived.java +++ b/src/org/python/antlr/ast/ModuleDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/NameDerived.java b/src/org/python/antlr/ast/NameDerived.java --- a/src/org/python/antlr/ast/NameDerived.java +++ b/src/org/python/antlr/ast/NameDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/NumDerived.java b/src/org/python/antlr/ast/NumDerived.java --- a/src/org/python/antlr/ast/NumDerived.java +++ b/src/org/python/antlr/ast/NumDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/PassDerived.java b/src/org/python/antlr/ast/PassDerived.java --- a/src/org/python/antlr/ast/PassDerived.java +++ b/src/org/python/antlr/ast/PassDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/PrintDerived.java b/src/org/python/antlr/ast/PrintDerived.java --- a/src/org/python/antlr/ast/PrintDerived.java +++ b/src/org/python/antlr/ast/PrintDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/RaiseDerived.java b/src/org/python/antlr/ast/RaiseDerived.java --- a/src/org/python/antlr/ast/RaiseDerived.java +++ b/src/org/python/antlr/ast/RaiseDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ReprDerived.java b/src/org/python/antlr/ast/ReprDerived.java --- a/src/org/python/antlr/ast/ReprDerived.java +++ b/src/org/python/antlr/ast/ReprDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/ReturnDerived.java b/src/org/python/antlr/ast/ReturnDerived.java --- a/src/org/python/antlr/ast/ReturnDerived.java +++ b/src/org/python/antlr/ast/ReturnDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/SliceDerived.java b/src/org/python/antlr/ast/SliceDerived.java --- a/src/org/python/antlr/ast/SliceDerived.java +++ b/src/org/python/antlr/ast/SliceDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/StrDerived.java b/src/org/python/antlr/ast/StrDerived.java --- a/src/org/python/antlr/ast/StrDerived.java +++ b/src/org/python/antlr/ast/StrDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/SubscriptDerived.java b/src/org/python/antlr/ast/SubscriptDerived.java --- a/src/org/python/antlr/ast/SubscriptDerived.java +++ b/src/org/python/antlr/ast/SubscriptDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/SuiteDerived.java b/src/org/python/antlr/ast/SuiteDerived.java --- a/src/org/python/antlr/ast/SuiteDerived.java +++ b/src/org/python/antlr/ast/SuiteDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/TryExceptDerived.java b/src/org/python/antlr/ast/TryExceptDerived.java --- a/src/org/python/antlr/ast/TryExceptDerived.java +++ b/src/org/python/antlr/ast/TryExceptDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/TryFinallyDerived.java b/src/org/python/antlr/ast/TryFinallyDerived.java --- a/src/org/python/antlr/ast/TryFinallyDerived.java +++ b/src/org/python/antlr/ast/TryFinallyDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/TupleDerived.java b/src/org/python/antlr/ast/TupleDerived.java --- a/src/org/python/antlr/ast/TupleDerived.java +++ b/src/org/python/antlr/ast/TupleDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/UnaryOpDerived.java b/src/org/python/antlr/ast/UnaryOpDerived.java --- a/src/org/python/antlr/ast/UnaryOpDerived.java +++ b/src/org/python/antlr/ast/UnaryOpDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/WhileDerived.java b/src/org/python/antlr/ast/WhileDerived.java --- a/src/org/python/antlr/ast/WhileDerived.java +++ b/src/org/python/antlr/ast/WhileDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/WithDerived.java b/src/org/python/antlr/ast/WithDerived.java --- a/src/org/python/antlr/ast/WithDerived.java +++ b/src/org/python/antlr/ast/WithDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/YieldDerived.java b/src/org/python/antlr/ast/YieldDerived.java --- a/src/org/python/antlr/ast/YieldDerived.java +++ b/src/org/python/antlr/ast/YieldDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/aliasDerived.java b/src/org/python/antlr/ast/aliasDerived.java --- a/src/org/python/antlr/ast/aliasDerived.java +++ b/src/org/python/antlr/ast/aliasDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/argumentsDerived.java b/src/org/python/antlr/ast/argumentsDerived.java --- a/src/org/python/antlr/ast/argumentsDerived.java +++ b/src/org/python/antlr/ast/argumentsDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/comprehensionDerived.java b/src/org/python/antlr/ast/comprehensionDerived.java --- a/src/org/python/antlr/ast/comprehensionDerived.java +++ b/src/org/python/antlr/ast/comprehensionDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/ast/keywordDerived.java b/src/org/python/antlr/ast/keywordDerived.java --- a/src/org/python/antlr/ast/keywordDerived.java +++ b/src/org/python/antlr/ast/keywordDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/AddDerived.java b/src/org/python/antlr/op/AddDerived.java --- a/src/org/python/antlr/op/AddDerived.java +++ b/src/org/python/antlr/op/AddDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/AndDerived.java b/src/org/python/antlr/op/AndDerived.java --- a/src/org/python/antlr/op/AndDerived.java +++ b/src/org/python/antlr/op/AndDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/AugLoadDerived.java b/src/org/python/antlr/op/AugLoadDerived.java --- a/src/org/python/antlr/op/AugLoadDerived.java +++ b/src/org/python/antlr/op/AugLoadDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/AugStoreDerived.java b/src/org/python/antlr/op/AugStoreDerived.java --- a/src/org/python/antlr/op/AugStoreDerived.java +++ b/src/org/python/antlr/op/AugStoreDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/BitAndDerived.java b/src/org/python/antlr/op/BitAndDerived.java --- a/src/org/python/antlr/op/BitAndDerived.java +++ b/src/org/python/antlr/op/BitAndDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/BitOrDerived.java b/src/org/python/antlr/op/BitOrDerived.java --- a/src/org/python/antlr/op/BitOrDerived.java +++ b/src/org/python/antlr/op/BitOrDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/BitXorDerived.java b/src/org/python/antlr/op/BitXorDerived.java --- a/src/org/python/antlr/op/BitXorDerived.java +++ b/src/org/python/antlr/op/BitXorDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/DelDerived.java b/src/org/python/antlr/op/DelDerived.java --- a/src/org/python/antlr/op/DelDerived.java +++ b/src/org/python/antlr/op/DelDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/DivDerived.java b/src/org/python/antlr/op/DivDerived.java --- a/src/org/python/antlr/op/DivDerived.java +++ b/src/org/python/antlr/op/DivDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/EqDerived.java b/src/org/python/antlr/op/EqDerived.java --- a/src/org/python/antlr/op/EqDerived.java +++ b/src/org/python/antlr/op/EqDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/FloorDivDerived.java b/src/org/python/antlr/op/FloorDivDerived.java --- a/src/org/python/antlr/op/FloorDivDerived.java +++ b/src/org/python/antlr/op/FloorDivDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/GtDerived.java b/src/org/python/antlr/op/GtDerived.java --- a/src/org/python/antlr/op/GtDerived.java +++ b/src/org/python/antlr/op/GtDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/GtEDerived.java b/src/org/python/antlr/op/GtEDerived.java --- a/src/org/python/antlr/op/GtEDerived.java +++ b/src/org/python/antlr/op/GtEDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/InDerived.java b/src/org/python/antlr/op/InDerived.java --- a/src/org/python/antlr/op/InDerived.java +++ b/src/org/python/antlr/op/InDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/InvertDerived.java b/src/org/python/antlr/op/InvertDerived.java --- a/src/org/python/antlr/op/InvertDerived.java +++ b/src/org/python/antlr/op/InvertDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/IsDerived.java b/src/org/python/antlr/op/IsDerived.java --- a/src/org/python/antlr/op/IsDerived.java +++ b/src/org/python/antlr/op/IsDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/IsNotDerived.java b/src/org/python/antlr/op/IsNotDerived.java --- a/src/org/python/antlr/op/IsNotDerived.java +++ b/src/org/python/antlr/op/IsNotDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/LShiftDerived.java b/src/org/python/antlr/op/LShiftDerived.java --- a/src/org/python/antlr/op/LShiftDerived.java +++ b/src/org/python/antlr/op/LShiftDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/LoadDerived.java b/src/org/python/antlr/op/LoadDerived.java --- a/src/org/python/antlr/op/LoadDerived.java +++ b/src/org/python/antlr/op/LoadDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/LtDerived.java b/src/org/python/antlr/op/LtDerived.java --- a/src/org/python/antlr/op/LtDerived.java +++ b/src/org/python/antlr/op/LtDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/LtEDerived.java b/src/org/python/antlr/op/LtEDerived.java --- a/src/org/python/antlr/op/LtEDerived.java +++ b/src/org/python/antlr/op/LtEDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/ModDerived.java b/src/org/python/antlr/op/ModDerived.java --- a/src/org/python/antlr/op/ModDerived.java +++ b/src/org/python/antlr/op/ModDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/MultDerived.java b/src/org/python/antlr/op/MultDerived.java --- a/src/org/python/antlr/op/MultDerived.java +++ b/src/org/python/antlr/op/MultDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/NotDerived.java b/src/org/python/antlr/op/NotDerived.java --- a/src/org/python/antlr/op/NotDerived.java +++ b/src/org/python/antlr/op/NotDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/NotEqDerived.java b/src/org/python/antlr/op/NotEqDerived.java --- a/src/org/python/antlr/op/NotEqDerived.java +++ b/src/org/python/antlr/op/NotEqDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/NotInDerived.java b/src/org/python/antlr/op/NotInDerived.java --- a/src/org/python/antlr/op/NotInDerived.java +++ b/src/org/python/antlr/op/NotInDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/OrDerived.java b/src/org/python/antlr/op/OrDerived.java --- a/src/org/python/antlr/op/OrDerived.java +++ b/src/org/python/antlr/op/OrDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/ParamDerived.java b/src/org/python/antlr/op/ParamDerived.java --- a/src/org/python/antlr/op/ParamDerived.java +++ b/src/org/python/antlr/op/ParamDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/PowDerived.java b/src/org/python/antlr/op/PowDerived.java --- a/src/org/python/antlr/op/PowDerived.java +++ b/src/org/python/antlr/op/PowDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/RShiftDerived.java b/src/org/python/antlr/op/RShiftDerived.java --- a/src/org/python/antlr/op/RShiftDerived.java +++ b/src/org/python/antlr/op/RShiftDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/StoreDerived.java b/src/org/python/antlr/op/StoreDerived.java --- a/src/org/python/antlr/op/StoreDerived.java +++ b/src/org/python/antlr/op/StoreDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/SubDerived.java b/src/org/python/antlr/op/SubDerived.java --- a/src/org/python/antlr/op/SubDerived.java +++ b/src/org/python/antlr/op/SubDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/UAddDerived.java b/src/org/python/antlr/op/UAddDerived.java --- a/src/org/python/antlr/op/UAddDerived.java +++ b/src/org/python/antlr/op/UAddDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/antlr/op/USubDerived.java b/src/org/python/antlr/op/USubDerived.java --- a/src/org/python/antlr/op/USubDerived.java +++ b/src/org/python/antlr/op/USubDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/ClasspathPyImporterDerived.java b/src/org/python/core/ClasspathPyImporterDerived.java --- a/src/org/python/core/ClasspathPyImporterDerived.java +++ b/src/org/python/core/ClasspathPyImporterDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java --- a/src/org/python/core/Py.java +++ b/src/org/python/core/Py.java @@ -31,6 +31,7 @@ import org.python.antlr.base.mod; import org.python.core.adapter.ClassicPyObjectAdapter; import org.python.core.adapter.ExtensiblePyObjectAdapter; +import org.python.core.finalization.FinalizeTrigger; import org.python.modules.posix.PosixModule; import org.python.util.Generic; @@ -2291,7 +2292,7 @@ public PyObject __call__(PyObject[] args, String[] kws) { Object[] margs = new Object[]{args, kws}; try { - return Py.java2py(method.invoke(null, margs)); + return Py.java2py(method.invoke(null, margs)); } catch (Throwable t) { throw Py.JavaError(t); } diff --git a/src/org/python/core/PyArrayDerived.java b/src/org/python/core/PyArrayDerived.java --- a/src/org/python/core/PyArrayDerived.java +++ b/src/org/python/core/PyArrayDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyBaseExceptionDerived.java b/src/org/python/core/PyBaseExceptionDerived.java --- a/src/org/python/core/PyBaseExceptionDerived.java +++ b/src/org/python/core/PyBaseExceptionDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyByteArrayDerived.java b/src/org/python/core/PyByteArrayDerived.java --- a/src/org/python/core/PyByteArrayDerived.java +++ b/src/org/python/core/PyByteArrayDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyClass.java b/src/org/python/core/PyClass.java --- a/src/org/python/core/PyClass.java +++ b/src/org/python/core/PyClass.java @@ -190,12 +190,6 @@ if (__del__ != null) { inst.finalizeTrigger = FinalizeTrigger.makeTrigger(inst); } -// if (__del__ == null) { -// inst = new PyInstance(this); -// } else { -// // the class defined a __del__ method -// inst = new PyFinalizableInstance(this); -// } inst.__init__(args, keywords); return inst; } diff --git a/src/org/python/core/PyClassMethodDerived.java b/src/org/python/core/PyClassMethodDerived.java --- a/src/org/python/core/PyClassMethodDerived.java +++ b/src/org/python/core/PyClassMethodDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyComplexDerived.java b/src/org/python/core/PyComplexDerived.java --- a/src/org/python/core/PyComplexDerived.java +++ b/src/org/python/core/PyComplexDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyDictionaryDerived.java b/src/org/python/core/PyDictionaryDerived.java --- a/src/org/python/core/PyDictionaryDerived.java +++ b/src/org/python/core/PyDictionaryDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyEnumerateDerived.java b/src/org/python/core/PyEnumerateDerived.java --- a/src/org/python/core/PyEnumerateDerived.java +++ b/src/org/python/core/PyEnumerateDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyFile.java b/src/org/python/core/PyFile.java --- a/src/org/python/core/PyFile.java +++ b/src/org/python/core/PyFile.java @@ -683,7 +683,7 @@ } @Override - public void __del__Builtin() { + public void __del_builtin__() { if (closer != null) { closer.close(); } diff --git a/src/org/python/core/PyFileDerived.java b/src/org/python/core/PyFileDerived.java --- a/src/org/python/core/PyFileDerived.java +++ b/src/org/python/core/PyFileDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyFloatDerived.java b/src/org/python/core/PyFloatDerived.java --- a/src/org/python/core/PyFloatDerived.java +++ b/src/org/python/core/PyFloatDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyFrozenSetDerived.java b/src/org/python/core/PyFrozenSetDerived.java --- a/src/org/python/core/PyFrozenSetDerived.java +++ b/src/org/python/core/PyFrozenSetDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyGenerator.java b/src/org/python/core/PyGenerator.java --- a/src/org/python/core/PyGenerator.java +++ b/src/org/python/core/PyGenerator.java @@ -112,7 +112,7 @@ } @Override - public void __del__Builtin() { + public void __del_builtin__() { if (gi_frame == null || gi_frame.f_lasti == -1) { return; } diff --git a/src/org/python/core/PyInstance.java b/src/org/python/core/PyInstance.java --- a/src/org/python/core/PyInstance.java +++ b/src/org/python/core/PyInstance.java @@ -18,6 +18,7 @@ public static final PyType TYPE = PyType.fromClass(PyInstance.class); public FinalizeTrigger finalizeTrigger; + private static JavaFunc __ensure_finalizer__Function; // xxx doc, final name public transient PyClass instclass; @@ -29,9 +30,6 @@ public PyInstance() { super(TYPE); -// if (TYPE.needsFinalizer()) { -// finalizeTrigger = FinalizeTrigger.makeTrigger(this); -// } } public PyInstance(PyClass iclass, PyObject dict) { @@ -41,16 +39,10 @@ dict = new PyStringMap(); } __dict__ = dict; -// if (TYPE.needsFinalizer()) { -// finalizeTrigger = FinalizeTrigger.makeTrigger(this); -// } } public PyInstance(PyClass iclass) { this(iclass, null); -// if (TYPE.needsFinalizer()) { -// finalizeTrigger = FinalizeTrigger.makeTrigger(this); -// } } @ExposedNew @@ -161,9 +153,27 @@ return ifindfunction(name); } + public static void ensureFinalizer(PyObject[] args, String[] kws) { + FinalizeTrigger.ensureFinalizer((PyInstance) args[0]); + } + + private static JavaFunc makeFunction__ensure_finalizer__() { + try { + return new JavaFunc( + PyInstance.class.getMethod("ensureFinalizer", + PyObject[].class, String[].class)); + } catch (Exception e) {return null;} //cannot happen + } + protected PyObject ifindlocal(String name) { if (name == "__dict__") return __dict__; if (name == "__class__") return instclass; + if (name == "__ensure_finalizer__") { + if (__ensure_finalizer__Function == null) { + __ensure_finalizer__Function = makeFunction__ensure_finalizer__(); + } + return new PyMethod(__ensure_finalizer__Function, this, instclass); + } if (__dict__ == null) return null; return __dict__.__finditem__(name); @@ -1929,17 +1939,6 @@ return super.__ixor__(o); } - /* - public void ensureFinalizer() - { - instance_ensureFinalizer(); - } - - public void instance_ensureFinalizer() { - FinalizeTrigger.ensureFinalizer(this); - } - */ - @Override public void __del__() { try { diff --git a/src/org/python/core/PyIntegerDerived.java b/src/org/python/core/PyIntegerDerived.java --- a/src/org/python/core/PyIntegerDerived.java +++ b/src/org/python/core/PyIntegerDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyListDerived.java b/src/org/python/core/PyListDerived.java --- a/src/org/python/core/PyListDerived.java +++ b/src/org/python/core/PyListDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyLongDerived.java b/src/org/python/core/PyLongDerived.java --- a/src/org/python/core/PyLongDerived.java +++ b/src/org/python/core/PyLongDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyModuleDerived.java b/src/org/python/core/PyModuleDerived.java --- a/src/org/python/core/PyModuleDerived.java +++ b/src/org/python/core/PyModuleDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyObject.java b/src/org/python/core/PyObject.java --- a/src/org/python/core/PyObject.java +++ b/src/org/python/core/PyObject.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; +import org.python.core.finalization.FinalizeTrigger; import org.python.expose.ExposedClassMethod; import org.python.expose.ExposedDelete; import org.python.expose.ExposedGet; @@ -238,6 +239,12 @@ return __repr__(); } + @ExposedMethod + public void __ensure_finalizer__() { + //PyObjects that implement HasFinalizeTrigger shall implement this method via: + //FinalizeTrigger.ensureFinalizer(this); + } + public PyUnicode __unicode__() { return new PyUnicode(__str__()); } diff --git a/src/org/python/core/PyObjectDerived.java b/src/org/python/core/PyObjectDerived.java --- a/src/org/python/core/PyObjectDerived.java +++ b/src/org/python/core/PyObjectDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyPropertyDerived.java b/src/org/python/core/PyPropertyDerived.java --- a/src/org/python/core/PyPropertyDerived.java +++ b/src/org/python/core/PyPropertyDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PySetDerived.java b/src/org/python/core/PySetDerived.java --- a/src/org/python/core/PySetDerived.java +++ b/src/org/python/core/PySetDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyStringDerived.java b/src/org/python/core/PyStringDerived.java --- a/src/org/python/core/PyStringDerived.java +++ b/src/org/python/core/PyStringDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PySuperDerived.java b/src/org/python/core/PySuperDerived.java --- a/src/org/python/core/PySuperDerived.java +++ b/src/org/python/core/PySuperDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyTupleDerived.java b/src/org/python/core/PyTupleDerived.java --- a/src/org/python/core/PyTupleDerived.java +++ b/src/org/python/core/PyTupleDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyTypeDerived.java b/src/org/python/core/PyTypeDerived.java --- a/src/org/python/core/PyTypeDerived.java +++ b/src/org/python/core/PyTypeDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/PyUnicodeDerived.java b/src/org/python/core/PyUnicodeDerived.java --- a/src/org/python/core/PyUnicodeDerived.java +++ b/src/org/python/core/PyUnicodeDerived.java @@ -19,7 +19,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -27,7 +27,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/core/finalization/FinalizableBuiltin.java b/src/org/python/core/finalization/FinalizableBuiltin.java --- a/src/org/python/core/finalization/FinalizableBuiltin.java +++ b/src/org/python/core/finalization/FinalizableBuiltin.java @@ -6,13 +6,13 @@ public interface FinalizableBuiltin extends HasFinalizeTrigger { /** - * {@code __del__Builtin} is the built-in's own finalizer, while - * {@code __del__Derived} refers to an instance's in-dict {@code __del__}. - * A FinalizeTrigger calls {@code __del__Derived} first and - * - if existent - {@code __del__Builtin} after that. A plain {@code __del__} + * {@code __del_builtin__} is the built-in's own finalizer, while + * {@code __del_derived__} refers to an instance's in-dict {@code __del__}. + * A FinalizeTrigger calls {@code __del_derived__} first and + * - if existent - {@code __del_builtin__} after that. A plain {@code __del__} * would behave as overwritten by {@code __del__Derived}, i.e. won't be called * if the type implements {@code FinalizablePyObjectDerived} while - * {@code __del__Builtin} is called in any case. + * {@code __del_builtin__} is called in any case. */ - public void __del__Builtin(); + public void __del_builtin__(); } diff --git a/src/org/python/core/finalization/FinalizablePyObject.java b/src/org/python/core/finalization/FinalizablePyObject.java --- a/src/org/python/core/finalization/FinalizablePyObject.java +++ b/src/org/python/core/finalization/FinalizablePyObject.java @@ -9,17 +9,17 @@ *

* The difference is that {@code __del__} can be overwritten by a * new-style subclass's {@code __del__}-method on Python-side, while - * {@code __del__Builtin} is always called. If a Python-side - * finalizer exists, {@code __del__Builtin} will be called after the + * {@code __del_builtin__} is always called. If a Python-side + * finalizer exists, {@code __del_builtin__} will be called after the * Python-side finalizer has been processed. *

*

* One can even implement both interfaces. * If both interfaces are implemented, the {@code FinalizeTrigger} will - * call {@code __del__} first and then {@code __del__Builtin}. If a + * call {@code __del__} first and then {@code __del_builtin__}. If a * new-style subclass has an own, Python-side {@code __del__}-method, this * overwrites the Java-implemented {@code __del__}, but not - * {@code __del__Builtin}, which will be called after the Python-side + * {@code __del_builtin__}, which will be called after the Python-side * finalizer. *

*

@@ -60,14 +60,14 @@ * If your finalizer resurrects the object (Python allows this) and you wish the * finalizer to run again on next collection of the object:
* In the block where the resurrection occurs, let your {@code __del__}- or - * {@code __del__Builtin}-method call
+ * {@code __del_builtin__}-method call
* {@code FinalizeTrigger.ensureFinalizer(this);}. * * *

*

* Note: Regarding to object resurrection, Jython currently behaves like CPython >= 3.4. - * That means the finalizer {@code __del__} or {@code __del__Builtin} is called only the + * That means the finalizer {@code __del__} or {@code __del_builtin__} is called only the * first time an object gets gc'ed. If pre 3.4. behavior is required for some reason (i.e. * have the finalizer called repeatedly on every collection after a resurrection), one can * achieve this manually via step 5). @@ -75,7 +75,7 @@ *

* It is possible to switch finalization on and off at any desired time for a certain object. * This can be helpful if it is only necessary to have {@code __del__} or - * {@code __del__Builtin} called for certain configurations of an object. + * {@code __del_builtin__} called for certain configurations of an object. *

*

* To turn off the finalizer, call
diff --git a/src/org/python/core/finalization/FinalizablePyObjectDerived.java b/src/org/python/core/finalization/FinalizablePyObjectDerived.java --- a/src/org/python/core/finalization/FinalizablePyObjectDerived.java +++ b/src/org/python/core/finalization/FinalizablePyObjectDerived.java @@ -11,13 +11,13 @@ public interface FinalizablePyObjectDerived extends HasFinalizeTrigger { /** - * {@code __del__Builtin} is the built-in's own finalizer, while - * {@code __del__Derived} refers to an instance's in-dict {@code __del__}. - * A FinalizeTrigger calls {@code __del__Derived} first and - * - if existent - {@code __del__Builtin} after that. A plain {@code __del__} - * would behave as overwritten by {@code __del__Derived}, i.e. won't be called + * {@code __del_builtin__} is the built-in's own finalizer, while + * {@code __del_derived__} refers to an instance's in-dict {@code __del__}. + * A FinalizeTrigger calls {@code __del_derived__} first and + * - if existent - {@code __del_builtin__} after that. A plain {@code __del__} + * would behave as overwritten by {@code __del_derived__}, i.e. won't be called * if the type implements {@code FinalizablePyObjectDerived} while - * {@code __del__Builtin} is called in any case. + * {@code __del_builtin__} is called in any case. */ - public void __del__Derived(); + public void __del_derived__(); } diff --git a/src/org/python/core/finalization/FinalizeTrigger.java b/src/org/python/core/finalization/FinalizeTrigger.java --- a/src/org/python/core/finalization/FinalizeTrigger.java +++ b/src/org/python/core/finalization/FinalizeTrigger.java @@ -1,10 +1,6 @@ package org.python.core.finalization; import java.lang.reflect.Field; -import java.lang.ref.WeakReference; -import java.lang.ref.SoftReference; -import java.lang.ref.Reference; -import org.python.core.PyObject; /** * To use finalizers on {@code PyObject}s, read the documentation of @@ -26,16 +22,6 @@ } } - /* - public static FinalizeTrigger makeTriggerDerived(FinalizablePyObjectDerived toFinalize) { - if (factory != null) { - return factory.makeTriggerDerived(toFinalize); - } else { - return new FinalizeTriggerDerived(toFinalize); - } - } - */ - /** * Recreates the {@code FinalizeTrigger} of the given object. This makes sure that * once the resurrected object is gc'ed again, its {@code __del__}-method will be @@ -46,12 +32,6 @@ setFinalizeTrigger(resurrect, trigger); } - /* - public static void ensureFinalizerDerived(FinalizablePyObjectDerived resurrect) { - setFinalizeTrigger(resurrect, makeTriggerDerived(resurrect)); - } - */ - public static void setFinalizeTrigger(HasFinalizeTrigger toFinalize, FinalizeTrigger trigger) { Field triggerField; try { @@ -92,6 +72,7 @@ protected HasFinalizeTrigger toFinalize; + public void clear() { toFinalize = null; } @@ -108,31 +89,13 @@ protected void finalize() throws Throwable { if (toFinalize != null) { if (toFinalize instanceof FinalizablePyObjectDerived) { - ((FinalizablePyObjectDerived) toFinalize).__del__Derived(); + ((FinalizablePyObjectDerived) toFinalize).__del_derived__(); } else if (toFinalize instanceof FinalizablePyObject) { ((FinalizablePyObject) toFinalize).__del__(); } if (toFinalize instanceof FinalizableBuiltin) { - ((FinalizableBuiltin) toFinalize).__del__Builtin(); + ((FinalizableBuiltin) toFinalize).__del_builtin__(); } } } - - - /* - * A FinalizeTrigger variant that only calls __del__Derived, but not the - * built-in's finalizer __del__. It can be used to control finalization - * behavior of resurrected objects in more detail. - */ - /*protected static class FinalizeTriggerDerived extends FinalizeTrigger { - protected FinalizeTriggerDerived(FinalizablePyObjectDerived toFinalize) { - super(toFinalize); - } - - protected void finalize() throws Throwable { - if (toFinalize != null) { - ((FinalizablePyObjectDerived) toFinalize).__del__Derived(); - } - } - }*/ } diff --git a/src/org/python/modules/PyStructDerived.java b/src/org/python/modules/PyStructDerived.java --- a/src/org/python/modules/PyStructDerived.java +++ b/src/org/python/modules/PyStructDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/_collections/PyDefaultDictDerived.java b/src/org/python/modules/_collections/PyDefaultDictDerived.java --- a/src/org/python/modules/_collections/PyDefaultDictDerived.java +++ b/src/org/python/modules/_collections/PyDefaultDictDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/_collections/PyDequeDerived.java b/src/org/python/modules/_collections/PyDequeDerived.java --- a/src/org/python/modules/_collections/PyDequeDerived.java +++ b/src/org/python/modules/_collections/PyDequeDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/_csv/PyDialectDerived.java b/src/org/python/modules/_csv/PyDialectDerived.java --- a/src/org/python/modules/_csv/PyDialectDerived.java +++ b/src/org/python/modules/_csv/PyDialectDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/_functools/PyPartialDerived.java b/src/org/python/modules/_functools/PyPartialDerived.java --- a/src/org/python/modules/_functools/PyPartialDerived.java +++ b/src/org/python/modules/_functools/PyPartialDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/_io/PyFileIODerived.java b/src/org/python/modules/_io/PyFileIODerived.java --- a/src/org/python/modules/_io/PyFileIODerived.java +++ b/src/org/python/modules/_io/PyFileIODerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/_io/PyIOBase.java b/src/org/python/modules/_io/PyIOBase.java --- a/src/org/python/modules/_io/PyIOBase.java +++ b/src/org/python/modules/_io/PyIOBase.java @@ -732,7 +732,7 @@ } @Override - public void __del__Builtin() { + public void __del_builtin__() { closer.dismiss(); invoke("close"); } diff --git a/src/org/python/modules/_io/PyIOBaseDerived.java b/src/org/python/modules/_io/PyIOBaseDerived.java --- a/src/org/python/modules/_io/PyIOBaseDerived.java +++ b/src/org/python/modules/_io/PyIOBaseDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/_io/PyRawIOBaseDerived.java b/src/org/python/modules/_io/PyRawIOBaseDerived.java --- a/src/org/python/modules/_io/PyRawIOBaseDerived.java +++ b/src/org/python/modules/_io/PyRawIOBaseDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/_weakref/ReferenceTypeDerived.java b/src/org/python/modules/_weakref/ReferenceTypeDerived.java --- a/src/org/python/modules/_weakref/ReferenceTypeDerived.java +++ b/src/org/python/modules/_weakref/ReferenceTypeDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/bz2/PyBZ2File.java b/src/org/python/modules/bz2/PyBZ2File.java --- a/src/org/python/modules/bz2/PyBZ2File.java +++ b/src/org/python/modules/bz2/PyBZ2File.java @@ -76,7 +76,7 @@ } @Override - public void __del__Builtin() { + public void __del_builtin__() { BZ2File_close(); } diff --git a/src/org/python/modules/bz2/PyBZ2FileDerived.java b/src/org/python/modules/bz2/PyBZ2FileDerived.java --- a/src/org/python/modules/bz2/PyBZ2FileDerived.java +++ b/src/org/python/modules/bz2/PyBZ2FileDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/PyTeeIteratorDerived.java b/src/org/python/modules/itertools/PyTeeIteratorDerived.java --- a/src/org/python/modules/itertools/PyTeeIteratorDerived.java +++ b/src/org/python/modules/itertools/PyTeeIteratorDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/chainDerived.java b/src/org/python/modules/itertools/chainDerived.java --- a/src/org/python/modules/itertools/chainDerived.java +++ b/src/org/python/modules/itertools/chainDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/combinationsDerived.java b/src/org/python/modules/itertools/combinationsDerived.java --- a/src/org/python/modules/itertools/combinationsDerived.java +++ b/src/org/python/modules/itertools/combinationsDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java --- a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java +++ b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/compressDerived.java b/src/org/python/modules/itertools/compressDerived.java --- a/src/org/python/modules/itertools/compressDerived.java +++ b/src/org/python/modules/itertools/compressDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/countDerived.java b/src/org/python/modules/itertools/countDerived.java --- a/src/org/python/modules/itertools/countDerived.java +++ b/src/org/python/modules/itertools/countDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/cycleDerived.java b/src/org/python/modules/itertools/cycleDerived.java --- a/src/org/python/modules/itertools/cycleDerived.java +++ b/src/org/python/modules/itertools/cycleDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/dropwhileDerived.java b/src/org/python/modules/itertools/dropwhileDerived.java --- a/src/org/python/modules/itertools/dropwhileDerived.java +++ b/src/org/python/modules/itertools/dropwhileDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/groupbyDerived.java b/src/org/python/modules/itertools/groupbyDerived.java --- a/src/org/python/modules/itertools/groupbyDerived.java +++ b/src/org/python/modules/itertools/groupbyDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/ifilterDerived.java b/src/org/python/modules/itertools/ifilterDerived.java --- a/src/org/python/modules/itertools/ifilterDerived.java +++ b/src/org/python/modules/itertools/ifilterDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/ifilterfalseDerived.java b/src/org/python/modules/itertools/ifilterfalseDerived.java --- a/src/org/python/modules/itertools/ifilterfalseDerived.java +++ b/src/org/python/modules/itertools/ifilterfalseDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/isliceDerived.java b/src/org/python/modules/itertools/isliceDerived.java --- a/src/org/python/modules/itertools/isliceDerived.java +++ b/src/org/python/modules/itertools/isliceDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/izipDerived.java b/src/org/python/modules/itertools/izipDerived.java --- a/src/org/python/modules/itertools/izipDerived.java +++ b/src/org/python/modules/itertools/izipDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/izipLongestDerived.java b/src/org/python/modules/itertools/izipLongestDerived.java --- a/src/org/python/modules/itertools/izipLongestDerived.java +++ b/src/org/python/modules/itertools/izipLongestDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/permutationsDerived.java b/src/org/python/modules/itertools/permutationsDerived.java --- a/src/org/python/modules/itertools/permutationsDerived.java +++ b/src/org/python/modules/itertools/permutationsDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/productDerived.java b/src/org/python/modules/itertools/productDerived.java --- a/src/org/python/modules/itertools/productDerived.java +++ b/src/org/python/modules/itertools/productDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/repeatDerived.java b/src/org/python/modules/itertools/repeatDerived.java --- a/src/org/python/modules/itertools/repeatDerived.java +++ b/src/org/python/modules/itertools/repeatDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/starmapDerived.java b/src/org/python/modules/itertools/starmapDerived.java --- a/src/org/python/modules/itertools/starmapDerived.java +++ b/src/org/python/modules/itertools/starmapDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/itertools/takewhileDerived.java b/src/org/python/modules/itertools/takewhileDerived.java --- a/src/org/python/modules/itertools/takewhileDerived.java +++ b/src/org/python/modules/itertools/takewhileDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/random/PyRandomDerived.java b/src/org/python/modules/random/PyRandomDerived.java --- a/src/org/python/modules/random/PyRandomDerived.java +++ b/src/org/python/modules/random/PyRandomDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/thread/PyLocalDerived.java b/src/org/python/modules/thread/PyLocalDerived.java --- a/src/org/python/modules/thread/PyLocalDerived.java +++ b/src/org/python/modules/thread/PyLocalDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/org/python/modules/zipimport/zipimporterDerived.java b/src/org/python/modules/zipimport/zipimporterDerived.java --- a/src/org/python/modules/zipimport/zipimporterDerived.java +++ b/src/org/python/modules/zipimport/zipimporterDerived.java @@ -20,7 +20,7 @@ private PyObject[]slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type=getType(); PyObject impl=self_type.lookup("__del__"); if (impl!=null) { @@ -28,7 +28,7 @@ } } - public void ensureFinalizer() { + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/templates/gderived-defs b/src/templates/gderived-defs --- a/src/templates/gderived-defs +++ b/src/templates/gderived-defs @@ -20,15 +20,15 @@ private PyObject[] slots; - public void __del__Derived() { + public void __del_derived__() { PyType self_type = getType(); PyObject impl = self_type.lookup("__del__"); if (impl != null) { impl.__get__(this, self_type).__call__(); } } - - public void ensureFinalizer() { + + public void __ensure_finalizer__() { FinalizeTrigger.ensureFinalizer(this); } diff --git a/src/templates/object.derived b/src/templates/object.derived --- a/src/templates/object.derived +++ b/src/templates/object.derived @@ -431,4 +431,3 @@ } return super.__coerce_ex__(o); } - -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Thu Sep 4 06:35:38 2014 From: jython-checkins at python.org (jim.baker) Date: Thu, 4 Sep 2014 06:35:38 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Removed_the_dead_import_in_?= =?utf-8?q?Py=2Ejava_and_replaced_various_tab_indentations_by?= Message-ID: <3hpTj66M83z7LkR@mail.python.org> http://hg.python.org/jython/rev/5397c1f405c5 changeset: 7362:5397c1f405c5 user: Stefan Richthofer date: Tue Aug 26 14:35:57 2014 +0200 summary: Removed the dead import in Py.java and replaced various tab indentations by spaces. Beneath the one I accidentally caused when I had inserted some tmporarily debugging output, the search-and-replace fixed this for 21 other occurences too. files: src/org/python/core/Py.java | 41 ++++++++++++------------ 1 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java --- a/src/org/python/core/Py.java +++ b/src/org/python/core/Py.java @@ -31,7 +31,6 @@ import org.python.antlr.base.mod; import org.python.core.adapter.ClassicPyObjectAdapter; import org.python.core.adapter.ExtensiblePyObjectAdapter; -import org.python.core.finalization.FinalizeTrigger; import org.python.modules.posix.PosixModule; import org.python.util.Generic; @@ -838,27 +837,27 @@ * @throws ClassNotFoundException if the class wasn't found by the class loader */ private static Class findClassInternal(String name, String reason) throws ClassNotFoundException { - ClassLoader classLoader = Py.getSystemState().getClassLoader(); + ClassLoader classLoader = Py.getSystemState().getClassLoader(); if (classLoader != null) { - if (reason != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in sys.classLoader"); - } + if (reason != null) { + writeDebug("import", "trying " + name + " as " + reason + + " in sys.classLoader"); + } return loadAndInitClass(name, classLoader); } if (!syspathJavaLoaderRestricted) { try { classLoader = imp.getSyspathJavaLoader(); if (classLoader != null && reason != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in SysPathJavaLoader"); + writeDebug("import", "trying " + name + " as " + reason + + " in SysPathJavaLoader"); } } catch (SecurityException e) { syspathJavaLoaderRestricted = true; } } if (syspathJavaLoaderRestricted) { - classLoader = imp.getParentClassLoader(); + classLoader = imp.getParentClassLoader(); if (classLoader != null && reason != null) { writeDebug("import", "trying " + name + " as " + reason + " in Jython's parent class loader"); @@ -866,20 +865,20 @@ } if (classLoader != null) { try { - return loadAndInitClass(name, classLoader); + return loadAndInitClass(name, classLoader); } catch (ClassNotFoundException cnfe) { // let the default classloader try - // XXX: by trying another classloader that may not be on a - // parent/child relationship with the Jython's parent - // classsloader we are risking some nasty class loading - // problems (such as having two incompatible copies for - // the same class that is itself a dependency of two - // classes loaded from these two different class loaders) + // XXX: by trying another classloader that may not be on a + // parent/child relationship with the Jython's parent + // classsloader we are risking some nasty class loading + // problems (such as having two incompatible copies for + // the same class that is itself a dependency of two + // classes loaded from these two different class loaders) } } if (reason != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in context class loader, for backwards compatibility"); + writeDebug("import", "trying " + name + " as " + reason + + " in context class loader, for backwards compatibility"); } return loadAndInitClass(name, Thread.currentThread().getContextClassLoader()); } @@ -891,7 +890,7 @@ */ public static Class findClass(String name) { try { - return findClassInternal(name, null); + return findClassInternal(name, null); } catch (ClassNotFoundException e) { // e.printStackTrace(); return null; @@ -931,7 +930,7 @@ // We *need* to initialize classes on findClass/findClassEx, so that import // statements can trigger static initializers private static Class loadAndInitClass(String name, ClassLoader loader) throws ClassNotFoundException { - return Class.forName(name, true, loader); + return Class.forName(name, true, loader); } @@ -2292,7 +2291,7 @@ public PyObject __call__(PyObject[] args, String[] kws) { Object[] margs = new Object[]{args, kws}; try { - return Py.java2py(method.invoke(null, margs)); + return Py.java2py(method.invoke(null, margs)); } catch (Throwable t) { throw Py.JavaError(t); } -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Thu Sep 4 06:35:42 2014 From: jython-checkins at python.org (jim.baker) Date: Thu, 4 Sep 2014 06:35:42 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython_=28merge_default_-=3E_default?= =?utf-8?q?=29=3A_Merged_finalization_support_for_newstyle_classes?= Message-ID: <3hpTjB1LqBz7Ljn@mail.python.org> http://hg.python.org/jython/rev/61081b8859c1 changeset: 7363:61081b8859c1 parent: 7359:83cd10f1826d parent: 7362:5397c1f405c5 user: Jim Baker date: Tue Aug 26 22:51:33 2014 -0600 summary: Merged finalization support for newstyle classes files: Lib/test/test_finalizers.py | 418 ++++++++++ src/org/python/antlr/ast/AssertDerived.java | 26 +- src/org/python/antlr/ast/AssignDerived.java | 26 +- src/org/python/antlr/ast/AttributeDerived.java | 26 +- src/org/python/antlr/ast/AugAssignDerived.java | 26 +- src/org/python/antlr/ast/BinOpDerived.java | 26 +- src/org/python/antlr/ast/BoolOpDerived.java | 26 +- src/org/python/antlr/ast/BreakDerived.java | 26 +- src/org/python/antlr/ast/CallDerived.java | 26 +- src/org/python/antlr/ast/ClassDefDerived.java | 26 +- src/org/python/antlr/ast/CompareDerived.java | 26 +- src/org/python/antlr/ast/ContinueDerived.java | 26 +- src/org/python/antlr/ast/DeleteDerived.java | 26 +- src/org/python/antlr/ast/DictDerived.java | 26 +- src/org/python/antlr/ast/EllipsisDerived.java | 26 +- src/org/python/antlr/ast/ExceptHandlerDerived.java | 26 +- src/org/python/antlr/ast/ExecDerived.java | 26 +- src/org/python/antlr/ast/ExprDerived.java | 26 +- src/org/python/antlr/ast/ExpressionDerived.java | 26 +- src/org/python/antlr/ast/ExtSliceDerived.java | 26 +- src/org/python/antlr/ast/ForDerived.java | 26 +- src/org/python/antlr/ast/FunctionDefDerived.java | 26 +- src/org/python/antlr/ast/GeneratorExpDerived.java | 26 +- src/org/python/antlr/ast/GlobalDerived.java | 26 +- src/org/python/antlr/ast/IfDerived.java | 26 +- src/org/python/antlr/ast/IfExpDerived.java | 26 +- src/org/python/antlr/ast/ImportDerived.java | 26 +- src/org/python/antlr/ast/ImportFromDerived.java | 26 +- src/org/python/antlr/ast/IndexDerived.java | 26 +- src/org/python/antlr/ast/InteractiveDerived.java | 26 +- src/org/python/antlr/ast/LambdaDerived.java | 26 +- src/org/python/antlr/ast/ListCompDerived.java | 26 +- src/org/python/antlr/ast/ListDerived.java | 26 +- src/org/python/antlr/ast/ModuleDerived.java | 26 +- src/org/python/antlr/ast/NameDerived.java | 26 +- src/org/python/antlr/ast/NumDerived.java | 26 +- src/org/python/antlr/ast/PassDerived.java | 26 +- src/org/python/antlr/ast/PrintDerived.java | 26 +- src/org/python/antlr/ast/RaiseDerived.java | 26 +- src/org/python/antlr/ast/ReprDerived.java | 26 +- src/org/python/antlr/ast/ReturnDerived.java | 26 +- src/org/python/antlr/ast/SliceDerived.java | 26 +- src/org/python/antlr/ast/StrDerived.java | 26 +- src/org/python/antlr/ast/SubscriptDerived.java | 26 +- src/org/python/antlr/ast/SuiteDerived.java | 26 +- src/org/python/antlr/ast/TryExceptDerived.java | 26 +- src/org/python/antlr/ast/TryFinallyDerived.java | 26 +- src/org/python/antlr/ast/TupleDerived.java | 26 +- src/org/python/antlr/ast/UnaryOpDerived.java | 26 +- src/org/python/antlr/ast/WhileDerived.java | 26 +- src/org/python/antlr/ast/WithDerived.java | 26 +- src/org/python/antlr/ast/YieldDerived.java | 26 +- src/org/python/antlr/ast/aliasDerived.java | 26 +- src/org/python/antlr/ast/argumentsDerived.java | 26 +- src/org/python/antlr/ast/comprehensionDerived.java | 26 +- src/org/python/antlr/ast/keywordDerived.java | 26 +- src/org/python/antlr/op/AddDerived.java | 26 +- src/org/python/antlr/op/AndDerived.java | 26 +- src/org/python/antlr/op/AugLoadDerived.java | 26 +- src/org/python/antlr/op/AugStoreDerived.java | 26 +- src/org/python/antlr/op/BitAndDerived.java | 26 +- src/org/python/antlr/op/BitOrDerived.java | 26 +- src/org/python/antlr/op/BitXorDerived.java | 26 +- src/org/python/antlr/op/DelDerived.java | 26 +- src/org/python/antlr/op/DivDerived.java | 26 +- src/org/python/antlr/op/EqDerived.java | 26 +- src/org/python/antlr/op/FloorDivDerived.java | 26 +- src/org/python/antlr/op/GtDerived.java | 26 +- src/org/python/antlr/op/GtEDerived.java | 26 +- src/org/python/antlr/op/InDerived.java | 26 +- src/org/python/antlr/op/InvertDerived.java | 26 +- src/org/python/antlr/op/IsDerived.java | 26 +- src/org/python/antlr/op/IsNotDerived.java | 26 +- src/org/python/antlr/op/LShiftDerived.java | 26 +- src/org/python/antlr/op/LoadDerived.java | 26 +- src/org/python/antlr/op/LtDerived.java | 26 +- src/org/python/antlr/op/LtEDerived.java | 26 +- src/org/python/antlr/op/ModDerived.java | 26 +- src/org/python/antlr/op/MultDerived.java | 26 +- src/org/python/antlr/op/NotDerived.java | 26 +- src/org/python/antlr/op/NotEqDerived.java | 26 +- src/org/python/antlr/op/NotInDerived.java | 26 +- src/org/python/antlr/op/OrDerived.java | 26 +- src/org/python/antlr/op/ParamDerived.java | 26 +- src/org/python/antlr/op/PowDerived.java | 26 +- src/org/python/antlr/op/RShiftDerived.java | 26 +- src/org/python/antlr/op/StoreDerived.java | 26 +- src/org/python/antlr/op/SubDerived.java | 26 +- src/org/python/antlr/op/UAddDerived.java | 26 +- src/org/python/antlr/op/USubDerived.java | 26 +- src/org/python/core/ClasspathPyImporterDerived.java | 23 +- src/org/python/core/Py.java | 38 +- src/org/python/core/PyArrayDerived.java | 26 +- src/org/python/core/PyBaseExceptionDerived.java | 23 +- src/org/python/core/PyByteArrayDerived.java | 26 +- src/org/python/core/PyClass.java | 9 +- src/org/python/core/PyClassMethodDerived.java | 26 +- src/org/python/core/PyComplexDerived.java | 26 +- src/org/python/core/PyDictionaryDerived.java | 26 +- src/org/python/core/PyEnumerateDerived.java | 26 +- src/org/python/core/PyFile.java | 16 +- src/org/python/core/PyFileDerived.java | 26 +- src/org/python/core/PyFinalizableInstance.java | 37 - src/org/python/core/PyFloatDerived.java | 26 +- src/org/python/core/PyFrozenSetDerived.java | 26 +- src/org/python/core/PyGenerator.java | 13 +- src/org/python/core/PyInstance.java | 52 +- src/org/python/core/PyIntegerDerived.java | 26 +- src/org/python/core/PyListDerived.java | 26 +- src/org/python/core/PyLongDerived.java | 26 +- src/org/python/core/PyModuleDerived.java | 23 +- src/org/python/core/PyObject.java | 22 + src/org/python/core/PyObjectDerived.java | 26 +- src/org/python/core/PyPropertyDerived.java | 26 +- src/org/python/core/PySetDerived.java | 26 +- src/org/python/core/PyStringDerived.java | 26 +- src/org/python/core/PySuperDerived.java | 26 +- src/org/python/core/PyTupleDerived.java | 26 +- src/org/python/core/PyType.java | 22 +- src/org/python/core/PyTypeDerived.java | 23 +- src/org/python/core/PyUnicodeDerived.java | 26 +- src/org/python/core/finalization/FinalizableBuiltin.java | 18 + src/org/python/core/finalization/FinalizablePyObject.java | 90 ++ src/org/python/core/finalization/FinalizablePyObjectDerived.java | 23 + src/org/python/core/finalization/FinalizeTrigger.java | 101 ++ src/org/python/core/finalization/FinalizeTriggerFactory.java | 6 + src/org/python/core/finalization/HasFinalizeTrigger.java | 13 + src/org/python/core/finalization/PyFinalizableObject.java | 17 + src/org/python/modules/PyStructDerived.java | 26 +- src/org/python/modules/_collections/PyDefaultDictDerived.java | 26 +- src/org/python/modules/_collections/PyDequeDerived.java | 26 +- src/org/python/modules/_csv/PyDialectDerived.java | 23 +- src/org/python/modules/_functools/PyPartialDerived.java | 26 +- src/org/python/modules/_io/PyFileIODerived.java | 23 +- src/org/python/modules/_io/PyIOBase.java | 11 +- src/org/python/modules/_io/PyIOBaseDerived.java | 23 +- src/org/python/modules/_io/PyRawIOBaseDerived.java | 23 +- src/org/python/modules/_weakref/ReferenceTypeDerived.java | 26 +- src/org/python/modules/bz2/PyBZ2CompressorDerived.java | 26 +- src/org/python/modules/bz2/PyBZ2DecompressorDerived.java | 26 +- src/org/python/modules/bz2/PyBZ2File.java | 13 +- src/org/python/modules/bz2/PyBZ2FileDerived.java | 26 +- src/org/python/modules/itertools/PyTeeIteratorDerived.java | 26 +- src/org/python/modules/itertools/chainDerived.java | 26 +- src/org/python/modules/itertools/combinationsDerived.java | 26 +- src/org/python/modules/itertools/combinationsWithReplacementDerived.java | 26 +- src/org/python/modules/itertools/compressDerived.java | 26 +- src/org/python/modules/itertools/countDerived.java | 26 +- src/org/python/modules/itertools/cycleDerived.java | 26 +- src/org/python/modules/itertools/dropwhileDerived.java | 26 +- src/org/python/modules/itertools/groupbyDerived.java | 26 +- src/org/python/modules/itertools/ifilterDerived.java | 26 +- src/org/python/modules/itertools/ifilterfalseDerived.java | 26 +- src/org/python/modules/itertools/isliceDerived.java | 26 +- src/org/python/modules/itertools/izipDerived.java | 26 +- src/org/python/modules/itertools/izipLongestDerived.java | 26 +- src/org/python/modules/itertools/permutationsDerived.java | 26 +- src/org/python/modules/itertools/productDerived.java | 26 +- src/org/python/modules/itertools/repeatDerived.java | 26 +- src/org/python/modules/itertools/starmapDerived.java | 26 +- src/org/python/modules/itertools/takewhileDerived.java | 26 +- src/org/python/modules/random/PyRandomDerived.java | 26 +- src/org/python/modules/thread/PyLocalDerived.java | 23 +- src/org/python/modules/zipimport/zipimporterDerived.java | 26 +- src/templates/gderived-defs | 26 +- src/templates/gderived.py | 125 +- src/templates/object.derived | 3 +- 167 files changed, 4553 insertions(+), 289 deletions(-) diff --git a/Lib/test/test_finalizers.py b/Lib/test/test_finalizers.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_finalizers.py @@ -0,0 +1,418 @@ +''' +Created on 06.08.2014 +''' + +import unittest +import types +import time +try: + from java.lang import System +except: + pass + +class GCDetector(): + gcIndex = 0 + + def __del__(self): + GCDetector.gcIndex += 1 + +maxGCRun = 10 + +def runGCIfJython(): + try: + currentIndex = GCDetector.gcIndex + gcCount = 0 + detector = GCDetector() + detector = None + while currentIndex == GCDetector.gcIndex and gcCount < maxGCRun: + System.gc() + gcCount += 1 + time.sleep(0.1) + except: + pass + +finalizeMsgList = [] +verbose = False +resurrectedObject_I = None +resurrectedObject_J = None +resurrectedObject_K = None +resurrectedObject_L = None +resurrectedObject_M = None +resurrectedObject_N = None + +class ResurrectableDummyClass(): + + def __init__(self, name): + self.name = name + self.doResurrection = True + + def __str__(self): + return self.name + + +class ResurrectableDummyClassNew(object): + + def __init__(self, name): + self.name = name + self.doResurrection = True + + def __str__(self): + return self.name + + +def __del__I(self): + global resurrectedObject_I + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_I = self + +def __del__J(self): + global resurrectedObject_J + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_J = self + +def __del__K(self): + global resurrectedObject_K + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_K = self + +def __del__L(self): + global resurrectedObject_L + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_L = self + +def __del__M(self): + global resurrectedObject_M + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_M = self + +def __del__N(self): + global resurrectedObject_N + finalizeMsgList.append(str(self)+" finalized (ResurrectableDummyClass)") + if verbose: + print str(self)+" finalized (ResurrectableDummyClass)" + if self.doResurrection: + resurrectedObject_N = self + +delI = __del__I +delJ = __del__J +delK = __del__K +delL = __del__L +delM = __del__M +delN = __del__N + + +class DummyClass(): + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + +class DummyClassDel(): + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyClassDel)") + if verbose: + print str(self)+" finalized (DummyClassDel)" + + +class DummyClassNew(object): + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + +class DummyClassDelNew(object): + + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyClassDelNew)") + if verbose: + print str(self)+" finalized (DummyClassDelNew)" + +class DummyFileClassNew(file): + + def __init__(self, name): + self.name0 = name + + def __str__(self): + return self.name0 + + def __del__(self): + finalizeMsgList.append(str(self)+" finalized (DummyFileClassNew)") + if verbose: + print str(self)+" finalized (DummyFileClassNew)" + + +def __del__class(self): + finalizeMsgList.append(str(self)+" finalized (acquired by class)") + if verbose: + print str(self)+" finalized (acquired by class)" + +def __del__object(self): + finalizeMsgList.append(str(self)+" finalized (acquired by object)") + if verbose: + print str(self)+" finalized (acquired by object)" + +def __del__object0(): + finalizeMsgList.append("_ finalized (acquired by object)") + if verbose: + print "_ finalized (acquired by object)" + +delClass = __del__class +delObject = __del__object +delObject0 = __del__object0 + +class TestFinalizers(unittest.TestCase): + def test_finalizer_builtin_oldStyleClass(self): + A = DummyClassDel("A") + A = None + runGCIfJython() + assert("A finalized (DummyClassDel)" in finalizeMsgList) + + def test_classAcquiresFinalizer_beforeInstanciation_oldStyleClass(self): + DummyClass.__del__ = delClass + B = DummyClass("B") + B = None + runGCIfJython() + assert("B finalized (acquired by class)" in finalizeMsgList) + del DummyClass.__del__ + + def test_classAcquiresFinalizer_afterInstanciation_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer call + C = DummyClass("C") + DummyClass.__del__ = delClass + try: + C.__ensure_finalizer__() + except: + pass + C = None + runGCIfJython() + assert("C finalized (acquired by class)" in finalizeMsgList) + del DummyClass.__del__ + + def test_instanceAcquiresFinalizer_bound_oldStyleClass(self): + D = DummyClassDel("D") + dl = types.MethodType(delObject, D.name) + D.__del__ = dl + D = None + runGCIfJython() + assert("D finalized (DummyClassDel)" not in finalizeMsgList) + assert("D finalized (acquired by object)" in finalizeMsgList) + + def test_finalizer_builtin_newStyleClass(self): + E = DummyClassDelNew("E") + E = None + runGCIfJython() + assert("E finalized (DummyClassDelNew)" in finalizeMsgList) + + def test_classAcquiresFinalizer_beforeInstanciation_newStyleClass(self): + DummyClassNew.__del__ = delClass + F = DummyClassNew("F") + F = None + runGCIfJython() + assert("F finalized (acquired by class)" in finalizeMsgList) + del DummyClassNew.__del__ + + def test_classAcquiresFinalizer_afterInstanciation_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer call + G = DummyClassNew("G") + DummyClassNew.__del__ = delClass + try: + G.__ensure_finalizer__() + except: + pass + G = None + runGCIfJython() + assert("G finalized (acquired by class)" in finalizeMsgList) + del DummyClassNew.__del__ + + def test_instanceAcquiresFinalizer_bound_newStyleClass(self): + """ + It seems, CPython prohibits new style instances from acquiring a finalizer. + """ + H = DummyClassDelNew("H") + H.__del__ = types.MethodType(delObject, H.name) + H = None + runGCIfJython() + assert("H finalized (DummyClassDelNew)" in finalizeMsgList) + assert("H finalized (acquired by object)" not in finalizeMsgList) + + def test_instanceAcquiresFinalizer_bound_newStyleClass2(self): + """ + It seems, CPython prohibits new style instances from acquiring a finalizer. + If one calls the instance-acquired __del__ manually, it works, but the gc + will still call the old one. + """ + H = DummyClassDelNew("H2") + H.__del__ = types.MethodType(delObject, H.name) + H.__del__() + H = None + runGCIfJython() + assert("H2 finalized (DummyClassDelNew)" in finalizeMsgList) + assert("H2 finalized (acquired by object)" in finalizeMsgList) + + def test_objectResurrection_oldStyleClass(self): + ResurrectableDummyClass.__del__ = delI + I = ResurrectableDummyClass("I") + I = None + runGCIfJython() + assert("I finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_I) == "I") + + def test_objectDoubleResurrection_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClass.__del__ = delJ + J = ResurrectableDummyClass("J") + J = None + + runGCIfJython() + assert("J finalized (ResurrectableDummyClass)" in finalizeMsgList) + global resurrectedObject_J + assert(str(resurrectedObject_J) == "J") + J = resurrectedObject_J + resurrectedObject_J = None + assert(resurrectedObject_J is None) + try: + #For Jython one can restore the finalizer manually. + #This is offered as an easy fix if the CPython behavior + #in this test should be needed for some reason. + J.__ensure_finalizer__() + except: + pass + J = None + + runGCIfJython() + assert(str(resurrectedObject_J) == "J") + resurrectedObject_J.doResurrection = False + try: + #again... + resurrectedObject_J.__ensure_finalizer__() + except: + pass + resurrectedObject_J = None + + runGCIfJython() + assert(resurrectedObject_J is None) + + + def test_objectDoubleResurrectionAndFinalize_oldStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClass.__del__ = delK + K = ResurrectableDummyClass("K") + K = None + + runGCIfJython() + assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) + finalizeMsgList.remove("K finalized (ResurrectableDummyClass)") + assert("K finalized (ResurrectableDummyClass)" not in finalizeMsgList) + global resurrectedObject_K + assert(str(resurrectedObject_K) == "K") + K = resurrectedObject_K + resurrectedObject_K = None + assert(resurrectedObject_K is None) + try: + K.__ensure_finalizer__() + except: + pass + K = None + + runGCIfJython() + assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_K) == "K") + + def test_objectResurrection_newStyleClass(self): + ResurrectableDummyClassNew.__del__ = delL + L = ResurrectableDummyClassNew("L") + L = None + runGCIfJython() + assert("L finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_L) == "L") + + def test_objectDoubleResurrection_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClassNew.__del__ = delM + M = ResurrectableDummyClassNew("M") + M = None + + runGCIfJython() + assert("M finalized (ResurrectableDummyClass)" in finalizeMsgList) + global resurrectedObject_M + assert(str(resurrectedObject_M) == "M") + M = resurrectedObject_M + resurrectedObject_M = None + assert(resurrectedObject_M is None) + try: + M.__ensure_finalizer__() + except: + pass + M = None + + runGCIfJython() + assert(str(resurrectedObject_M) == "M") + + def test_objectDoubleResurrectionAndFinalize_newStyleClass(self): + #okay to fail in Jython without the manual ensureFinalizer calls + ResurrectableDummyClassNew.__del__ = delN + N = ResurrectableDummyClassNew("N") + N = None + + runGCIfJython() + assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) + finalizeMsgList.remove("N finalized (ResurrectableDummyClass)") + assert("N finalized (ResurrectableDummyClass)" not in finalizeMsgList) + global resurrectedObject_N + assert(str(resurrectedObject_N) == "N") + N = resurrectedObject_N + resurrectedObject_N = None + assert(resurrectedObject_N is None) + try: + N.__ensure_finalizer__() + except: + pass + N = None + + runGCIfJython() + assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) + assert(str(resurrectedObject_N) == "N") + + def test_file_overwrite_del(self): + O = DummyFileClassNew("O") + O = None + + runGCIfJython() + assert("O finalized (DummyFileClassNew)" in finalizeMsgList) + +if __name__ == '__main__': + unittest.main() + diff --git a/src/org/python/antlr/ast/AssertDerived.java b/src/org/python/antlr/ast/AssertDerived.java --- a/src/org/python/antlr/ast/AssertDerived.java +++ b/src/org/python/antlr/ast/AssertDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AssertDerived extends Assert implements Slotted { +public class AssertDerived extends Assert implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/AssignDerived.java b/src/org/python/antlr/ast/AssignDerived.java --- a/src/org/python/antlr/ast/AssignDerived.java +++ b/src/org/python/antlr/ast/AssignDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AssignDerived extends Assign implements Slotted { +public class AssignDerived extends Assign implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/AttributeDerived.java b/src/org/python/antlr/ast/AttributeDerived.java --- a/src/org/python/antlr/ast/AttributeDerived.java +++ b/src/org/python/antlr/ast/AttributeDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AttributeDerived extends Attribute implements Slotted { +public class AttributeDerived extends Attribute implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/AugAssignDerived.java b/src/org/python/antlr/ast/AugAssignDerived.java --- a/src/org/python/antlr/ast/AugAssignDerived.java +++ b/src/org/python/antlr/ast/AugAssignDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AugAssignDerived extends AugAssign implements Slotted { +public class AugAssignDerived extends AugAssign implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/BinOpDerived.java b/src/org/python/antlr/ast/BinOpDerived.java --- a/src/org/python/antlr/ast/BinOpDerived.java +++ b/src/org/python/antlr/ast/BinOpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BinOpDerived extends BinOp implements Slotted { +public class BinOpDerived extends BinOp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/BoolOpDerived.java b/src/org/python/antlr/ast/BoolOpDerived.java --- a/src/org/python/antlr/ast/BoolOpDerived.java +++ b/src/org/python/antlr/ast/BoolOpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BoolOpDerived extends BoolOp implements Slotted { +public class BoolOpDerived extends BoolOp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/BreakDerived.java b/src/org/python/antlr/ast/BreakDerived.java --- a/src/org/python/antlr/ast/BreakDerived.java +++ b/src/org/python/antlr/ast/BreakDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BreakDerived extends Break implements Slotted { +public class BreakDerived extends Break implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/CallDerived.java b/src/org/python/antlr/ast/CallDerived.java --- a/src/org/python/antlr/ast/CallDerived.java +++ b/src/org/python/antlr/ast/CallDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class CallDerived extends Call implements Slotted { +public class CallDerived extends Call implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ClassDefDerived.java b/src/org/python/antlr/ast/ClassDefDerived.java --- a/src/org/python/antlr/ast/ClassDefDerived.java +++ b/src/org/python/antlr/ast/ClassDefDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ClassDefDerived extends ClassDef implements Slotted { +public class ClassDefDerived extends ClassDef implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/CompareDerived.java b/src/org/python/antlr/ast/CompareDerived.java --- a/src/org/python/antlr/ast/CompareDerived.java +++ b/src/org/python/antlr/ast/CompareDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class CompareDerived extends Compare implements Slotted { +public class CompareDerived extends Compare implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ContinueDerived.java b/src/org/python/antlr/ast/ContinueDerived.java --- a/src/org/python/antlr/ast/ContinueDerived.java +++ b/src/org/python/antlr/ast/ContinueDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ContinueDerived extends Continue implements Slotted { +public class ContinueDerived extends Continue implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/DeleteDerived.java b/src/org/python/antlr/ast/DeleteDerived.java --- a/src/org/python/antlr/ast/DeleteDerived.java +++ b/src/org/python/antlr/ast/DeleteDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class DeleteDerived extends Delete implements Slotted { +public class DeleteDerived extends Delete implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/DictDerived.java b/src/org/python/antlr/ast/DictDerived.java --- a/src/org/python/antlr/ast/DictDerived.java +++ b/src/org/python/antlr/ast/DictDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class DictDerived extends Dict implements Slotted { +public class DictDerived extends Dict implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/EllipsisDerived.java b/src/org/python/antlr/ast/EllipsisDerived.java --- a/src/org/python/antlr/ast/EllipsisDerived.java +++ b/src/org/python/antlr/ast/EllipsisDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class EllipsisDerived extends Ellipsis implements Slotted { +public class EllipsisDerived extends Ellipsis implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExceptHandlerDerived.java b/src/org/python/antlr/ast/ExceptHandlerDerived.java --- a/src/org/python/antlr/ast/ExceptHandlerDerived.java +++ b/src/org/python/antlr/ast/ExceptHandlerDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExceptHandlerDerived extends ExceptHandler implements Slotted { +public class ExceptHandlerDerived extends ExceptHandler implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExecDerived.java b/src/org/python/antlr/ast/ExecDerived.java --- a/src/org/python/antlr/ast/ExecDerived.java +++ b/src/org/python/antlr/ast/ExecDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExecDerived extends Exec implements Slotted { +public class ExecDerived extends Exec implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExprDerived.java b/src/org/python/antlr/ast/ExprDerived.java --- a/src/org/python/antlr/ast/ExprDerived.java +++ b/src/org/python/antlr/ast/ExprDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExprDerived extends Expr implements Slotted { +public class ExprDerived extends Expr implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExpressionDerived.java b/src/org/python/antlr/ast/ExpressionDerived.java --- a/src/org/python/antlr/ast/ExpressionDerived.java +++ b/src/org/python/antlr/ast/ExpressionDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExpressionDerived extends Expression implements Slotted { +public class ExpressionDerived extends Expression implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ExtSliceDerived.java b/src/org/python/antlr/ast/ExtSliceDerived.java --- a/src/org/python/antlr/ast/ExtSliceDerived.java +++ b/src/org/python/antlr/ast/ExtSliceDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ExtSliceDerived extends ExtSlice implements Slotted { +public class ExtSliceDerived extends ExtSlice implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ForDerived.java b/src/org/python/antlr/ast/ForDerived.java --- a/src/org/python/antlr/ast/ForDerived.java +++ b/src/org/python/antlr/ast/ForDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ForDerived extends For implements Slotted { +public class ForDerived extends For implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/FunctionDefDerived.java b/src/org/python/antlr/ast/FunctionDefDerived.java --- a/src/org/python/antlr/ast/FunctionDefDerived.java +++ b/src/org/python/antlr/ast/FunctionDefDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class FunctionDefDerived extends FunctionDef implements Slotted { +public class FunctionDefDerived extends FunctionDef implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/GeneratorExpDerived.java b/src/org/python/antlr/ast/GeneratorExpDerived.java --- a/src/org/python/antlr/ast/GeneratorExpDerived.java +++ b/src/org/python/antlr/ast/GeneratorExpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class GeneratorExpDerived extends GeneratorExp implements Slotted { +public class GeneratorExpDerived extends GeneratorExp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/GlobalDerived.java b/src/org/python/antlr/ast/GlobalDerived.java --- a/src/org/python/antlr/ast/GlobalDerived.java +++ b/src/org/python/antlr/ast/GlobalDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class GlobalDerived extends Global implements Slotted { +public class GlobalDerived extends Global implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/IfDerived.java b/src/org/python/antlr/ast/IfDerived.java --- a/src/org/python/antlr/ast/IfDerived.java +++ b/src/org/python/antlr/ast/IfDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IfDerived extends If implements Slotted { +public class IfDerived extends If implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/IfExpDerived.java b/src/org/python/antlr/ast/IfExpDerived.java --- a/src/org/python/antlr/ast/IfExpDerived.java +++ b/src/org/python/antlr/ast/IfExpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IfExpDerived extends IfExp implements Slotted { +public class IfExpDerived extends IfExp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ImportDerived.java b/src/org/python/antlr/ast/ImportDerived.java --- a/src/org/python/antlr/ast/ImportDerived.java +++ b/src/org/python/antlr/ast/ImportDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ImportDerived extends Import implements Slotted { +public class ImportDerived extends Import implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ImportFromDerived.java b/src/org/python/antlr/ast/ImportFromDerived.java --- a/src/org/python/antlr/ast/ImportFromDerived.java +++ b/src/org/python/antlr/ast/ImportFromDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ImportFromDerived extends ImportFrom implements Slotted { +public class ImportFromDerived extends ImportFrom implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/IndexDerived.java b/src/org/python/antlr/ast/IndexDerived.java --- a/src/org/python/antlr/ast/IndexDerived.java +++ b/src/org/python/antlr/ast/IndexDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IndexDerived extends Index implements Slotted { +public class IndexDerived extends Index implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/InteractiveDerived.java b/src/org/python/antlr/ast/InteractiveDerived.java --- a/src/org/python/antlr/ast/InteractiveDerived.java +++ b/src/org/python/antlr/ast/InteractiveDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class InteractiveDerived extends Interactive implements Slotted { +public class InteractiveDerived extends Interactive implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/LambdaDerived.java b/src/org/python/antlr/ast/LambdaDerived.java --- a/src/org/python/antlr/ast/LambdaDerived.java +++ b/src/org/python/antlr/ast/LambdaDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LambdaDerived extends Lambda implements Slotted { +public class LambdaDerived extends Lambda implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ListCompDerived.java b/src/org/python/antlr/ast/ListCompDerived.java --- a/src/org/python/antlr/ast/ListCompDerived.java +++ b/src/org/python/antlr/ast/ListCompDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ListCompDerived extends ListComp implements Slotted { +public class ListCompDerived extends ListComp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ListDerived.java b/src/org/python/antlr/ast/ListDerived.java --- a/src/org/python/antlr/ast/ListDerived.java +++ b/src/org/python/antlr/ast/ListDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ListDerived extends List implements Slotted { +public class ListDerived extends List implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ModuleDerived.java b/src/org/python/antlr/ast/ModuleDerived.java --- a/src/org/python/antlr/ast/ModuleDerived.java +++ b/src/org/python/antlr/ast/ModuleDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ModuleDerived extends Module implements Slotted { +public class ModuleDerived extends Module implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/NameDerived.java b/src/org/python/antlr/ast/NameDerived.java --- a/src/org/python/antlr/ast/NameDerived.java +++ b/src/org/python/antlr/ast/NameDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NameDerived extends Name implements Slotted { +public class NameDerived extends Name implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/NumDerived.java b/src/org/python/antlr/ast/NumDerived.java --- a/src/org/python/antlr/ast/NumDerived.java +++ b/src/org/python/antlr/ast/NumDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NumDerived extends Num implements Slotted { +public class NumDerived extends Num implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/PassDerived.java b/src/org/python/antlr/ast/PassDerived.java --- a/src/org/python/antlr/ast/PassDerived.java +++ b/src/org/python/antlr/ast/PassDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PassDerived extends Pass implements Slotted { +public class PassDerived extends Pass implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/PrintDerived.java b/src/org/python/antlr/ast/PrintDerived.java --- a/src/org/python/antlr/ast/PrintDerived.java +++ b/src/org/python/antlr/ast/PrintDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PrintDerived extends Print implements Slotted { +public class PrintDerived extends Print implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/RaiseDerived.java b/src/org/python/antlr/ast/RaiseDerived.java --- a/src/org/python/antlr/ast/RaiseDerived.java +++ b/src/org/python/antlr/ast/RaiseDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class RaiseDerived extends Raise implements Slotted { +public class RaiseDerived extends Raise implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ReprDerived.java b/src/org/python/antlr/ast/ReprDerived.java --- a/src/org/python/antlr/ast/ReprDerived.java +++ b/src/org/python/antlr/ast/ReprDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ReprDerived extends Repr implements Slotted { +public class ReprDerived extends Repr implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/ReturnDerived.java b/src/org/python/antlr/ast/ReturnDerived.java --- a/src/org/python/antlr/ast/ReturnDerived.java +++ b/src/org/python/antlr/ast/ReturnDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ReturnDerived extends Return implements Slotted { +public class ReturnDerived extends Return implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/SliceDerived.java b/src/org/python/antlr/ast/SliceDerived.java --- a/src/org/python/antlr/ast/SliceDerived.java +++ b/src/org/python/antlr/ast/SliceDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class SliceDerived extends Slice implements Slotted { +public class SliceDerived extends Slice implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/StrDerived.java b/src/org/python/antlr/ast/StrDerived.java --- a/src/org/python/antlr/ast/StrDerived.java +++ b/src/org/python/antlr/ast/StrDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class StrDerived extends Str implements Slotted { +public class StrDerived extends Str implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/SubscriptDerived.java b/src/org/python/antlr/ast/SubscriptDerived.java --- a/src/org/python/antlr/ast/SubscriptDerived.java +++ b/src/org/python/antlr/ast/SubscriptDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class SubscriptDerived extends Subscript implements Slotted { +public class SubscriptDerived extends Subscript implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/SuiteDerived.java b/src/org/python/antlr/ast/SuiteDerived.java --- a/src/org/python/antlr/ast/SuiteDerived.java +++ b/src/org/python/antlr/ast/SuiteDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class SuiteDerived extends Suite implements Slotted { +public class SuiteDerived extends Suite implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/TryExceptDerived.java b/src/org/python/antlr/ast/TryExceptDerived.java --- a/src/org/python/antlr/ast/TryExceptDerived.java +++ b/src/org/python/antlr/ast/TryExceptDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class TryExceptDerived extends TryExcept implements Slotted { +public class TryExceptDerived extends TryExcept implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/TryFinallyDerived.java b/src/org/python/antlr/ast/TryFinallyDerived.java --- a/src/org/python/antlr/ast/TryFinallyDerived.java +++ b/src/org/python/antlr/ast/TryFinallyDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class TryFinallyDerived extends TryFinally implements Slotted { +public class TryFinallyDerived extends TryFinally implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/TupleDerived.java b/src/org/python/antlr/ast/TupleDerived.java --- a/src/org/python/antlr/ast/TupleDerived.java +++ b/src/org/python/antlr/ast/TupleDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class TupleDerived extends Tuple implements Slotted { +public class TupleDerived extends Tuple implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/UnaryOpDerived.java b/src/org/python/antlr/ast/UnaryOpDerived.java --- a/src/org/python/antlr/ast/UnaryOpDerived.java +++ b/src/org/python/antlr/ast/UnaryOpDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class UnaryOpDerived extends UnaryOp implements Slotted { +public class UnaryOpDerived extends UnaryOp implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/WhileDerived.java b/src/org/python/antlr/ast/WhileDerived.java --- a/src/org/python/antlr/ast/WhileDerived.java +++ b/src/org/python/antlr/ast/WhileDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class WhileDerived extends While implements Slotted { +public class WhileDerived extends While implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/WithDerived.java b/src/org/python/antlr/ast/WithDerived.java --- a/src/org/python/antlr/ast/WithDerived.java +++ b/src/org/python/antlr/ast/WithDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class WithDerived extends With implements Slotted { +public class WithDerived extends With implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/YieldDerived.java b/src/org/python/antlr/ast/YieldDerived.java --- a/src/org/python/antlr/ast/YieldDerived.java +++ b/src/org/python/antlr/ast/YieldDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class YieldDerived extends Yield implements Slotted { +public class YieldDerived extends Yield implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/aliasDerived.java b/src/org/python/antlr/ast/aliasDerived.java --- a/src/org/python/antlr/ast/aliasDerived.java +++ b/src/org/python/antlr/ast/aliasDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class aliasDerived extends alias implements Slotted { +public class aliasDerived extends alias implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/argumentsDerived.java b/src/org/python/antlr/ast/argumentsDerived.java --- a/src/org/python/antlr/ast/argumentsDerived.java +++ b/src/org/python/antlr/ast/argumentsDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class argumentsDerived extends arguments implements Slotted { +public class argumentsDerived extends arguments implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/comprehensionDerived.java b/src/org/python/antlr/ast/comprehensionDerived.java --- a/src/org/python/antlr/ast/comprehensionDerived.java +++ b/src/org/python/antlr/ast/comprehensionDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class comprehensionDerived extends comprehension implements Slotted { +public class comprehensionDerived extends comprehension implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/ast/keywordDerived.java b/src/org/python/antlr/ast/keywordDerived.java --- a/src/org/python/antlr/ast/keywordDerived.java +++ b/src/org/python/antlr/ast/keywordDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class keywordDerived extends keyword implements Slotted { +public class keywordDerived extends keyword implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/AddDerived.java b/src/org/python/antlr/op/AddDerived.java --- a/src/org/python/antlr/op/AddDerived.java +++ b/src/org/python/antlr/op/AddDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AddDerived extends Add implements Slotted { +public class AddDerived extends Add implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/AndDerived.java b/src/org/python/antlr/op/AndDerived.java --- a/src/org/python/antlr/op/AndDerived.java +++ b/src/org/python/antlr/op/AndDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AndDerived extends And implements Slotted { +public class AndDerived extends And implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/AugLoadDerived.java b/src/org/python/antlr/op/AugLoadDerived.java --- a/src/org/python/antlr/op/AugLoadDerived.java +++ b/src/org/python/antlr/op/AugLoadDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AugLoadDerived extends AugLoad implements Slotted { +public class AugLoadDerived extends AugLoad implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/AugStoreDerived.java b/src/org/python/antlr/op/AugStoreDerived.java --- a/src/org/python/antlr/op/AugStoreDerived.java +++ b/src/org/python/antlr/op/AugStoreDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class AugStoreDerived extends AugStore implements Slotted { +public class AugStoreDerived extends AugStore implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/BitAndDerived.java b/src/org/python/antlr/op/BitAndDerived.java --- a/src/org/python/antlr/op/BitAndDerived.java +++ b/src/org/python/antlr/op/BitAndDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BitAndDerived extends BitAnd implements Slotted { +public class BitAndDerived extends BitAnd implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/BitOrDerived.java b/src/org/python/antlr/op/BitOrDerived.java --- a/src/org/python/antlr/op/BitOrDerived.java +++ b/src/org/python/antlr/op/BitOrDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BitOrDerived extends BitOr implements Slotted { +public class BitOrDerived extends BitOr implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/BitXorDerived.java b/src/org/python/antlr/op/BitXorDerived.java --- a/src/org/python/antlr/op/BitXorDerived.java +++ b/src/org/python/antlr/op/BitXorDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class BitXorDerived extends BitXor implements Slotted { +public class BitXorDerived extends BitXor implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/DelDerived.java b/src/org/python/antlr/op/DelDerived.java --- a/src/org/python/antlr/op/DelDerived.java +++ b/src/org/python/antlr/op/DelDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class DelDerived extends Del implements Slotted { +public class DelDerived extends Del implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/DivDerived.java b/src/org/python/antlr/op/DivDerived.java --- a/src/org/python/antlr/op/DivDerived.java +++ b/src/org/python/antlr/op/DivDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class DivDerived extends Div implements Slotted { +public class DivDerived extends Div implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/EqDerived.java b/src/org/python/antlr/op/EqDerived.java --- a/src/org/python/antlr/op/EqDerived.java +++ b/src/org/python/antlr/op/EqDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class EqDerived extends Eq implements Slotted { +public class EqDerived extends Eq implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/FloorDivDerived.java b/src/org/python/antlr/op/FloorDivDerived.java --- a/src/org/python/antlr/op/FloorDivDerived.java +++ b/src/org/python/antlr/op/FloorDivDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class FloorDivDerived extends FloorDiv implements Slotted { +public class FloorDivDerived extends FloorDiv implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/GtDerived.java b/src/org/python/antlr/op/GtDerived.java --- a/src/org/python/antlr/op/GtDerived.java +++ b/src/org/python/antlr/op/GtDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class GtDerived extends Gt implements Slotted { +public class GtDerived extends Gt implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/GtEDerived.java b/src/org/python/antlr/op/GtEDerived.java --- a/src/org/python/antlr/op/GtEDerived.java +++ b/src/org/python/antlr/op/GtEDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class GtEDerived extends GtE implements Slotted { +public class GtEDerived extends GtE implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/InDerived.java b/src/org/python/antlr/op/InDerived.java --- a/src/org/python/antlr/op/InDerived.java +++ b/src/org/python/antlr/op/InDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class InDerived extends In implements Slotted { +public class InDerived extends In implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/InvertDerived.java b/src/org/python/antlr/op/InvertDerived.java --- a/src/org/python/antlr/op/InvertDerived.java +++ b/src/org/python/antlr/op/InvertDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class InvertDerived extends Invert implements Slotted { +public class InvertDerived extends Invert implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/IsDerived.java b/src/org/python/antlr/op/IsDerived.java --- a/src/org/python/antlr/op/IsDerived.java +++ b/src/org/python/antlr/op/IsDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IsDerived extends Is implements Slotted { +public class IsDerived extends Is implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/IsNotDerived.java b/src/org/python/antlr/op/IsNotDerived.java --- a/src/org/python/antlr/op/IsNotDerived.java +++ b/src/org/python/antlr/op/IsNotDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class IsNotDerived extends IsNot implements Slotted { +public class IsNotDerived extends IsNot implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/LShiftDerived.java b/src/org/python/antlr/op/LShiftDerived.java --- a/src/org/python/antlr/op/LShiftDerived.java +++ b/src/org/python/antlr/op/LShiftDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LShiftDerived extends LShift implements Slotted { +public class LShiftDerived extends LShift implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/LoadDerived.java b/src/org/python/antlr/op/LoadDerived.java --- a/src/org/python/antlr/op/LoadDerived.java +++ b/src/org/python/antlr/op/LoadDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LoadDerived extends Load implements Slotted { +public class LoadDerived extends Load implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/LtDerived.java b/src/org/python/antlr/op/LtDerived.java --- a/src/org/python/antlr/op/LtDerived.java +++ b/src/org/python/antlr/op/LtDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LtDerived extends Lt implements Slotted { +public class LtDerived extends Lt implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/LtEDerived.java b/src/org/python/antlr/op/LtEDerived.java --- a/src/org/python/antlr/op/LtEDerived.java +++ b/src/org/python/antlr/op/LtEDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class LtEDerived extends LtE implements Slotted { +public class LtEDerived extends LtE implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/ModDerived.java b/src/org/python/antlr/op/ModDerived.java --- a/src/org/python/antlr/op/ModDerived.java +++ b/src/org/python/antlr/op/ModDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ModDerived extends Mod implements Slotted { +public class ModDerived extends Mod implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/MultDerived.java b/src/org/python/antlr/op/MultDerived.java --- a/src/org/python/antlr/op/MultDerived.java +++ b/src/org/python/antlr/op/MultDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class MultDerived extends Mult implements Slotted { +public class MultDerived extends Mult implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/NotDerived.java b/src/org/python/antlr/op/NotDerived.java --- a/src/org/python/antlr/op/NotDerived.java +++ b/src/org/python/antlr/op/NotDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NotDerived extends Not implements Slotted { +public class NotDerived extends Not implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/NotEqDerived.java b/src/org/python/antlr/op/NotEqDerived.java --- a/src/org/python/antlr/op/NotEqDerived.java +++ b/src/org/python/antlr/op/NotEqDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NotEqDerived extends NotEq implements Slotted { +public class NotEqDerived extends NotEq implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/NotInDerived.java b/src/org/python/antlr/op/NotInDerived.java --- a/src/org/python/antlr/op/NotInDerived.java +++ b/src/org/python/antlr/op/NotInDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class NotInDerived extends NotIn implements Slotted { +public class NotInDerived extends NotIn implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/OrDerived.java b/src/org/python/antlr/op/OrDerived.java --- a/src/org/python/antlr/op/OrDerived.java +++ b/src/org/python/antlr/op/OrDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class OrDerived extends Or implements Slotted { +public class OrDerived extends Or implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/ParamDerived.java b/src/org/python/antlr/op/ParamDerived.java --- a/src/org/python/antlr/op/ParamDerived.java +++ b/src/org/python/antlr/op/ParamDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ParamDerived extends Param implements Slotted { +public class ParamDerived extends Param implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/PowDerived.java b/src/org/python/antlr/op/PowDerived.java --- a/src/org/python/antlr/op/PowDerived.java +++ b/src/org/python/antlr/op/PowDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PowDerived extends Pow implements Slotted { +public class PowDerived extends Pow implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/RShiftDerived.java b/src/org/python/antlr/op/RShiftDerived.java --- a/src/org/python/antlr/op/RShiftDerived.java +++ b/src/org/python/antlr/op/RShiftDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class RShiftDerived extends RShift implements Slotted { +public class RShiftDerived extends RShift implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/StoreDerived.java b/src/org/python/antlr/op/StoreDerived.java --- a/src/org/python/antlr/op/StoreDerived.java +++ b/src/org/python/antlr/op/StoreDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class StoreDerived extends Store implements Slotted { +public class StoreDerived extends Store implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/SubDerived.java b/src/org/python/antlr/op/SubDerived.java --- a/src/org/python/antlr/op/SubDerived.java +++ b/src/org/python/antlr/op/SubDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class SubDerived extends Sub implements Slotted { +public class SubDerived extends Sub implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/UAddDerived.java b/src/org/python/antlr/op/UAddDerived.java --- a/src/org/python/antlr/op/UAddDerived.java +++ b/src/org/python/antlr/op/UAddDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class UAddDerived extends UAdd implements Slotted { +public class UAddDerived extends UAdd implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/antlr/op/USubDerived.java b/src/org/python/antlr/op/USubDerived.java --- a/src/org/python/antlr/op/USubDerived.java +++ b/src/org/python/antlr/op/USubDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class USubDerived extends USub implements Slotted { +public class USubDerived extends USub implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/ClasspathPyImporterDerived.java b/src/org/python/core/ClasspathPyImporterDerived.java --- a/src/org/python/core/ClasspathPyImporterDerived.java +++ b/src/org/python/core/ClasspathPyImporterDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ClasspathPyImporterDerived extends ClasspathPyImporter implements Slotted { +public class ClasspathPyImporterDerived extends ClasspathPyImporter implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,9 +19,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public ClasspathPyImporterDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -978,6 +997,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java --- a/src/org/python/core/Py.java +++ b/src/org/python/core/Py.java @@ -837,27 +837,27 @@ * @throws ClassNotFoundException if the class wasn't found by the class loader */ private static Class findClassInternal(String name, String reason) throws ClassNotFoundException { - ClassLoader classLoader = Py.getSystemState().getClassLoader(); + ClassLoader classLoader = Py.getSystemState().getClassLoader(); if (classLoader != null) { - if (reason != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in sys.classLoader"); - } + if (reason != null) { + writeDebug("import", "trying " + name + " as " + reason + + " in sys.classLoader"); + } return loadAndInitClass(name, classLoader); } if (!syspathJavaLoaderRestricted) { try { classLoader = imp.getSyspathJavaLoader(); if (classLoader != null && reason != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in SysPathJavaLoader"); + writeDebug("import", "trying " + name + " as " + reason + + " in SysPathJavaLoader"); } } catch (SecurityException e) { syspathJavaLoaderRestricted = true; } } if (syspathJavaLoaderRestricted) { - classLoader = imp.getParentClassLoader(); + classLoader = imp.getParentClassLoader(); if (classLoader != null && reason != null) { writeDebug("import", "trying " + name + " as " + reason + " in Jython's parent class loader"); @@ -865,20 +865,20 @@ } if (classLoader != null) { try { - return loadAndInitClass(name, classLoader); + return loadAndInitClass(name, classLoader); } catch (ClassNotFoundException cnfe) { // let the default classloader try - // XXX: by trying another classloader that may not be on a - // parent/child relationship with the Jython's parent - // classsloader we are risking some nasty class loading - // problems (such as having two incompatible copies for - // the same class that is itself a dependency of two - // classes loaded from these two different class loaders) + // XXX: by trying another classloader that may not be on a + // parent/child relationship with the Jython's parent + // classsloader we are risking some nasty class loading + // problems (such as having two incompatible copies for + // the same class that is itself a dependency of two + // classes loaded from these two different class loaders) } } if (reason != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in context class loader, for backwards compatibility"); + writeDebug("import", "trying " + name + " as " + reason + + " in context class loader, for backwards compatibility"); } return loadAndInitClass(name, Thread.currentThread().getContextClassLoader()); } @@ -890,7 +890,7 @@ */ public static Class findClass(String name) { try { - return findClassInternal(name, null); + return findClassInternal(name, null); } catch (ClassNotFoundException e) { // e.printStackTrace(); return null; @@ -930,7 +930,7 @@ // We *need* to initialize classes on findClass/findClassEx, so that import // statements can trigger static initializers private static Class loadAndInitClass(String name, ClassLoader loader) throws ClassNotFoundException { - return Class.forName(name, true, loader); + return Class.forName(name, true, loader); } diff --git a/src/org/python/core/PyArrayDerived.java b/src/org/python/core/PyArrayDerived.java --- a/src/org/python/core/PyArrayDerived.java +++ b/src/org/python/core/PyArrayDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyArrayDerived extends PyArray implements Slotted { +public class PyArrayDerived extends PyArray implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyBaseExceptionDerived.java b/src/org/python/core/PyBaseExceptionDerived.java --- a/src/org/python/core/PyBaseExceptionDerived.java +++ b/src/org/python/core/PyBaseExceptionDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyBaseExceptionDerived extends PyBaseException implements Slotted { +public class PyBaseExceptionDerived extends PyBaseException implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,9 +19,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyBaseExceptionDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -978,6 +997,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyByteArrayDerived.java b/src/org/python/core/PyByteArrayDerived.java --- a/src/org/python/core/PyByteArrayDerived.java +++ b/src/org/python/core/PyByteArrayDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyByteArrayDerived extends PyByteArray implements Slotted { +public class PyByteArrayDerived extends PyByteArray implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyClass.java b/src/org/python/core/PyClass.java --- a/src/org/python/core/PyClass.java +++ b/src/org/python/core/PyClass.java @@ -3,6 +3,7 @@ import org.python.expose.ExposedNew; import org.python.expose.ExposedType; +import org.python.core.finalization.FinalizeTrigger; /** * The classic Python class. @@ -185,11 +186,9 @@ @Override public PyObject __call__(PyObject[] args, String[] keywords) { PyInstance inst; - if (__del__ == null) { - inst = new PyInstance(this); - } else { - // the class defined a __del__ method - inst = new PyFinalizableInstance(this); + inst = new PyInstance(this); + if (__del__ != null) { + inst.finalizeTrigger = FinalizeTrigger.makeTrigger(inst); } inst.__init__(args, keywords); return inst; diff --git a/src/org/python/core/PyClassMethodDerived.java b/src/org/python/core/PyClassMethodDerived.java --- a/src/org/python/core/PyClassMethodDerived.java +++ b/src/org/python/core/PyClassMethodDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyClassMethodDerived extends PyClassMethod implements Slotted { +public class PyClassMethodDerived extends PyClassMethod implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyComplexDerived.java b/src/org/python/core/PyComplexDerived.java --- a/src/org/python/core/PyComplexDerived.java +++ b/src/org/python/core/PyComplexDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyComplexDerived extends PyComplex implements Slotted { +public class PyComplexDerived extends PyComplex implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,real,imaginary); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyDictionaryDerived.java b/src/org/python/core/PyDictionaryDerived.java --- a/src/org/python/core/PyDictionaryDerived.java +++ b/src/org/python/core/PyDictionaryDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyDictionaryDerived extends PyDictionary implements Slotted { +public class PyDictionaryDerived extends PyDictionary implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyEnumerateDerived.java b/src/org/python/core/PyEnumerateDerived.java --- a/src/org/python/core/PyEnumerateDerived.java +++ b/src/org/python/core/PyEnumerateDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyEnumerateDerived extends PyEnumerate implements Slotted { +public class PyEnumerateDerived extends PyEnumerate implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,seq,start); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyFile.java b/src/org/python/core/PyFile.java --- a/src/org/python/core/PyFile.java +++ b/src/org/python/core/PyFile.java @@ -8,6 +8,8 @@ import java.io.OutputStream; import java.util.concurrent.Callable; +import org.python.core.finalization.FinalizableBuiltin; +import org.python.core.finalization.FinalizeTrigger; import org.python.core.io.BinaryIOWrapper; import org.python.core.io.BufferedIOBase; import org.python.core.io.BufferedRandom; @@ -33,7 +35,7 @@ * The Python file type. Wraps an {@link TextIOBase} object. */ @ExposedType(name = "file", doc = BuiltinDocs.file_doc) -public class PyFile extends PyObject { +public class PyFile extends PyObject implements FinalizableBuiltin { public static final PyType TYPE = PyType.fromClass(PyFile.class); @@ -80,21 +82,26 @@ /** The file's closer object; ensures the file is closed at * shutdown */ private Closer closer; + + public FinalizeTrigger finalizeTrigger; - public PyFile() {} + public PyFile() {finalizeTrigger = FinalizeTrigger.makeTrigger(this);} public PyFile(PyType subType) { super(subType); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } public PyFile(RawIOBase raw, String name, String mode, int bufsize) { parseMode(mode); file___init__(raw, name, mode, bufsize); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } public PyFile(InputStream istream, String name, String mode, int bufsize, boolean closefd) { parseMode(mode); file___init__(new StreamIO(istream, closefd), name, mode, bufsize); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } /** @@ -126,6 +133,7 @@ public PyFile(OutputStream ostream, String name, String mode, int bufsize, boolean closefd) { parseMode(mode); file___init__(new StreamIO(ostream, closefd), name, mode, bufsize); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } /** @@ -153,6 +161,7 @@ public PyFile(String name, String mode, int bufsize) { file___init__(new FileIO(name, parseMode(mode)), name, mode, bufsize); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } @ExposedNew @@ -674,8 +683,7 @@ } @Override - protected void finalize() throws Throwable { - super.finalize(); + public void __del_builtin__() { if (closer != null) { closer.close(); } diff --git a/src/org/python/core/PyFileDerived.java b/src/org/python/core/PyFileDerived.java --- a/src/org/python/core/PyFileDerived.java +++ b/src/org/python/core/PyFileDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyFileDerived extends PyFile implements Slotted { +public class PyFileDerived extends PyFile implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyFinalizableInstance.java b/src/org/python/core/PyFinalizableInstance.java deleted file mode 100644 --- a/src/org/python/core/PyFinalizableInstance.java +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Corporation for National Research Initiatives -// These are just like normal instances, except that their classes included -// a definition for __del__(), i.e. Python's finalizer. These two instance -// types have to be separated due to Java performance issues. - -package org.python.core; - - -/** - * A python class instance with __del__ defined. - *

- * This is a special class due to performance. Defining - * finalize() on a class, makes the class a lot slower. - */ -public class PyFinalizableInstance extends PyInstance { - - public PyFinalizableInstance(PyClass iclass) { - super(iclass); - } - - // __del__ method is invoked upon object finalization. - @Override - protected void finalize() { - try { - instclass.__del__.__call__(this); - } catch (PyException exc) { - // Try to get the right method description. - PyObject method = instclass.__del__; - try { - method = __findattr__("__del__"); - } catch (PyException e) { - // nothing we can do - } - Py.writeUnraisable(exc, method); - } - } -} diff --git a/src/org/python/core/PyFloatDerived.java b/src/org/python/core/PyFloatDerived.java --- a/src/org/python/core/PyFloatDerived.java +++ b/src/org/python/core/PyFloatDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyFloatDerived extends PyFloat implements Slotted { +public class PyFloatDerived extends PyFloat implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,v); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyFrozenSetDerived.java b/src/org/python/core/PyFrozenSetDerived.java --- a/src/org/python/core/PyFrozenSetDerived.java +++ b/src/org/python/core/PyFrozenSetDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyFrozenSetDerived extends PyFrozenSet implements Slotted { +public class PyFrozenSetDerived extends PyFrozenSet implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,data); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyGenerator.java b/src/org/python/core/PyGenerator.java --- a/src/org/python/core/PyGenerator.java +++ b/src/org/python/core/PyGenerator.java @@ -1,12 +1,14 @@ /* Copyright (c) Jython Developers */ package org.python.core; +import org.python.core.finalization.FinalizableBuiltin; +import org.python.core.finalization.FinalizeTrigger; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedType; @ExposedType(name = "generator", base = PyObject.class, isBaseType = false) -public class PyGenerator extends PyIterator { +public class PyGenerator extends PyIterator implements FinalizableBuiltin { public static final PyType TYPE = PyType.fromClass(PyGenerator.class); @@ -20,6 +22,8 @@ protected boolean gi_running; private PyObject closure; + + public FinalizeTrigger finalizeTrigger; public PyGenerator(PyFrame frame, PyObject closure) { super(TYPE); @@ -28,6 +32,7 @@ gi_code = gi_frame.f_code; } this.closure = closure; + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } public PyObject send(PyObject value) { @@ -105,9 +110,9 @@ gi_frame.setGeneratorInput(ex); return next(); } - + @Override - protected void finalize() throws Throwable { + public void __del_builtin__() { if (gi_frame == null || gi_frame.f_lasti == -1) { return; } @@ -127,8 +132,6 @@ } catch (Throwable t) { // but we currently ignore any Java exception completely. perhaps we // can also output something meaningful too? - } finally { - super.finalize(); } } diff --git a/src/org/python/core/PyInstance.java b/src/org/python/core/PyInstance.java --- a/src/org/python/core/PyInstance.java +++ b/src/org/python/core/PyInstance.java @@ -6,14 +6,20 @@ import org.python.expose.ExposedType; import org.python.expose.MethodType; +import org.python.core.finalization.FinalizablePyObject; +import org.python.core.finalization.FinalizeTrigger; + /** * An instance of a classic Python class. */ @ExposedType(name = "instance", isBaseType = false) -public class PyInstance extends PyObject { +public class PyInstance extends PyObject implements FinalizablePyObject { public static final PyType TYPE = PyType.fromClass(PyInstance.class); + public FinalizeTrigger finalizeTrigger; + private static JavaFunc __ensure_finalizer__Function; + // xxx doc, final name public transient PyClass instclass; @@ -147,9 +153,27 @@ return ifindfunction(name); } + public static void ensureFinalizer(PyObject[] args, String[] kws) { + FinalizeTrigger.ensureFinalizer((PyInstance) args[0]); + } + + private static JavaFunc makeFunction__ensure_finalizer__() { + try { + return new JavaFunc( + PyInstance.class.getMethod("ensureFinalizer", + PyObject[].class, String[].class)); + } catch (Exception e) {return null;} //cannot happen + } + protected PyObject ifindlocal(String name) { if (name == "__dict__") return __dict__; if (name == "__class__") return instclass; + if (name == "__ensure_finalizer__") { + if (__ensure_finalizer__Function == null) { + __ensure_finalizer__Function = makeFunction__ensure_finalizer__(); + } + return new PyMethod(__ensure_finalizer__Function, this, instclass); + } if (__dict__ == null) return null; return __dict__.__finditem__(name); @@ -263,6 +287,9 @@ if (name == "__class__") { if (value instanceof PyClass) { instclass = (PyClass) value; + if (instclass.__del__ != null && finalizeTrigger == null) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__class__ must be set to a class"); } @@ -278,6 +305,9 @@ } else { __dict__.__setitem__(name, value); } + if (name == "__del__" && finalizeTrigger == null) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } protected void noField(String name, PyObject value) { @@ -1909,4 +1939,24 @@ return super.__ixor__(o); } + @Override + public void __del__() { + try { + PyObject method = __findattr__("__del__"); + if (method != null) { + method.__call__(); + } else if (instclass.__del__ != null) { + instclass.__del__.__call__(this); + } + } catch (PyException exc) { + // Try to get the right method description. + PyObject method = instclass.__del__; + try { + method = __findattr__("__del__"); + } catch (PyException e) { + // nothing we can do + } + Py.writeUnraisable(exc, method); + } + } } diff --git a/src/org/python/core/PyIntegerDerived.java b/src/org/python/core/PyIntegerDerived.java --- a/src/org/python/core/PyIntegerDerived.java +++ b/src/org/python/core/PyIntegerDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyIntegerDerived extends PyInteger implements Slotted { +public class PyIntegerDerived extends PyInteger implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,v); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyListDerived.java b/src/org/python/core/PyListDerived.java --- a/src/org/python/core/PyListDerived.java +++ b/src/org/python/core/PyListDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyListDerived extends PyList implements Slotted { +public class PyListDerived extends PyList implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyLongDerived.java b/src/org/python/core/PyLongDerived.java --- a/src/org/python/core/PyLongDerived.java +++ b/src/org/python/core/PyLongDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyLongDerived extends PyLong implements Slotted { +public class PyLongDerived extends PyLong implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,v); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyModuleDerived.java b/src/org/python/core/PyModuleDerived.java --- a/src/org/python/core/PyModuleDerived.java +++ b/src/org/python/core/PyModuleDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyModuleDerived extends PyModule implements Slotted { +public class PyModuleDerived extends PyModule implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,9 +19,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyModuleDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -978,6 +997,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyObject.java b/src/org/python/core/PyObject.java --- a/src/org/python/core/PyObject.java +++ b/src/org/python/core/PyObject.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; +import org.python.core.finalization.FinalizeTrigger; import org.python.expose.ExposedClassMethod; import org.python.expose.ExposedDelete; import org.python.expose.ExposedGet; @@ -99,6 +100,21 @@ return new_.for_type == subtype ? new PyObject() : new PyObjectDerived(subtype); } + /** + *

+ * From Jython 2.7 on, {@code PyObject}s must not have finalizers directly. + * If a finalizer, a.k.a. {@code __del__} is needed, follow the instructions in the + * documentation of {@link org.python.core.finalization.FinalizablePyObject}. + *

+ *

+ * Note that this empty finalizer implementation is optimized away by the JVM + * (See {@link http://www.javaspecialists.eu/archive/Issue170.html}). + * So {@code PyObject}s are not expensively treaded as finalizable objects by the + * GC. Its only intention is to prevent subclasses from having Java-style finalizers. + *

+ */ + protected final void finalize() throws Throwable {} + @ExposedMethod(doc = BuiltinDocs.object___init___doc) final void object___init__(PyObject[] args, String[] keywords) { } @@ -223,6 +239,12 @@ return __repr__(); } + @ExposedMethod + public void __ensure_finalizer__() { + //PyObjects that implement HasFinalizeTrigger shall implement this method via: + //FinalizeTrigger.ensureFinalizer(this); + } + public PyUnicode __unicode__() { return new PyUnicode(__str__()); } diff --git a/src/org/python/core/PyObjectDerived.java b/src/org/python/core/PyObjectDerived.java --- a/src/org/python/core/PyObjectDerived.java +++ b/src/org/python/core/PyObjectDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyObjectDerived extends PyObject implements Slotted { +public class PyObjectDerived extends PyObject implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyPropertyDerived.java b/src/org/python/core/PyPropertyDerived.java --- a/src/org/python/core/PyPropertyDerived.java +++ b/src/org/python/core/PyPropertyDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyPropertyDerived extends PyProperty implements Slotted { +public class PyPropertyDerived extends PyProperty implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PySetDerived.java b/src/org/python/core/PySetDerived.java --- a/src/org/python/core/PySetDerived.java +++ b/src/org/python/core/PySetDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PySetDerived extends PySet implements Slotted { +public class PySetDerived extends PySet implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyStringDerived.java b/src/org/python/core/PyStringDerived.java --- a/src/org/python/core/PyStringDerived.java +++ b/src/org/python/core/PyStringDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyStringDerived extends PyString implements Slotted { +public class PyStringDerived extends PyString implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,v); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PySuperDerived.java b/src/org/python/core/PySuperDerived.java --- a/src/org/python/core/PySuperDerived.java +++ b/src/org/python/core/PySuperDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PySuperDerived extends PySuper implements Slotted { +public class PySuperDerived extends PySuper implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyTupleDerived.java b/src/org/python/core/PyTupleDerived.java --- a/src/org/python/core/PyTupleDerived.java +++ b/src/org/python/core/PyTupleDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyTupleDerived extends PyTuple implements Slotted { +public class PyTupleDerived extends PyTuple implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,elements); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyType.java b/src/org/python/core/PyType.java --- a/src/org/python/core/PyType.java +++ b/src/org/python/core/PyType.java @@ -82,7 +82,7 @@ protected boolean needs_weakref; /** Whether finalization is required for this type's instances (implements __del__). */ - private boolean needs_finalizer; + protected boolean needs_finalizer; /** Whether this type's __getattribute__ is object.__getattribute__. */ private volatile boolean usesObjectGetattribute; @@ -310,7 +310,7 @@ if (wantWeak) { createWeakrefSlot(); } - needs_finalizer = lookup_mro("__del__") != null; + needs_finalizer = needsFinalizer(); } /** @@ -568,6 +568,24 @@ } /** + * Offers public read-only access to the protected field needs_finalizer. + * + * @return a boolean indicating whether the type implements __del__ + */ + public final boolean needsFinalizer() { + //It might be sluggish to assume that if a finalizer was needed + //once, this would never change. However since an expensive + //FinalizeTrigger was created anyway, it won't hurt to keep it. + //Whether there actually is a __del__ in the dict will be checked + //again when the finalizer runs. + if (needs_finalizer) return true; + else { + needs_finalizer = lookup_mro("__del__") != null; + return needs_finalizer; + } + } + + /** * Ensures that the physical layout between this type and other are compatible. * Raises a TypeError if not. */ diff --git a/src/org/python/core/PyTypeDerived.java b/src/org/python/core/PyTypeDerived.java --- a/src/org/python/core/PyTypeDerived.java +++ b/src/org/python/core/PyTypeDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyTypeDerived extends PyType implements Slotted { +public class PyTypeDerived extends PyType implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,9 +19,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyTypeDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -978,6 +997,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/PyUnicodeDerived.java b/src/org/python/core/PyUnicodeDerived.java --- a/src/org/python/core/PyUnicodeDerived.java +++ b/src/org/python/core/PyUnicodeDerived.java @@ -2,8 +2,12 @@ package org.python.core; import java.io.Serializable; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyUnicodeDerived extends PyUnicode implements Slotted { +public class PyUnicodeDerived extends PyUnicode implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -15,6 +19,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -28,6 +44,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -42,6 +61,9 @@ super(subtype,string); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1002,6 +1024,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/core/finalization/FinalizableBuiltin.java b/src/org/python/core/finalization/FinalizableBuiltin.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizableBuiltin.java @@ -0,0 +1,18 @@ +package org.python.core.finalization; + +/** + * See documentation of {@link FinalizablePyObject}. + */ + +public interface FinalizableBuiltin extends HasFinalizeTrigger { + /** + * {@code __del_builtin__} is the built-in's own finalizer, while + * {@code __del_derived__} refers to an instance's in-dict {@code __del__}. + * A FinalizeTrigger calls {@code __del_derived__} first and + * - if existent - {@code __del_builtin__} after that. A plain {@code __del__} + * would behave as overwritten by {@code __del__Derived}, i.e. won't be called + * if the type implements {@code FinalizablePyObjectDerived} while + * {@code __del_builtin__} is called in any case. + */ + public void __del_builtin__(); +} diff --git a/src/org/python/core/finalization/FinalizablePyObject.java b/src/org/python/core/finalization/FinalizablePyObject.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizablePyObject.java @@ -0,0 +1,90 @@ +package org.python.core.finalization; + +/** + *

+ * This interface allows {@code PyObject}s to have finalizers. + * Alternatively one can use + * {@link org.python.core.finalization.FinalizableBuiltin}. + *

+ *

+ * The difference is that {@code __del__} can be overwritten by a + * new-style subclass's {@code __del__}-method on Python-side, while + * {@code __del_builtin__} is always called. If a Python-side + * finalizer exists, {@code __del_builtin__} will be called after the + * Python-side finalizer has been processed. + *

+ *

+ * One can even implement both interfaces. + * If both interfaces are implemented, the {@code FinalizeTrigger} will + * call {@code __del__} first and then {@code __del_builtin__}. If a + * new-style subclass has an own, Python-side {@code __del__}-method, this + * overwrites the Java-implemented {@code __del__}, but not + * {@code __del_builtin__}, which will be called after the Python-side + * finalizer. + *

+ *

+ * If you are writing a custom built-in that shall directly + * extend {@link org.python.core.PyObject} and have a finalizer, you can simply + * extend {@link org.python.core.finalization.PyFinalizableObject} + * and overwrite its {@code __del__}-method. + * Follow the instructions below, starting at 4). + *

+ *

+ * If you want to extend some subclass of PyObject that does not yet implement + * this interface, you have to take care of the following steps: + *

    + *
  1. + * Let your subclass implement {@code FinalizablePyObject} + * (or {@link org.python.core.finalization.FinalizableBuiltin}). + *
  2. + *
  3. + * Let it have a member
    + * {@code public FinalizeTrigger finalizeTrigger;}
    + * Other scopes also work, but might fail with security managers. + *
  4. + *
  5. + * In every constructor initialize this member via
    + * {@code finalizeTrigger = FinalizeTrigger.makeTrigger(this);}
    + * or
    + * {@code FinalizeTrigger.ensureFinalizer(this);}
    + * The latter is a better abstraction, but slightly less performant, + * since it uses reflection. + *
  6. + *
  7. + * Write your {@code __del__}-method however you intend it. + * (or {@code __del__Builtin} if + * {@link org.python.core.finalization.FinalizableBuiltin} was used) + *
  8. + *
  9. + * (optional)
    + * If your finalizer resurrects the object (Python allows this) and you wish the + * finalizer to run again on next collection of the object:
    + * In the block where the resurrection occurs, let your {@code __del__}- or + * {@code __del_builtin__}-method call
    + * {@code FinalizeTrigger.ensureFinalizer(this);}. + *
  10. + *
+ *

+ *

+ * Note: Regarding to object resurrection, Jython currently behaves like CPython >= 3.4. + * That means the finalizer {@code __del__} or {@code __del_builtin__} is called only the + * first time an object gets gc'ed. If pre 3.4. behavior is required for some reason (i.e. + * have the finalizer called repeatedly on every collection after a resurrection), one can + * achieve this manually via step 5). + *

+ *

+ * It is possible to switch finalization on and off at any desired time for a certain object. + * This can be helpful if it is only necessary to have {@code __del__} or + * {@code __del_builtin__} called for certain configurations of an object. + *

+ *

+ * To turn off the finalizer, call
+ * {@code finalizeTrigger.clear();}
+ * To turn it on again, call
+ * {@code finalizeTrigger.trigger(this);} + *

+ */ + +public interface FinalizablePyObject extends HasFinalizeTrigger { + public void __del__(); +} diff --git a/src/org/python/core/finalization/FinalizablePyObjectDerived.java b/src/org/python/core/finalization/FinalizablePyObjectDerived.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizablePyObjectDerived.java @@ -0,0 +1,23 @@ +package org.python.core.finalization; + +/** + * This interface should never be used directly in any hand-written code. + * It should only appear in automatically generated {@code fooDerived}-classes. + * + * To use finalizers in hand-written classes read the instructions at + * {@link org.python.core.finalization.FinalizablePyObject}. + * + */ +public interface FinalizablePyObjectDerived extends HasFinalizeTrigger { + + /** + * {@code __del_builtin__} is the built-in's own finalizer, while + * {@code __del_derived__} refers to an instance's in-dict {@code __del__}. + * A FinalizeTrigger calls {@code __del_derived__} first and + * - if existent - {@code __del_builtin__} after that. A plain {@code __del__} + * would behave as overwritten by {@code __del_derived__}, i.e. won't be called + * if the type implements {@code FinalizablePyObjectDerived} while + * {@code __del_builtin__} is called in any case. + */ + public void __del_derived__(); +} diff --git a/src/org/python/core/finalization/FinalizeTrigger.java b/src/org/python/core/finalization/FinalizeTrigger.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizeTrigger.java @@ -0,0 +1,101 @@ +package org.python.core.finalization; + +import java.lang.reflect.Field; + +/** + * To use finalizers on {@code PyObject}s, read the documentation of + * {@link org.python.core.finalization.FinalizablePyObject}. + */ +public class FinalizeTrigger { + + /** + * This optional factory hook allows to replace the + * default {@code FinalizeTrigger}. It is f.i. needed by JyNI. + */ + public static FinalizeTriggerFactory factory; + + public static FinalizeTrigger makeTrigger(HasFinalizeTrigger toFinalize) { + if (factory != null) { + return factory.makeTrigger(toFinalize); + } else { + return new FinalizeTrigger(toFinalize); + } + } + + /** + * Recreates the {@code FinalizeTrigger} of the given object. This makes sure that + * once the resurrected object is gc'ed again, its {@code __del__}-method will be + * called again. + */ + public static void ensureFinalizer(HasFinalizeTrigger resurrect) { + FinalizeTrigger trigger = makeTrigger(resurrect); + setFinalizeTrigger(resurrect, trigger); + } + + public static void setFinalizeTrigger(HasFinalizeTrigger toFinalize, FinalizeTrigger trigger) { + Field triggerField; + try { + triggerField = toFinalize.getClass().getDeclaredField("finalizeTrigger"); + } catch (NoSuchFieldException nfe) { + throw new IllegalArgumentException(toFinalize.getClass()+" must have a field finalizeTrigger."); + } + try { + triggerField.set(toFinalize, trigger); + } catch (IllegalAccessException iae) { + try { + triggerField.setAccessible(true); + triggerField.set(toFinalize, trigger); + } catch (Exception e) { + throw new IllegalArgumentException("finalizeTrigger in "+toFinalize.getClass()+" must be accessible."); + } + } + } + + public static FinalizeTrigger getFinalizeTrigger(HasFinalizeTrigger toFinalize) { + Field triggerField; + try { + triggerField = toFinalize.getClass().getDeclaredField("finalizeTrigger"); + } catch (NoSuchFieldException nfe) { + throw new IllegalArgumentException(toFinalize.getClass()+" must have a field finalizeTrigger."); + } + try { + return (FinalizeTrigger) triggerField.get(toFinalize); + } catch (IllegalAccessException iae) { + try { + triggerField.setAccessible(true); + return (FinalizeTrigger) triggerField.get(toFinalize); + } catch (Exception e) { + throw new IllegalArgumentException("finalizeTrigger in "+toFinalize.getClass()+" must be accessible."); + } + } + } + + + protected HasFinalizeTrigger toFinalize; + + public void clear() { + toFinalize = null; + } + + public void trigger(HasFinalizeTrigger toFinalize) + { + this.toFinalize = toFinalize; + } + + protected FinalizeTrigger(HasFinalizeTrigger toFinalize) { + this.toFinalize = toFinalize; + } + + protected void finalize() throws Throwable { + if (toFinalize != null) { + if (toFinalize instanceof FinalizablePyObjectDerived) { + ((FinalizablePyObjectDerived) toFinalize).__del_derived__(); + } else if (toFinalize instanceof FinalizablePyObject) { + ((FinalizablePyObject) toFinalize).__del__(); + } + if (toFinalize instanceof FinalizableBuiltin) { + ((FinalizableBuiltin) toFinalize).__del_builtin__(); + } + } + } +} diff --git a/src/org/python/core/finalization/FinalizeTriggerFactory.java b/src/org/python/core/finalization/FinalizeTriggerFactory.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/FinalizeTriggerFactory.java @@ -0,0 +1,6 @@ +package org.python.core.finalization; + +public interface FinalizeTriggerFactory { + + public FinalizeTrigger makeTrigger(HasFinalizeTrigger toFinalize); +} diff --git a/src/org/python/core/finalization/HasFinalizeTrigger.java b/src/org/python/core/finalization/HasFinalizeTrigger.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/HasFinalizeTrigger.java @@ -0,0 +1,13 @@ +package org.python.core.finalization; + +/** + * This is a pure marker-interface to indicate that a + * {@link org.python.core.PyObject} has a field declaration + * {@code FinalizeTrigger finalizeTrigger;} + * and thus can be treated by Jython's finalization API. + * + * For detailed instructions how to use finalizers in Jython, see + * {@link org.python.core.finalization.FinalizablePyObject}. + */ +public interface HasFinalizeTrigger { +} diff --git a/src/org/python/core/finalization/PyFinalizableObject.java b/src/org/python/core/finalization/PyFinalizableObject.java new file mode 100644 --- /dev/null +++ b/src/org/python/core/finalization/PyFinalizableObject.java @@ -0,0 +1,17 @@ +package org.python.core.finalization; + +import org.python.core.PyObject;; + +/** + * For detailed intructions how to use finalizers on PyObjects, + * read the documentation of {@link org.python.core.finalization.FinalizablePyObject}. + */ +public abstract class PyFinalizableObject extends PyObject implements FinalizablePyObject { + + public FinalizeTrigger finalizeTrigger; + + public PyFinalizableObject() { + super(); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } +} diff --git a/src/org/python/modules/PyStructDerived.java b/src/org/python/modules/PyStructDerived.java --- a/src/org/python/modules/PyStructDerived.java +++ b/src/org/python/modules/PyStructDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyStructDerived extends PyStruct implements Slotted { +public class PyStructDerived extends PyStruct implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype,format); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_collections/PyDefaultDictDerived.java b/src/org/python/modules/_collections/PyDefaultDictDerived.java --- a/src/org/python/modules/_collections/PyDefaultDictDerived.java +++ b/src/org/python/modules/_collections/PyDefaultDictDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyDefaultDictDerived extends PyDefaultDict implements Slotted { +public class PyDefaultDictDerived extends PyDefaultDict implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_collections/PyDequeDerived.java b/src/org/python/modules/_collections/PyDequeDerived.java --- a/src/org/python/modules/_collections/PyDequeDerived.java +++ b/src/org/python/modules/_collections/PyDequeDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyDequeDerived extends PyDeque implements Slotted { +public class PyDequeDerived extends PyDeque implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_csv/PyDialectDerived.java b/src/org/python/modules/_csv/PyDialectDerived.java --- a/src/org/python/modules/_csv/PyDialectDerived.java +++ b/src/org/python/modules/_csv/PyDialectDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyDialectDerived extends PyDialect implements Slotted { +public class PyDialectDerived extends PyDialect implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyDialectDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_functools/PyPartialDerived.java b/src/org/python/modules/_functools/PyPartialDerived.java --- a/src/org/python/modules/_functools/PyPartialDerived.java +++ b/src/org/python/modules/_functools/PyPartialDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyPartialDerived extends PyPartial implements Slotted { +public class PyPartialDerived extends PyPartial implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_io/PyFileIODerived.java b/src/org/python/modules/_io/PyFileIODerived.java --- a/src/org/python/modules/_io/PyFileIODerived.java +++ b/src/org/python/modules/_io/PyFileIODerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyFileIODerived extends PyFileIO implements Slotted { +public class PyFileIODerived extends PyFileIO implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyFileIODerived(PyType subtype,PyObject file,OpenMode mode,boolean closefd) { super(subtype,file,mode,closefd); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_io/PyIOBase.java b/src/org/python/modules/_io/PyIOBase.java --- a/src/org/python/modules/_io/PyIOBase.java +++ b/src/org/python/modules/_io/PyIOBase.java @@ -16,6 +16,8 @@ import org.python.core.PyType; import org.python.core.PyUnicode; import org.python.core.buffer.SimpleStringBuffer; +import org.python.core.finalization.FinalizableBuiltin; +import org.python.core.finalization.FinalizeTrigger; import org.python.core.io.FileIO; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; @@ -38,20 +40,24 @@ * in Python. */ @ExposedType(name = "_io._IOBase", doc = PyIOBase.doc) -public class PyIOBase extends PyObject { +public class PyIOBase extends PyObject implements FinalizableBuiltin { public static final PyType TYPE = PyType.fromClass(PyIOBase.class); /** The ioDelegate's closer object; ensures the stream is closed at shutdown */ private Closer closer; + + public FinalizeTrigger finalizeTrigger; protected PyIOBase() { this(TYPE); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } protected PyIOBase(PyType subtype) { super(subtype); closer = new Closer(this, Py.getSystemState()); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } /** @@ -726,10 +732,9 @@ } @Override - protected void finalize() throws Throwable { + public void __del_builtin__() { closer.dismiss(); invoke("close"); - super.finalize(); } /** Convenience method providing the exception in the _checkWhatever() methods. */ diff --git a/src/org/python/modules/_io/PyIOBaseDerived.java b/src/org/python/modules/_io/PyIOBaseDerived.java --- a/src/org/python/modules/_io/PyIOBaseDerived.java +++ b/src/org/python/modules/_io/PyIOBaseDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyIOBaseDerived extends PyIOBase implements Slotted { +public class PyIOBaseDerived extends PyIOBase implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyIOBaseDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_io/PyRawIOBaseDerived.java b/src/org/python/modules/_io/PyRawIOBaseDerived.java --- a/src/org/python/modules/_io/PyRawIOBaseDerived.java +++ b/src/org/python/modules/_io/PyRawIOBaseDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyRawIOBaseDerived extends PyRawIOBase implements Slotted { +public class PyRawIOBaseDerived extends PyRawIOBase implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyRawIOBaseDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/_weakref/ReferenceTypeDerived.java b/src/org/python/modules/_weakref/ReferenceTypeDerived.java --- a/src/org/python/modules/_weakref/ReferenceTypeDerived.java +++ b/src/org/python/modules/_weakref/ReferenceTypeDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ReferenceTypeDerived extends ReferenceType implements Slotted { +public class ReferenceTypeDerived extends ReferenceType implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype,gref,callback); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyBZ2CompressorDerived extends PyBZ2Compressor implements Slotted { +public class PyBZ2CompressorDerived extends PyBZ2Compressor implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyBZ2DecompressorDerived extends PyBZ2Decompressor implements Slotted { +public class PyBZ2DecompressorDerived extends PyBZ2Decompressor implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/bz2/PyBZ2File.java b/src/org/python/modules/bz2/PyBZ2File.java --- a/src/org/python/modules/bz2/PyBZ2File.java +++ b/src/org/python/modules/bz2/PyBZ2File.java @@ -24,6 +24,9 @@ import org.python.core.PySequence; import org.python.core.PyString; import org.python.core.PyType; +import org.python.core.finalization.FinalizablePyObject; +import org.python.core.finalization.FinalizableBuiltin; +import org.python.core.finalization.FinalizeTrigger; import org.python.core.io.BinaryIOWrapper; import org.python.core.io.BufferedReader; import org.python.core.io.BufferedWriter; @@ -37,7 +40,7 @@ import org.python.expose.ExposedType; @ExposedType(name = "bz2.BZ2File") -public class PyBZ2File extends PyObject { +public class PyBZ2File extends PyObject implements FinalizablePyObject, FinalizableBuiltin { public static final PyType TYPE = PyType.fromClass(PyBZ2File.class); private int buffering; @@ -58,20 +61,23 @@ private boolean needReadBufferInit = false; private boolean inReadMode = false; private boolean inWriteMode = false; + + public FinalizeTrigger finalizeTrigger; public PyBZ2File() { super(TYPE); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } public PyBZ2File(PyType subType) { super(subType); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } @Override - protected void finalize() throws Throwable { + public void __del_builtin__() { BZ2File_close(); - super.finalize(); } @ExposedNew @@ -151,6 +157,7 @@ } } + @Override @ExposedMethod public void __del__() { BZ2File_close(); diff --git a/src/org/python/modules/bz2/PyBZ2FileDerived.java b/src/org/python/modules/bz2/PyBZ2FileDerived.java --- a/src/org/python/modules/bz2/PyBZ2FileDerived.java +++ b/src/org/python/modules/bz2/PyBZ2FileDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyBZ2FileDerived extends PyBZ2File implements Slotted { +public class PyBZ2FileDerived extends PyBZ2File implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/PyTeeIteratorDerived.java b/src/org/python/modules/itertools/PyTeeIteratorDerived.java --- a/src/org/python/modules/itertools/PyTeeIteratorDerived.java +++ b/src/org/python/modules/itertools/PyTeeIteratorDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyTeeIteratorDerived extends PyTeeIterator implements Slotted { +public class PyTeeIteratorDerived extends PyTeeIterator implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/chainDerived.java b/src/org/python/modules/itertools/chainDerived.java --- a/src/org/python/modules/itertools/chainDerived.java +++ b/src/org/python/modules/itertools/chainDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class chainDerived extends chain implements Slotted { +public class chainDerived extends chain implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/combinationsDerived.java b/src/org/python/modules/itertools/combinationsDerived.java --- a/src/org/python/modules/itertools/combinationsDerived.java +++ b/src/org/python/modules/itertools/combinationsDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class combinationsDerived extends combinations implements Slotted { +public class combinationsDerived extends combinations implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java --- a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java +++ b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class combinationsWithReplacementDerived extends combinationsWithReplacement implements Slotted { +public class combinationsWithReplacementDerived extends combinationsWithReplacement implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/compressDerived.java b/src/org/python/modules/itertools/compressDerived.java --- a/src/org/python/modules/itertools/compressDerived.java +++ b/src/org/python/modules/itertools/compressDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class compressDerived extends compress implements Slotted { +public class compressDerived extends compress implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/countDerived.java b/src/org/python/modules/itertools/countDerived.java --- a/src/org/python/modules/itertools/countDerived.java +++ b/src/org/python/modules/itertools/countDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class countDerived extends count implements Slotted { +public class countDerived extends count implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/cycleDerived.java b/src/org/python/modules/itertools/cycleDerived.java --- a/src/org/python/modules/itertools/cycleDerived.java +++ b/src/org/python/modules/itertools/cycleDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class cycleDerived extends cycle implements Slotted { +public class cycleDerived extends cycle implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/dropwhileDerived.java b/src/org/python/modules/itertools/dropwhileDerived.java --- a/src/org/python/modules/itertools/dropwhileDerived.java +++ b/src/org/python/modules/itertools/dropwhileDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class dropwhileDerived extends dropwhile implements Slotted { +public class dropwhileDerived extends dropwhile implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/groupbyDerived.java b/src/org/python/modules/itertools/groupbyDerived.java --- a/src/org/python/modules/itertools/groupbyDerived.java +++ b/src/org/python/modules/itertools/groupbyDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class groupbyDerived extends groupby implements Slotted { +public class groupbyDerived extends groupby implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/ifilterDerived.java b/src/org/python/modules/itertools/ifilterDerived.java --- a/src/org/python/modules/itertools/ifilterDerived.java +++ b/src/org/python/modules/itertools/ifilterDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ifilterDerived extends ifilter implements Slotted { +public class ifilterDerived extends ifilter implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/ifilterfalseDerived.java b/src/org/python/modules/itertools/ifilterfalseDerived.java --- a/src/org/python/modules/itertools/ifilterfalseDerived.java +++ b/src/org/python/modules/itertools/ifilterfalseDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class ifilterfalseDerived extends ifilterfalse implements Slotted { +public class ifilterfalseDerived extends ifilterfalse implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/isliceDerived.java b/src/org/python/modules/itertools/isliceDerived.java --- a/src/org/python/modules/itertools/isliceDerived.java +++ b/src/org/python/modules/itertools/isliceDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class isliceDerived extends islice implements Slotted { +public class isliceDerived extends islice implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/izipDerived.java b/src/org/python/modules/itertools/izipDerived.java --- a/src/org/python/modules/itertools/izipDerived.java +++ b/src/org/python/modules/itertools/izipDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class izipDerived extends izip implements Slotted { +public class izipDerived extends izip implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/izipLongestDerived.java b/src/org/python/modules/itertools/izipLongestDerived.java --- a/src/org/python/modules/itertools/izipLongestDerived.java +++ b/src/org/python/modules/itertools/izipLongestDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class izipLongestDerived extends izipLongest implements Slotted { +public class izipLongestDerived extends izipLongest implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/permutationsDerived.java b/src/org/python/modules/itertools/permutationsDerived.java --- a/src/org/python/modules/itertools/permutationsDerived.java +++ b/src/org/python/modules/itertools/permutationsDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class permutationsDerived extends permutations implements Slotted { +public class permutationsDerived extends permutations implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/productDerived.java b/src/org/python/modules/itertools/productDerived.java --- a/src/org/python/modules/itertools/productDerived.java +++ b/src/org/python/modules/itertools/productDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class productDerived extends product implements Slotted { +public class productDerived extends product implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/repeatDerived.java b/src/org/python/modules/itertools/repeatDerived.java --- a/src/org/python/modules/itertools/repeatDerived.java +++ b/src/org/python/modules/itertools/repeatDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class repeatDerived extends repeat implements Slotted { +public class repeatDerived extends repeat implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/starmapDerived.java b/src/org/python/modules/itertools/starmapDerived.java --- a/src/org/python/modules/itertools/starmapDerived.java +++ b/src/org/python/modules/itertools/starmapDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class starmapDerived extends starmap implements Slotted { +public class starmapDerived extends starmap implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/itertools/takewhileDerived.java b/src/org/python/modules/itertools/takewhileDerived.java --- a/src/org/python/modules/itertools/takewhileDerived.java +++ b/src/org/python/modules/itertools/takewhileDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class takewhileDerived extends takewhile implements Slotted { +public class takewhileDerived extends takewhile implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/random/PyRandomDerived.java b/src/org/python/modules/random/PyRandomDerived.java --- a/src/org/python/modules/random/PyRandomDerived.java +++ b/src/org/python/modules/random/PyRandomDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyRandomDerived extends PyRandom implements Slotted { +public class PyRandomDerived extends PyRandom implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/thread/PyLocalDerived.java b/src/org/python/modules/thread/PyLocalDerived.java --- a/src/org/python/modules/thread/PyLocalDerived.java +++ b/src/org/python/modules/thread/PyLocalDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class PyLocalDerived extends PyLocal implements Slotted { +public class PyLocalDerived extends PyLocal implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,9 +20,24 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + public PyLocalDerived(PyType subtype) { super(subtype); slots=new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -979,6 +998,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/org/python/modules/zipimport/zipimporterDerived.java b/src/org/python/modules/zipimport/zipimporterDerived.java --- a/src/org/python/modules/zipimport/zipimporterDerived.java +++ b/src/org/python/modules/zipimport/zipimporterDerived.java @@ -3,8 +3,12 @@ import java.io.Serializable; import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived; -public class zipimporterDerived extends zipimporter implements Slotted { +public class zipimporterDerived extends zipimporter implements Slotted,FinalizablePyObjectDerived { + + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +20,18 @@ private PyObject[]slots; + public void __del_derived__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__del__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } + private PyObject dict; public PyObject fastGetDict() { @@ -29,6 +45,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { dict=newDict; + if (dict.__finditem__(PyString.fromInterned("__del__"))!=null&&finalizeTrigger==null) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); } @@ -43,6 +62,9 @@ super(subtype); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger=FinalizeTrigger.makeTrigger(this); + } } public PyString __str__() { @@ -1003,6 +1025,8 @@ PyObject impl=self_type.lookup("__setattr__"); if (impl!=null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); diff --git a/src/templates/gderived-defs b/src/templates/gderived-defs --- a/src/templates/gderived-defs +++ b/src/templates/gderived-defs @@ -4,8 +4,11 @@ package org.python.core; import java.io.Serializable; + import org.python.core.finalization.FinalizeTrigger; + import org.python.core.finalization.FinalizablePyObjectDerived; - public class `concat`(`base,Derived) extends `base implements Slotted { + public class `concat`(`base,Derived) extends `base implements Slotted, FinalizablePyObjectDerived { + public FinalizeTrigger finalizeTrigger; public PyObject getSlot(int index) { return slots[index]; @@ -16,6 +19,18 @@ } private PyObject[] slots; + + public void __del_derived__() { + PyType self_type = getType(); + PyObject impl = self_type.lookup("__del__"); + if (impl != null) { + impl.__get__(this, self_type).__call__(); + } + } + + public void __ensure_finalizer__() { + FinalizeTrigger.ensureFinalizer(this); + } `decls; } @@ -81,6 +96,9 @@ public void setDict(PyObject newDict) { if (newDict instanceof PyStringMap || newDict instanceof PyDictionary ) { dict = newDict; + if (dict.__finditem__(PyString.fromInterned("__del__")) != null && finalizeTrigger == null) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } else { throw Py.TypeError("__dict__ must be set to a Dictionary " + newDict.getClass().getName()); @@ -96,6 +114,9 @@ public `concat`(`base,Derived)(PyType subtype,`extraargs) { super(subtype,`extra); slots = new PyObject[subtype.getNumSlots()]; + if (subtype.needsFinalizer()) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } define: (ClassBodyDeclarations)ctr_userdict @@ -103,6 +124,9 @@ super(subtype,`extra); slots = new PyObject[subtype.getNumSlots()]; dict = subtype.instDict(); + if (subtype.needsFinalizer()) { + finalizeTrigger = FinalizeTrigger.makeTrigger(this); + } } define: (ClassBodyDeclarations)toString diff --git a/src/templates/gderived.py b/src/templates/gderived.py --- a/src/templates/gderived.py +++ b/src/templates/gderived.py @@ -8,7 +8,7 @@ import directives import java_parser import java_templating -from java_templating import JavaTemplate,jast_make,jast +from java_templating import JavaTemplate, jast_make, jast org_python_dir = os.path.join(os.path.dirname(os.path.abspath(scriptdir)), 'org', 'python') @@ -19,22 +19,24 @@ package org.python.%s; import java.io.Serializable; -import org.python.core.*;""" +import org.python.core.*; +import org.python.core.finalization.FinalizeTrigger; +import org.python.core.finalization.FinalizablePyObjectDerived;""" modif_re = re.compile(r"(?:\((\w+)\))?(\w+)") # os.path.samefile unavailable on Windows before Python v3.2 -if hasattr(os.path,"samefile"): +if hasattr(os.path, "samefile"): # Good: available on this platform os_path_samefile = os.path.samefile else: - def os_path_samefile(a,b): + def os_path_samefile(a, b): 'Files are considered the same if their absolute paths are equal' return os.path.abspath(a)==os.path.abspath(b) class Gen: - priority_order = ['require','define','base_class', + priority_order = ['require', 'define', 'base_class', 'want_dict', 'ctr', 'incl', @@ -44,7 +46,7 @@ 'no_toString' ] - def __init__(self,bindings=None,priority_order=None): + def __init__(self, bindings=None, priority_order=None): if bindings is None: self.global_bindings = { 'csub': java_templating.csub, 'concat': java_templating.concat, @@ -64,35 +66,35 @@ self.no_toString = False self.ctr_done = 0 - def debug(self,bindings): - for name,val in bindings.items(): - if isinstance(val,JavaTemplate): + def debug(self, bindings): + for name, val in bindings.items(): + if isinstance(val, JavaTemplate): print "%s:" % name print val.texpand({}) - def invalid(self,dire,value): - raise Exception,"invalid '%s': %s" % (dire,value) + def invalid(self, dire, value): + raise Exception,"invalid '%s': %s" % (dire, value) - def get_aux(self,name): + def get_aux(self, name): if self.auxiliary is None: - aux_gen = Gen(priority_order=['require','define']) - directives.execute(directives.load(os.path.join(scriptdir,'gderived-defs')),aux_gen) + aux_gen = Gen(priority_order=['require', 'define']) + directives.execute(directives.load(os.path.join(scriptdir, 'gderived-defs')), aux_gen) self.auxiliary = aux_gen.global_bindings return self.auxiliary[name] - def dire_require(self,name,parm,body): + def dire_require(self, name, parm, body): if body is not None: - self.invalid('require','non-empty body') - sub_gen = Gen(bindings=self.global_bindings, priority__order=['require','define']) - directives.execute(directives.load(parm.strip()),sub_gen) + self.invalid('require', 'non-empty body') + sub_gen = Gen(bindings=self.global_bindings, priority__order=['require', 'define']) + directives.execute(directives.load(parm.strip()), sub_gen) - def dire_define(self,name,parm,body): + def dire_define(self, name, parm, body): parms = parm.split() if not parms: - self.invalid('define',parm) + self.invalid('define', parm) parsed_name = modif_re.match(parms[0]) if not parsed_name: - self.invalid('define',parm) + self.invalid('define', parm) templ_kind = parsed_name.group(1) templ_name = parsed_name.group(2) if templ_kind is None: @@ -104,40 +106,40 @@ start = templ_kind) self.global_bindings[templ_name] = templ - def dire_base_class(self,name,parm,body): + def dire_base_class(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') if self.base_class is None: self.base_class = JavaTemplate(parm.strip()) self.global_bindings['base'] = self.base_class - def dire_want_dict(self,name,parm,body): + def dire_want_dict(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') if self.want_dict is None: self.want_dict = {"true": 1, "false": 0}[parm.strip()] - def dire_no_toString(self,name,parm,body): + def dire_no_toString(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') self.no_toString = True - def dire_incl(self,name,parm,body): + def dire_incl(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') directives.execute(directives.load(parm.strip()+'.derived'),self) - def dire_ctr(self,name,parm,body): + def dire_ctr(self, name, parm, body): if self.ctr_done: return if body is not None: - self.invalid(name,"non-empty body") + self.invalid(name, "non-empty body") if self.want_dict: self.add_decl(self.get_aux('userdict')) ctr = self.get_aux('ctr_userdict') else: ctr = self.get_aux('ctr') - extraargs = JavaTemplate(parm.strip(),start="FormalParameterListOpt") + extraargs = JavaTemplate(parm.strip(), start="FormalParameterListOpt") def visit(node): if isinstance(node, jast.VariableDeclaratorId): yield node.Identifier @@ -145,20 +147,20 @@ for child in node.children: for x in visit(child): yield x - extra = jast_make(jast.Expressions, [jast_make(jast.Primary,Identifier=x,ArgumentsOpt=None) for x in visit(extraargs.fragment)]) + extra = jast_make(jast.Expressions, [jast_make(jast.Primary, Identifier=x, ArgumentsOpt=None) for x in visit(extraargs.fragment)]) extra = JavaTemplate(extra) self.add_decl(ctr.tbind({'base': self.base_class, 'extraargs': extraargs, 'extra': extra})) self.ctr_done = 1 - def add_decl(self,templ): + def add_decl(self, templ): pair = self.get_aux('pair') self.decls = pair.tbind({'trailer': self.decls, 'last': templ}) - def dire_unary1(self,name,parm,body): + def dire_unary1(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') parms = parm.split() - if len(parms) not in (1,2,3): - self.invalid(name,parm) + if len(parms) not in (1, 2, 3): + self.invalid(name, parm) meth_name = parms[0] if len(parms) == 1: unary_body = self.get_aux('unary') @@ -176,28 +178,28 @@ 'rettype': JavaTemplate(rettype_class)})) - def dire_binary(self,name,parm,body): + def dire_binary(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') meth_names = parm.split() binary_body = self.get_aux('binary') for meth_name in meth_names: self.add_decl(binary_body.tbind({'binary': JavaTemplate(meth_name)})) - def dire_ibinary(self,name,parm,body): + def dire_ibinary(self, name, parm, body): if body is not None: - self.invalid(name,'non-empty body') + self.invalid(name, 'non-empty body') meth_names = parm.split() binary_body = self.get_aux('ibinary') for meth_name in meth_names: self.add_decl(binary_body.tbind({'binary': JavaTemplate(meth_name)})) - def dire_rest(self,name,parm,body): + def dire_rest(self, name, parm, body): if parm: - self.invalid(name,'non-empty parm') + self.invalid(name, 'non-empty parm') if body is None: return - self.add_decl(JavaTemplate(body,start='ClassBodyDeclarations')) + self.add_decl(JavaTemplate(body, start='ClassBodyDeclarations')) def generate(self): if not self.no_toString: @@ -209,10 +211,10 @@ if (lazy and os.path.exists(outfile) and os.stat(fn).st_mtime < os.stat(outfile).st_mtime): - return + return print 'Processing %s into %s' % (fn, outfile) gen = Gen() - directives.execute(directives.load(fn),gen) + directives.execute(directives.load(fn), gen) result = gen.generate() result = hack_derived_header(outfile, result) print >> open(outfile, 'w'), result @@ -240,30 +242,29 @@ header = DERIVED_HEADER % '.'.join(dirs) result[0:num - 1] = header.splitlines() break + + return '\n'.join(result) - return '\n'.join(result) - + if __name__ == '__main__': from gexpose import load_mappings, usage lazy = False if len(sys.argv) > 4: usage() - sys.exit(1) + sys.exit(1) if len(sys.argv) >= 2: - if '--help' in sys.argv: - usage() - sys.exit(0) - elif '--lazy' in sys.argv: - lazy = True - sys.argv.remove('--lazy') + if '--help' in sys.argv: + usage() + sys.exit(0) + elif '--lazy' in sys.argv: + lazy = True + sys.argv.remove('--lazy') if len(sys.argv) == 1: - for template, mapping in load_mappings().items(): - if template.endswith('derived'): - process(mapping[0], mapping[1], lazy) + for template, mapping in load_mappings().items(): + if template.endswith('derived'): + process(mapping[0], mapping[1], lazy) elif len(sys.argv) == 2: - mapping = load_mappings()[sys.argv[1]] + mapping = load_mappings()[sys.argv[1]] process(mapping[0], mapping[1], lazy) else: process(sys.argv[1], sys.argv[2], lazy) - - diff --git a/src/templates/object.derived b/src/templates/object.derived --- a/src/templates/object.derived +++ b/src/templates/object.derived @@ -318,6 +318,8 @@ PyObject impl = self_type.lookup("__setattr__"); if (impl != null) { impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + //CPython does not support instance-acquired finalizers. + //So we don't check for __del__ here. return; } super.__setattr__(name,value); @@ -429,4 +431,3 @@ } return super.__coerce_ex__(o); } - -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Thu Sep 4 06:35:44 2014 From: jython-checkins at python.org (jim.baker) Date: Thu, 4 Sep 2014 06:35:44 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Modified_=5F=5Fensure=5Ffin?= =?utf-8?q?alizer=5F=5F_to_work_without_using_reflection_and_added_some?= Message-ID: <3hpTjD3LkVz7Lkc@mail.python.org> http://hg.python.org/jython/rev/54f36c4c72d1 changeset: 7364:54f36c4c72d1 parent: 7362:5397c1f405c5 user: Stefan Richthofer date: Thu Aug 28 06:06:02 2014 +0200 summary: Modified __ensure_finalizer__ to work without using reflection and added some paragraphs to the documentation in FinalizablePyObject (stating use cases fo __ensure_finalizer__ and specifying that it is not possible to overwrite __ensure_finalizer__ on Python side). files: src/org/python/antlr/ast/AssertDerived.java | 2 +- src/org/python/antlr/ast/AssignDerived.java | 2 +- src/org/python/antlr/ast/AttributeDerived.java | 2 +- src/org/python/antlr/ast/AugAssignDerived.java | 2 +- src/org/python/antlr/ast/BinOpDerived.java | 2 +- src/org/python/antlr/ast/BoolOpDerived.java | 2 +- src/org/python/antlr/ast/BreakDerived.java | 2 +- src/org/python/antlr/ast/CallDerived.java | 2 +- src/org/python/antlr/ast/ClassDefDerived.java | 2 +- src/org/python/antlr/ast/CompareDerived.java | 2 +- src/org/python/antlr/ast/ContinueDerived.java | 2 +- src/org/python/antlr/ast/DeleteDerived.java | 2 +- src/org/python/antlr/ast/DictDerived.java | 2 +- src/org/python/antlr/ast/EllipsisDerived.java | 2 +- src/org/python/antlr/ast/ExceptHandlerDerived.java | 2 +- src/org/python/antlr/ast/ExecDerived.java | 2 +- src/org/python/antlr/ast/ExprDerived.java | 2 +- src/org/python/antlr/ast/ExpressionDerived.java | 2 +- src/org/python/antlr/ast/ExtSliceDerived.java | 2 +- src/org/python/antlr/ast/ForDerived.java | 2 +- src/org/python/antlr/ast/FunctionDefDerived.java | 2 +- src/org/python/antlr/ast/GeneratorExpDerived.java | 2 +- src/org/python/antlr/ast/GlobalDerived.java | 2 +- src/org/python/antlr/ast/IfDerived.java | 2 +- src/org/python/antlr/ast/IfExpDerived.java | 2 +- src/org/python/antlr/ast/ImportDerived.java | 2 +- src/org/python/antlr/ast/ImportFromDerived.java | 2 +- src/org/python/antlr/ast/IndexDerived.java | 2 +- src/org/python/antlr/ast/InteractiveDerived.java | 2 +- src/org/python/antlr/ast/LambdaDerived.java | 2 +- src/org/python/antlr/ast/ListCompDerived.java | 2 +- src/org/python/antlr/ast/ListDerived.java | 2 +- src/org/python/antlr/ast/ModuleDerived.java | 2 +- src/org/python/antlr/ast/NameDerived.java | 2 +- src/org/python/antlr/ast/NumDerived.java | 2 +- src/org/python/antlr/ast/PassDerived.java | 2 +- src/org/python/antlr/ast/PrintDerived.java | 2 +- src/org/python/antlr/ast/RaiseDerived.java | 2 +- src/org/python/antlr/ast/ReprDerived.java | 2 +- src/org/python/antlr/ast/ReturnDerived.java | 2 +- src/org/python/antlr/ast/SliceDerived.java | 2 +- src/org/python/antlr/ast/StrDerived.java | 2 +- src/org/python/antlr/ast/SubscriptDerived.java | 2 +- src/org/python/antlr/ast/SuiteDerived.java | 2 +- src/org/python/antlr/ast/TryExceptDerived.java | 2 +- src/org/python/antlr/ast/TryFinallyDerived.java | 2 +- src/org/python/antlr/ast/TupleDerived.java | 2 +- src/org/python/antlr/ast/UnaryOpDerived.java | 2 +- src/org/python/antlr/ast/WhileDerived.java | 2 +- src/org/python/antlr/ast/WithDerived.java | 2 +- src/org/python/antlr/ast/YieldDerived.java | 2 +- src/org/python/antlr/ast/aliasDerived.java | 2 +- src/org/python/antlr/ast/argumentsDerived.java | 2 +- src/org/python/antlr/ast/comprehensionDerived.java | 2 +- src/org/python/antlr/ast/keywordDerived.java | 2 +- src/org/python/antlr/op/AddDerived.java | 2 +- src/org/python/antlr/op/AndDerived.java | 2 +- src/org/python/antlr/op/AugLoadDerived.java | 2 +- src/org/python/antlr/op/AugStoreDerived.java | 2 +- src/org/python/antlr/op/BitAndDerived.java | 2 +- src/org/python/antlr/op/BitOrDerived.java | 2 +- src/org/python/antlr/op/BitXorDerived.java | 2 +- src/org/python/antlr/op/DelDerived.java | 2 +- src/org/python/antlr/op/DivDerived.java | 2 +- src/org/python/antlr/op/EqDerived.java | 2 +- src/org/python/antlr/op/FloorDivDerived.java | 2 +- src/org/python/antlr/op/GtDerived.java | 2 +- src/org/python/antlr/op/GtEDerived.java | 2 +- src/org/python/antlr/op/InDerived.java | 2 +- src/org/python/antlr/op/InvertDerived.java | 2 +- src/org/python/antlr/op/IsDerived.java | 2 +- src/org/python/antlr/op/IsNotDerived.java | 2 +- src/org/python/antlr/op/LShiftDerived.java | 2 +- src/org/python/antlr/op/LoadDerived.java | 2 +- src/org/python/antlr/op/LtDerived.java | 2 +- src/org/python/antlr/op/LtEDerived.java | 2 +- src/org/python/antlr/op/ModDerived.java | 2 +- src/org/python/antlr/op/MultDerived.java | 2 +- src/org/python/antlr/op/NotDerived.java | 2 +- src/org/python/antlr/op/NotEqDerived.java | 2 +- src/org/python/antlr/op/NotInDerived.java | 2 +- src/org/python/antlr/op/OrDerived.java | 2 +- src/org/python/antlr/op/ParamDerived.java | 2 +- src/org/python/antlr/op/PowDerived.java | 2 +- src/org/python/antlr/op/RShiftDerived.java | 2 +- src/org/python/antlr/op/StoreDerived.java | 2 +- src/org/python/antlr/op/SubDerived.java | 2 +- src/org/python/antlr/op/UAddDerived.java | 2 +- src/org/python/antlr/op/USubDerived.java | 2 +- src/org/python/core/ClasspathPyImporterDerived.java | 2 +- src/org/python/core/PyArrayDerived.java | 2 +- src/org/python/core/PyBaseExceptionDerived.java | 2 +- src/org/python/core/PyByteArrayDerived.java | 2 +- src/org/python/core/PyClassMethodDerived.java | 2 +- src/org/python/core/PyComplexDerived.java | 2 +- src/org/python/core/PyDictionaryDerived.java | 2 +- src/org/python/core/PyEnumerateDerived.java | 2 +- src/org/python/core/PyFileDerived.java | 2 +- src/org/python/core/PyFloatDerived.java | 2 +- src/org/python/core/PyFrozenSetDerived.java | 2 +- src/org/python/core/PyInstance.java | 2 +- src/org/python/core/PyIntegerDerived.java | 2 +- src/org/python/core/PyListDerived.java | 2 +- src/org/python/core/PyLongDerived.java | 2 +- src/org/python/core/PyModuleDerived.java | 2 +- src/org/python/core/PyObjectDerived.java | 2 +- src/org/python/core/PyPropertyDerived.java | 2 +- src/org/python/core/PySetDerived.java | 2 +- src/org/python/core/PyStringDerived.java | 2 +- src/org/python/core/PySuperDerived.java | 2 +- src/org/python/core/PyTupleDerived.java | 2 +- src/org/python/core/PyTypeDerived.java | 2 +- src/org/python/core/PyUnicodeDerived.java | 2 +- src/org/python/core/finalization/FinalizablePyObject.java | 19 ++++++++++ src/org/python/modules/PyStructDerived.java | 2 +- src/org/python/modules/_collections/PyDefaultDictDerived.java | 2 +- src/org/python/modules/_collections/PyDequeDerived.java | 2 +- src/org/python/modules/_csv/PyDialectDerived.java | 2 +- src/org/python/modules/_functools/PyPartialDerived.java | 2 +- src/org/python/modules/_io/PyFileIODerived.java | 2 +- src/org/python/modules/_io/PyIOBaseDerived.java | 2 +- src/org/python/modules/_io/PyRawIOBaseDerived.java | 2 +- src/org/python/modules/_weakref/ReferenceTypeDerived.java | 2 +- src/org/python/modules/bz2/PyBZ2CompressorDerived.java | 2 +- src/org/python/modules/bz2/PyBZ2DecompressorDerived.java | 2 +- src/org/python/modules/bz2/PyBZ2FileDerived.java | 2 +- src/org/python/modules/itertools/PyTeeIteratorDerived.java | 2 +- src/org/python/modules/itertools/chainDerived.java | 2 +- src/org/python/modules/itertools/combinationsDerived.java | 2 +- src/org/python/modules/itertools/combinationsWithReplacementDerived.java | 2 +- src/org/python/modules/itertools/compressDerived.java | 2 +- src/org/python/modules/itertools/countDerived.java | 2 +- src/org/python/modules/itertools/cycleDerived.java | 2 +- src/org/python/modules/itertools/dropwhileDerived.java | 2 +- src/org/python/modules/itertools/groupbyDerived.java | 2 +- src/org/python/modules/itertools/ifilterDerived.java | 2 +- src/org/python/modules/itertools/ifilterfalseDerived.java | 2 +- src/org/python/modules/itertools/isliceDerived.java | 2 +- src/org/python/modules/itertools/izipDerived.java | 2 +- src/org/python/modules/itertools/izipLongestDerived.java | 2 +- src/org/python/modules/itertools/permutationsDerived.java | 2 +- src/org/python/modules/itertools/productDerived.java | 2 +- src/org/python/modules/itertools/repeatDerived.java | 2 +- src/org/python/modules/itertools/starmapDerived.java | 2 +- src/org/python/modules/itertools/takewhileDerived.java | 2 +- src/org/python/modules/random/PyRandomDerived.java | 2 +- src/org/python/modules/thread/PyLocalDerived.java | 2 +- src/org/python/modules/zipimport/zipimporterDerived.java | 2 +- src/templates/gderived-defs | 2 +- 149 files changed, 167 insertions(+), 148 deletions(-) diff --git a/src/org/python/antlr/ast/AssertDerived.java b/src/org/python/antlr/ast/AssertDerived.java --- a/src/org/python/antlr/ast/AssertDerived.java +++ b/src/org/python/antlr/ast/AssertDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/AssignDerived.java b/src/org/python/antlr/ast/AssignDerived.java --- a/src/org/python/antlr/ast/AssignDerived.java +++ b/src/org/python/antlr/ast/AssignDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/AttributeDerived.java b/src/org/python/antlr/ast/AttributeDerived.java --- a/src/org/python/antlr/ast/AttributeDerived.java +++ b/src/org/python/antlr/ast/AttributeDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/AugAssignDerived.java b/src/org/python/antlr/ast/AugAssignDerived.java --- a/src/org/python/antlr/ast/AugAssignDerived.java +++ b/src/org/python/antlr/ast/AugAssignDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/BinOpDerived.java b/src/org/python/antlr/ast/BinOpDerived.java --- a/src/org/python/antlr/ast/BinOpDerived.java +++ b/src/org/python/antlr/ast/BinOpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/BoolOpDerived.java b/src/org/python/antlr/ast/BoolOpDerived.java --- a/src/org/python/antlr/ast/BoolOpDerived.java +++ b/src/org/python/antlr/ast/BoolOpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/BreakDerived.java b/src/org/python/antlr/ast/BreakDerived.java --- a/src/org/python/antlr/ast/BreakDerived.java +++ b/src/org/python/antlr/ast/BreakDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/CallDerived.java b/src/org/python/antlr/ast/CallDerived.java --- a/src/org/python/antlr/ast/CallDerived.java +++ b/src/org/python/antlr/ast/CallDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ClassDefDerived.java b/src/org/python/antlr/ast/ClassDefDerived.java --- a/src/org/python/antlr/ast/ClassDefDerived.java +++ b/src/org/python/antlr/ast/ClassDefDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/CompareDerived.java b/src/org/python/antlr/ast/CompareDerived.java --- a/src/org/python/antlr/ast/CompareDerived.java +++ b/src/org/python/antlr/ast/CompareDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ContinueDerived.java b/src/org/python/antlr/ast/ContinueDerived.java --- a/src/org/python/antlr/ast/ContinueDerived.java +++ b/src/org/python/antlr/ast/ContinueDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/DeleteDerived.java b/src/org/python/antlr/ast/DeleteDerived.java --- a/src/org/python/antlr/ast/DeleteDerived.java +++ b/src/org/python/antlr/ast/DeleteDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/DictDerived.java b/src/org/python/antlr/ast/DictDerived.java --- a/src/org/python/antlr/ast/DictDerived.java +++ b/src/org/python/antlr/ast/DictDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/EllipsisDerived.java b/src/org/python/antlr/ast/EllipsisDerived.java --- a/src/org/python/antlr/ast/EllipsisDerived.java +++ b/src/org/python/antlr/ast/EllipsisDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExceptHandlerDerived.java b/src/org/python/antlr/ast/ExceptHandlerDerived.java --- a/src/org/python/antlr/ast/ExceptHandlerDerived.java +++ b/src/org/python/antlr/ast/ExceptHandlerDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExecDerived.java b/src/org/python/antlr/ast/ExecDerived.java --- a/src/org/python/antlr/ast/ExecDerived.java +++ b/src/org/python/antlr/ast/ExecDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExprDerived.java b/src/org/python/antlr/ast/ExprDerived.java --- a/src/org/python/antlr/ast/ExprDerived.java +++ b/src/org/python/antlr/ast/ExprDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExpressionDerived.java b/src/org/python/antlr/ast/ExpressionDerived.java --- a/src/org/python/antlr/ast/ExpressionDerived.java +++ b/src/org/python/antlr/ast/ExpressionDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExtSliceDerived.java b/src/org/python/antlr/ast/ExtSliceDerived.java --- a/src/org/python/antlr/ast/ExtSliceDerived.java +++ b/src/org/python/antlr/ast/ExtSliceDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ForDerived.java b/src/org/python/antlr/ast/ForDerived.java --- a/src/org/python/antlr/ast/ForDerived.java +++ b/src/org/python/antlr/ast/ForDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/FunctionDefDerived.java b/src/org/python/antlr/ast/FunctionDefDerived.java --- a/src/org/python/antlr/ast/FunctionDefDerived.java +++ b/src/org/python/antlr/ast/FunctionDefDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/GeneratorExpDerived.java b/src/org/python/antlr/ast/GeneratorExpDerived.java --- a/src/org/python/antlr/ast/GeneratorExpDerived.java +++ b/src/org/python/antlr/ast/GeneratorExpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/GlobalDerived.java b/src/org/python/antlr/ast/GlobalDerived.java --- a/src/org/python/antlr/ast/GlobalDerived.java +++ b/src/org/python/antlr/ast/GlobalDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/IfDerived.java b/src/org/python/antlr/ast/IfDerived.java --- a/src/org/python/antlr/ast/IfDerived.java +++ b/src/org/python/antlr/ast/IfDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/IfExpDerived.java b/src/org/python/antlr/ast/IfExpDerived.java --- a/src/org/python/antlr/ast/IfExpDerived.java +++ b/src/org/python/antlr/ast/IfExpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ImportDerived.java b/src/org/python/antlr/ast/ImportDerived.java --- a/src/org/python/antlr/ast/ImportDerived.java +++ b/src/org/python/antlr/ast/ImportDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ImportFromDerived.java b/src/org/python/antlr/ast/ImportFromDerived.java --- a/src/org/python/antlr/ast/ImportFromDerived.java +++ b/src/org/python/antlr/ast/ImportFromDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/IndexDerived.java b/src/org/python/antlr/ast/IndexDerived.java --- a/src/org/python/antlr/ast/IndexDerived.java +++ b/src/org/python/antlr/ast/IndexDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/InteractiveDerived.java b/src/org/python/antlr/ast/InteractiveDerived.java --- a/src/org/python/antlr/ast/InteractiveDerived.java +++ b/src/org/python/antlr/ast/InteractiveDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/LambdaDerived.java b/src/org/python/antlr/ast/LambdaDerived.java --- a/src/org/python/antlr/ast/LambdaDerived.java +++ b/src/org/python/antlr/ast/LambdaDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ListCompDerived.java b/src/org/python/antlr/ast/ListCompDerived.java --- a/src/org/python/antlr/ast/ListCompDerived.java +++ b/src/org/python/antlr/ast/ListCompDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ListDerived.java b/src/org/python/antlr/ast/ListDerived.java --- a/src/org/python/antlr/ast/ListDerived.java +++ b/src/org/python/antlr/ast/ListDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ModuleDerived.java b/src/org/python/antlr/ast/ModuleDerived.java --- a/src/org/python/antlr/ast/ModuleDerived.java +++ b/src/org/python/antlr/ast/ModuleDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/NameDerived.java b/src/org/python/antlr/ast/NameDerived.java --- a/src/org/python/antlr/ast/NameDerived.java +++ b/src/org/python/antlr/ast/NameDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/NumDerived.java b/src/org/python/antlr/ast/NumDerived.java --- a/src/org/python/antlr/ast/NumDerived.java +++ b/src/org/python/antlr/ast/NumDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/PassDerived.java b/src/org/python/antlr/ast/PassDerived.java --- a/src/org/python/antlr/ast/PassDerived.java +++ b/src/org/python/antlr/ast/PassDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/PrintDerived.java b/src/org/python/antlr/ast/PrintDerived.java --- a/src/org/python/antlr/ast/PrintDerived.java +++ b/src/org/python/antlr/ast/PrintDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/RaiseDerived.java b/src/org/python/antlr/ast/RaiseDerived.java --- a/src/org/python/antlr/ast/RaiseDerived.java +++ b/src/org/python/antlr/ast/RaiseDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ReprDerived.java b/src/org/python/antlr/ast/ReprDerived.java --- a/src/org/python/antlr/ast/ReprDerived.java +++ b/src/org/python/antlr/ast/ReprDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ReturnDerived.java b/src/org/python/antlr/ast/ReturnDerived.java --- a/src/org/python/antlr/ast/ReturnDerived.java +++ b/src/org/python/antlr/ast/ReturnDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/SliceDerived.java b/src/org/python/antlr/ast/SliceDerived.java --- a/src/org/python/antlr/ast/SliceDerived.java +++ b/src/org/python/antlr/ast/SliceDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/StrDerived.java b/src/org/python/antlr/ast/StrDerived.java --- a/src/org/python/antlr/ast/StrDerived.java +++ b/src/org/python/antlr/ast/StrDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/SubscriptDerived.java b/src/org/python/antlr/ast/SubscriptDerived.java --- a/src/org/python/antlr/ast/SubscriptDerived.java +++ b/src/org/python/antlr/ast/SubscriptDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/SuiteDerived.java b/src/org/python/antlr/ast/SuiteDerived.java --- a/src/org/python/antlr/ast/SuiteDerived.java +++ b/src/org/python/antlr/ast/SuiteDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/TryExceptDerived.java b/src/org/python/antlr/ast/TryExceptDerived.java --- a/src/org/python/antlr/ast/TryExceptDerived.java +++ b/src/org/python/antlr/ast/TryExceptDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/TryFinallyDerived.java b/src/org/python/antlr/ast/TryFinallyDerived.java --- a/src/org/python/antlr/ast/TryFinallyDerived.java +++ b/src/org/python/antlr/ast/TryFinallyDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/TupleDerived.java b/src/org/python/antlr/ast/TupleDerived.java --- a/src/org/python/antlr/ast/TupleDerived.java +++ b/src/org/python/antlr/ast/TupleDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/UnaryOpDerived.java b/src/org/python/antlr/ast/UnaryOpDerived.java --- a/src/org/python/antlr/ast/UnaryOpDerived.java +++ b/src/org/python/antlr/ast/UnaryOpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/WhileDerived.java b/src/org/python/antlr/ast/WhileDerived.java --- a/src/org/python/antlr/ast/WhileDerived.java +++ b/src/org/python/antlr/ast/WhileDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/WithDerived.java b/src/org/python/antlr/ast/WithDerived.java --- a/src/org/python/antlr/ast/WithDerived.java +++ b/src/org/python/antlr/ast/WithDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/YieldDerived.java b/src/org/python/antlr/ast/YieldDerived.java --- a/src/org/python/antlr/ast/YieldDerived.java +++ b/src/org/python/antlr/ast/YieldDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/aliasDerived.java b/src/org/python/antlr/ast/aliasDerived.java --- a/src/org/python/antlr/ast/aliasDerived.java +++ b/src/org/python/antlr/ast/aliasDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/argumentsDerived.java b/src/org/python/antlr/ast/argumentsDerived.java --- a/src/org/python/antlr/ast/argumentsDerived.java +++ b/src/org/python/antlr/ast/argumentsDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/comprehensionDerived.java b/src/org/python/antlr/ast/comprehensionDerived.java --- a/src/org/python/antlr/ast/comprehensionDerived.java +++ b/src/org/python/antlr/ast/comprehensionDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/keywordDerived.java b/src/org/python/antlr/ast/keywordDerived.java --- a/src/org/python/antlr/ast/keywordDerived.java +++ b/src/org/python/antlr/ast/keywordDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/AddDerived.java b/src/org/python/antlr/op/AddDerived.java --- a/src/org/python/antlr/op/AddDerived.java +++ b/src/org/python/antlr/op/AddDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/AndDerived.java b/src/org/python/antlr/op/AndDerived.java --- a/src/org/python/antlr/op/AndDerived.java +++ b/src/org/python/antlr/op/AndDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/AugLoadDerived.java b/src/org/python/antlr/op/AugLoadDerived.java --- a/src/org/python/antlr/op/AugLoadDerived.java +++ b/src/org/python/antlr/op/AugLoadDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/AugStoreDerived.java b/src/org/python/antlr/op/AugStoreDerived.java --- a/src/org/python/antlr/op/AugStoreDerived.java +++ b/src/org/python/antlr/op/AugStoreDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/BitAndDerived.java b/src/org/python/antlr/op/BitAndDerived.java --- a/src/org/python/antlr/op/BitAndDerived.java +++ b/src/org/python/antlr/op/BitAndDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/BitOrDerived.java b/src/org/python/antlr/op/BitOrDerived.java --- a/src/org/python/antlr/op/BitOrDerived.java +++ b/src/org/python/antlr/op/BitOrDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/BitXorDerived.java b/src/org/python/antlr/op/BitXorDerived.java --- a/src/org/python/antlr/op/BitXorDerived.java +++ b/src/org/python/antlr/op/BitXorDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/DelDerived.java b/src/org/python/antlr/op/DelDerived.java --- a/src/org/python/antlr/op/DelDerived.java +++ b/src/org/python/antlr/op/DelDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/DivDerived.java b/src/org/python/antlr/op/DivDerived.java --- a/src/org/python/antlr/op/DivDerived.java +++ b/src/org/python/antlr/op/DivDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/EqDerived.java b/src/org/python/antlr/op/EqDerived.java --- a/src/org/python/antlr/op/EqDerived.java +++ b/src/org/python/antlr/op/EqDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/FloorDivDerived.java b/src/org/python/antlr/op/FloorDivDerived.java --- a/src/org/python/antlr/op/FloorDivDerived.java +++ b/src/org/python/antlr/op/FloorDivDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/GtDerived.java b/src/org/python/antlr/op/GtDerived.java --- a/src/org/python/antlr/op/GtDerived.java +++ b/src/org/python/antlr/op/GtDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/GtEDerived.java b/src/org/python/antlr/op/GtEDerived.java --- a/src/org/python/antlr/op/GtEDerived.java +++ b/src/org/python/antlr/op/GtEDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/InDerived.java b/src/org/python/antlr/op/InDerived.java --- a/src/org/python/antlr/op/InDerived.java +++ b/src/org/python/antlr/op/InDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/InvertDerived.java b/src/org/python/antlr/op/InvertDerived.java --- a/src/org/python/antlr/op/InvertDerived.java +++ b/src/org/python/antlr/op/InvertDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/IsDerived.java b/src/org/python/antlr/op/IsDerived.java --- a/src/org/python/antlr/op/IsDerived.java +++ b/src/org/python/antlr/op/IsDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/IsNotDerived.java b/src/org/python/antlr/op/IsNotDerived.java --- a/src/org/python/antlr/op/IsNotDerived.java +++ b/src/org/python/antlr/op/IsNotDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/LShiftDerived.java b/src/org/python/antlr/op/LShiftDerived.java --- a/src/org/python/antlr/op/LShiftDerived.java +++ b/src/org/python/antlr/op/LShiftDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/LoadDerived.java b/src/org/python/antlr/op/LoadDerived.java --- a/src/org/python/antlr/op/LoadDerived.java +++ b/src/org/python/antlr/op/LoadDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/LtDerived.java b/src/org/python/antlr/op/LtDerived.java --- a/src/org/python/antlr/op/LtDerived.java +++ b/src/org/python/antlr/op/LtDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/LtEDerived.java b/src/org/python/antlr/op/LtEDerived.java --- a/src/org/python/antlr/op/LtEDerived.java +++ b/src/org/python/antlr/op/LtEDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/ModDerived.java b/src/org/python/antlr/op/ModDerived.java --- a/src/org/python/antlr/op/ModDerived.java +++ b/src/org/python/antlr/op/ModDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/MultDerived.java b/src/org/python/antlr/op/MultDerived.java --- a/src/org/python/antlr/op/MultDerived.java +++ b/src/org/python/antlr/op/MultDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/NotDerived.java b/src/org/python/antlr/op/NotDerived.java --- a/src/org/python/antlr/op/NotDerived.java +++ b/src/org/python/antlr/op/NotDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/NotEqDerived.java b/src/org/python/antlr/op/NotEqDerived.java --- a/src/org/python/antlr/op/NotEqDerived.java +++ b/src/org/python/antlr/op/NotEqDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/NotInDerived.java b/src/org/python/antlr/op/NotInDerived.java --- a/src/org/python/antlr/op/NotInDerived.java +++ b/src/org/python/antlr/op/NotInDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/OrDerived.java b/src/org/python/antlr/op/OrDerived.java --- a/src/org/python/antlr/op/OrDerived.java +++ b/src/org/python/antlr/op/OrDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/ParamDerived.java b/src/org/python/antlr/op/ParamDerived.java --- a/src/org/python/antlr/op/ParamDerived.java +++ b/src/org/python/antlr/op/ParamDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/PowDerived.java b/src/org/python/antlr/op/PowDerived.java --- a/src/org/python/antlr/op/PowDerived.java +++ b/src/org/python/antlr/op/PowDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/RShiftDerived.java b/src/org/python/antlr/op/RShiftDerived.java --- a/src/org/python/antlr/op/RShiftDerived.java +++ b/src/org/python/antlr/op/RShiftDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/StoreDerived.java b/src/org/python/antlr/op/StoreDerived.java --- a/src/org/python/antlr/op/StoreDerived.java +++ b/src/org/python/antlr/op/StoreDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/SubDerived.java b/src/org/python/antlr/op/SubDerived.java --- a/src/org/python/antlr/op/SubDerived.java +++ b/src/org/python/antlr/op/SubDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/UAddDerived.java b/src/org/python/antlr/op/UAddDerived.java --- a/src/org/python/antlr/op/UAddDerived.java +++ b/src/org/python/antlr/op/UAddDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/USubDerived.java b/src/org/python/antlr/op/USubDerived.java --- a/src/org/python/antlr/op/USubDerived.java +++ b/src/org/python/antlr/op/USubDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/ClasspathPyImporterDerived.java b/src/org/python/core/ClasspathPyImporterDerived.java --- a/src/org/python/core/ClasspathPyImporterDerived.java +++ b/src/org/python/core/ClasspathPyImporterDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public ClasspathPyImporterDerived(PyType subtype) { diff --git a/src/org/python/core/PyArrayDerived.java b/src/org/python/core/PyArrayDerived.java --- a/src/org/python/core/PyArrayDerived.java +++ b/src/org/python/core/PyArrayDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyBaseExceptionDerived.java b/src/org/python/core/PyBaseExceptionDerived.java --- a/src/org/python/core/PyBaseExceptionDerived.java +++ b/src/org/python/core/PyBaseExceptionDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyBaseExceptionDerived(PyType subtype) { diff --git a/src/org/python/core/PyByteArrayDerived.java b/src/org/python/core/PyByteArrayDerived.java --- a/src/org/python/core/PyByteArrayDerived.java +++ b/src/org/python/core/PyByteArrayDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyClassMethodDerived.java b/src/org/python/core/PyClassMethodDerived.java --- a/src/org/python/core/PyClassMethodDerived.java +++ b/src/org/python/core/PyClassMethodDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyComplexDerived.java b/src/org/python/core/PyComplexDerived.java --- a/src/org/python/core/PyComplexDerived.java +++ b/src/org/python/core/PyComplexDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyDictionaryDerived.java b/src/org/python/core/PyDictionaryDerived.java --- a/src/org/python/core/PyDictionaryDerived.java +++ b/src/org/python/core/PyDictionaryDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyEnumerateDerived.java b/src/org/python/core/PyEnumerateDerived.java --- a/src/org/python/core/PyEnumerateDerived.java +++ b/src/org/python/core/PyEnumerateDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyFileDerived.java b/src/org/python/core/PyFileDerived.java --- a/src/org/python/core/PyFileDerived.java +++ b/src/org/python/core/PyFileDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyFloatDerived.java b/src/org/python/core/PyFloatDerived.java --- a/src/org/python/core/PyFloatDerived.java +++ b/src/org/python/core/PyFloatDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyFrozenSetDerived.java b/src/org/python/core/PyFrozenSetDerived.java --- a/src/org/python/core/PyFrozenSetDerived.java +++ b/src/org/python/core/PyFrozenSetDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyInstance.java b/src/org/python/core/PyInstance.java --- a/src/org/python/core/PyInstance.java +++ b/src/org/python/core/PyInstance.java @@ -154,7 +154,7 @@ } public static void ensureFinalizer(PyObject[] args, String[] kws) { - FinalizeTrigger.ensureFinalizer((PyInstance) args[0]); + ((PyInstance) args[0]).finalizeTrigger = FinalizeTrigger.makeTrigger((PyInstance) args[0]); } private static JavaFunc makeFunction__ensure_finalizer__() { diff --git a/src/org/python/core/PyIntegerDerived.java b/src/org/python/core/PyIntegerDerived.java --- a/src/org/python/core/PyIntegerDerived.java +++ b/src/org/python/core/PyIntegerDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyListDerived.java b/src/org/python/core/PyListDerived.java --- a/src/org/python/core/PyListDerived.java +++ b/src/org/python/core/PyListDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyLongDerived.java b/src/org/python/core/PyLongDerived.java --- a/src/org/python/core/PyLongDerived.java +++ b/src/org/python/core/PyLongDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyModuleDerived.java b/src/org/python/core/PyModuleDerived.java --- a/src/org/python/core/PyModuleDerived.java +++ b/src/org/python/core/PyModuleDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyModuleDerived(PyType subtype) { diff --git a/src/org/python/core/PyObjectDerived.java b/src/org/python/core/PyObjectDerived.java --- a/src/org/python/core/PyObjectDerived.java +++ b/src/org/python/core/PyObjectDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyPropertyDerived.java b/src/org/python/core/PyPropertyDerived.java --- a/src/org/python/core/PyPropertyDerived.java +++ b/src/org/python/core/PyPropertyDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PySetDerived.java b/src/org/python/core/PySetDerived.java --- a/src/org/python/core/PySetDerived.java +++ b/src/org/python/core/PySetDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyStringDerived.java b/src/org/python/core/PyStringDerived.java --- a/src/org/python/core/PyStringDerived.java +++ b/src/org/python/core/PyStringDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PySuperDerived.java b/src/org/python/core/PySuperDerived.java --- a/src/org/python/core/PySuperDerived.java +++ b/src/org/python/core/PySuperDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyTupleDerived.java b/src/org/python/core/PyTupleDerived.java --- a/src/org/python/core/PyTupleDerived.java +++ b/src/org/python/core/PyTupleDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyTypeDerived.java b/src/org/python/core/PyTypeDerived.java --- a/src/org/python/core/PyTypeDerived.java +++ b/src/org/python/core/PyTypeDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyTypeDerived(PyType subtype) { diff --git a/src/org/python/core/PyUnicodeDerived.java b/src/org/python/core/PyUnicodeDerived.java --- a/src/org/python/core/PyUnicodeDerived.java +++ b/src/org/python/core/PyUnicodeDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/finalization/FinalizablePyObject.java b/src/org/python/core/finalization/FinalizablePyObject.java --- a/src/org/python/core/finalization/FinalizablePyObject.java +++ b/src/org/python/core/finalization/FinalizablePyObject.java @@ -62,6 +62,10 @@ * In the block where the resurrection occurs, let your {@code __del__}- or * {@code __del_builtin__}-method call
* {@code FinalizeTrigger.ensureFinalizer(this);}. + * If you implement {@code __del__} in Python and need this functionality, you can + * simply call {@code someObject.__ensure_finalizer__()}
+ * Note that this is Jython specific and should be surrounded by a {@code try/except} + * block to ensure compatibility with other Python implementations. * * *

@@ -73,6 +77,21 @@ * achieve this manually via step 5). *

*

+ * The built-in function {@code __ensure_finalizer__} is also useful if a class acquires a + * finalizer after instances have already been created. Usually only those instances that were + * created after their class acquired the finalizer will actually be finalized (in contrast to + * CPython). + * However, one can manually tell earlier created instances to become finalizable by + * calling {@code __ensure_finalizer__()} on them. As mentioned above, it is recommended to + * surround this with a {@code try/except} block to ensure compatibility with other Python + * implementations. + *

+ *

+ * Note that it is not possible to overwrite {@code __ensure_finalizer__} on Python side. + * If one overwrites {@code __ensure_finalizer__} on Python side, Jython will ignore the + * overwrite-implementation and still call the original one. + *

+ *

* It is possible to switch finalization on and off at any desired time for a certain object. * This can be helpful if it is only necessary to have {@code __del__} or * {@code __del_builtin__} called for certain configurations of an object. diff --git a/src/org/python/modules/PyStructDerived.java b/src/org/python/modules/PyStructDerived.java --- a/src/org/python/modules/PyStructDerived.java +++ b/src/org/python/modules/PyStructDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/_collections/PyDefaultDictDerived.java b/src/org/python/modules/_collections/PyDefaultDictDerived.java --- a/src/org/python/modules/_collections/PyDefaultDictDerived.java +++ b/src/org/python/modules/_collections/PyDefaultDictDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/_collections/PyDequeDerived.java b/src/org/python/modules/_collections/PyDequeDerived.java --- a/src/org/python/modules/_collections/PyDequeDerived.java +++ b/src/org/python/modules/_collections/PyDequeDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/_csv/PyDialectDerived.java b/src/org/python/modules/_csv/PyDialectDerived.java --- a/src/org/python/modules/_csv/PyDialectDerived.java +++ b/src/org/python/modules/_csv/PyDialectDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyDialectDerived(PyType subtype) { diff --git a/src/org/python/modules/_functools/PyPartialDerived.java b/src/org/python/modules/_functools/PyPartialDerived.java --- a/src/org/python/modules/_functools/PyPartialDerived.java +++ b/src/org/python/modules/_functools/PyPartialDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/_io/PyFileIODerived.java b/src/org/python/modules/_io/PyFileIODerived.java --- a/src/org/python/modules/_io/PyFileIODerived.java +++ b/src/org/python/modules/_io/PyFileIODerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyFileIODerived(PyType subtype,PyObject file,OpenMode mode,boolean closefd) { diff --git a/src/org/python/modules/_io/PyIOBaseDerived.java b/src/org/python/modules/_io/PyIOBaseDerived.java --- a/src/org/python/modules/_io/PyIOBaseDerived.java +++ b/src/org/python/modules/_io/PyIOBaseDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyIOBaseDerived(PyType subtype) { diff --git a/src/org/python/modules/_io/PyRawIOBaseDerived.java b/src/org/python/modules/_io/PyRawIOBaseDerived.java --- a/src/org/python/modules/_io/PyRawIOBaseDerived.java +++ b/src/org/python/modules/_io/PyRawIOBaseDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyRawIOBaseDerived(PyType subtype) { diff --git a/src/org/python/modules/_weakref/ReferenceTypeDerived.java b/src/org/python/modules/_weakref/ReferenceTypeDerived.java --- a/src/org/python/modules/_weakref/ReferenceTypeDerived.java +++ b/src/org/python/modules/_weakref/ReferenceTypeDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/bz2/PyBZ2FileDerived.java b/src/org/python/modules/bz2/PyBZ2FileDerived.java --- a/src/org/python/modules/bz2/PyBZ2FileDerived.java +++ b/src/org/python/modules/bz2/PyBZ2FileDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/PyTeeIteratorDerived.java b/src/org/python/modules/itertools/PyTeeIteratorDerived.java --- a/src/org/python/modules/itertools/PyTeeIteratorDerived.java +++ b/src/org/python/modules/itertools/PyTeeIteratorDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/chainDerived.java b/src/org/python/modules/itertools/chainDerived.java --- a/src/org/python/modules/itertools/chainDerived.java +++ b/src/org/python/modules/itertools/chainDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/combinationsDerived.java b/src/org/python/modules/itertools/combinationsDerived.java --- a/src/org/python/modules/itertools/combinationsDerived.java +++ b/src/org/python/modules/itertools/combinationsDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java --- a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java +++ b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/compressDerived.java b/src/org/python/modules/itertools/compressDerived.java --- a/src/org/python/modules/itertools/compressDerived.java +++ b/src/org/python/modules/itertools/compressDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/countDerived.java b/src/org/python/modules/itertools/countDerived.java --- a/src/org/python/modules/itertools/countDerived.java +++ b/src/org/python/modules/itertools/countDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/cycleDerived.java b/src/org/python/modules/itertools/cycleDerived.java --- a/src/org/python/modules/itertools/cycleDerived.java +++ b/src/org/python/modules/itertools/cycleDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/dropwhileDerived.java b/src/org/python/modules/itertools/dropwhileDerived.java --- a/src/org/python/modules/itertools/dropwhileDerived.java +++ b/src/org/python/modules/itertools/dropwhileDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/groupbyDerived.java b/src/org/python/modules/itertools/groupbyDerived.java --- a/src/org/python/modules/itertools/groupbyDerived.java +++ b/src/org/python/modules/itertools/groupbyDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/ifilterDerived.java b/src/org/python/modules/itertools/ifilterDerived.java --- a/src/org/python/modules/itertools/ifilterDerived.java +++ b/src/org/python/modules/itertools/ifilterDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/ifilterfalseDerived.java b/src/org/python/modules/itertools/ifilterfalseDerived.java --- a/src/org/python/modules/itertools/ifilterfalseDerived.java +++ b/src/org/python/modules/itertools/ifilterfalseDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/isliceDerived.java b/src/org/python/modules/itertools/isliceDerived.java --- a/src/org/python/modules/itertools/isliceDerived.java +++ b/src/org/python/modules/itertools/isliceDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/izipDerived.java b/src/org/python/modules/itertools/izipDerived.java --- a/src/org/python/modules/itertools/izipDerived.java +++ b/src/org/python/modules/itertools/izipDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/izipLongestDerived.java b/src/org/python/modules/itertools/izipLongestDerived.java --- a/src/org/python/modules/itertools/izipLongestDerived.java +++ b/src/org/python/modules/itertools/izipLongestDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/permutationsDerived.java b/src/org/python/modules/itertools/permutationsDerived.java --- a/src/org/python/modules/itertools/permutationsDerived.java +++ b/src/org/python/modules/itertools/permutationsDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/productDerived.java b/src/org/python/modules/itertools/productDerived.java --- a/src/org/python/modules/itertools/productDerived.java +++ b/src/org/python/modules/itertools/productDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/repeatDerived.java b/src/org/python/modules/itertools/repeatDerived.java --- a/src/org/python/modules/itertools/repeatDerived.java +++ b/src/org/python/modules/itertools/repeatDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/starmapDerived.java b/src/org/python/modules/itertools/starmapDerived.java --- a/src/org/python/modules/itertools/starmapDerived.java +++ b/src/org/python/modules/itertools/starmapDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/takewhileDerived.java b/src/org/python/modules/itertools/takewhileDerived.java --- a/src/org/python/modules/itertools/takewhileDerived.java +++ b/src/org/python/modules/itertools/takewhileDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/random/PyRandomDerived.java b/src/org/python/modules/random/PyRandomDerived.java --- a/src/org/python/modules/random/PyRandomDerived.java +++ b/src/org/python/modules/random/PyRandomDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/thread/PyLocalDerived.java b/src/org/python/modules/thread/PyLocalDerived.java --- a/src/org/python/modules/thread/PyLocalDerived.java +++ b/src/org/python/modules/thread/PyLocalDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyLocalDerived(PyType subtype) { diff --git a/src/org/python/modules/zipimport/zipimporterDerived.java b/src/org/python/modules/zipimport/zipimporterDerived.java --- a/src/org/python/modules/zipimport/zipimporterDerived.java +++ b/src/org/python/modules/zipimport/zipimporterDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/templates/gderived-defs b/src/templates/gderived-defs --- a/src/templates/gderived-defs +++ b/src/templates/gderived-defs @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } `decls; -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Thu Sep 4 06:35:45 2014 From: jython-checkins at python.org (jim.baker) Date: Thu, 4 Sep 2014 06:35:45 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fixed_some_more_tab_occurre?= =?utf-8?q?nces_and_refined_the_doc_of_FinalizeTriggerFactory?= Message-ID: <3hpTjF65WGz7Lk4@mail.python.org> http://hg.python.org/jython/rev/d84a896267cc changeset: 7365:d84a896267cc user: Stefan Richthofer date: Thu Aug 28 23:35:44 2014 +0200 summary: Fixed some more tab occurrences and refined the doc of FinalizeTriggerFactory and the factory hook in FinalizeTrigger. Instead of just pointing out that it is needed by JyNI, the doc now states that the hook is reserved for use by JyNI. This is neccessary because if another extension would use it, this would possibly interfere with JyNI, yielding unforeseeable results. And honestly I really can't imagine a usecase for it other than JyNI ;) files: src/org/python/core/PyInstance.java | 5 +++-- src/org/python/core/finalization/FinalizablePyObject.java | 2 +- src/org/python/core/finalization/FinalizeTrigger.java | 5 +++-- src/org/python/core/finalization/FinalizeTriggerFactory.java | 7 +++++-- src/templates/gderived-defs | 10 +++++----- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/org/python/core/PyInstance.java b/src/org/python/core/PyInstance.java --- a/src/org/python/core/PyInstance.java +++ b/src/org/python/core/PyInstance.java @@ -154,9 +154,10 @@ } public static void ensureFinalizer(PyObject[] args, String[] kws) { - ((PyInstance) args[0]).finalizeTrigger = FinalizeTrigger.makeTrigger((PyInstance) args[0]); + ((PyInstance) args[0]).finalizeTrigger = FinalizeTrigger.makeTrigger( + (PyInstance) args[0]); } - + private static JavaFunc makeFunction__ensure_finalizer__() { try { return new JavaFunc( diff --git a/src/org/python/core/finalization/FinalizablePyObject.java b/src/org/python/core/finalization/FinalizablePyObject.java --- a/src/org/python/core/finalization/FinalizablePyObject.java +++ b/src/org/python/core/finalization/FinalizablePyObject.java @@ -58,7 +58,7 @@ *

  • * (optional)
    * If your finalizer resurrects the object (Python allows this) and you wish the - * finalizer to run again on next collection of the object:
    + * finalizer to run again on next collection of the object:
    * In the block where the resurrection occurs, let your {@code __del__}- or * {@code __del_builtin__}-method call
    * {@code FinalizeTrigger.ensureFinalizer(this);}. diff --git a/src/org/python/core/finalization/FinalizeTrigger.java b/src/org/python/core/finalization/FinalizeTrigger.java --- a/src/org/python/core/finalization/FinalizeTrigger.java +++ b/src/org/python/core/finalization/FinalizeTrigger.java @@ -9,8 +9,9 @@ public class FinalizeTrigger { /** - * This optional factory hook allows to replace the - * default {@code FinalizeTrigger}. It is f.i. needed by JyNI. + * This factory hook is reserved for use by JyNI. + * It allows to replace the default {@code FinalizeTrigger}. + * JyNI needs it to support garbage collection. */ public static FinalizeTriggerFactory factory; diff --git a/src/org/python/core/finalization/FinalizeTriggerFactory.java b/src/org/python/core/finalization/FinalizeTriggerFactory.java --- a/src/org/python/core/finalization/FinalizeTriggerFactory.java +++ b/src/org/python/core/finalization/FinalizeTriggerFactory.java @@ -1,6 +1,9 @@ package org.python.core.finalization; +/** + * Reserved for use by JyNI. + */ public interface FinalizeTriggerFactory { - - public FinalizeTrigger makeTrigger(HasFinalizeTrigger toFinalize); + + public FinalizeTrigger makeTrigger(HasFinalizeTrigger toFinalize); } diff --git a/src/templates/gderived-defs b/src/templates/gderived-defs --- a/src/templates/gderived-defs +++ b/src/templates/gderived-defs @@ -17,11 +17,11 @@ public void setSlot(int index, PyObject value) { slots[index] = value; } - + private PyObject[] slots; - + public void __del_derived__() { - PyType self_type = getType(); + PyType self_type = getType(); PyObject impl = self_type.lookup("__del__"); if (impl != null) { impl.__get__(this, self_type).__call__(); @@ -44,7 +44,7 @@ if (impl != null) { PyObject res = impl.__get__(this,self_type).__call__(other); if (res == Py.NotImplemented) - return null; + return null; return res; } return super.`binary(other); @@ -56,7 +56,7 @@ if (impl != null) { PyObject res = impl.__get__(this,self_type).__call__(other); if (res == Py.NotImplemented) - return null; + return null; return res; } return super.`binary(other); -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Thu Sep 4 06:35:47 2014 From: jython-checkins at python.org (jim.baker) Date: Thu, 4 Sep 2014 06:35:47 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Changed_test=5Ffinalizers?= =?utf-8?q?=2Epy_to_avoid_plain_assert_statements_and_use_assertIn=2C?= Message-ID: <3hpTjH1fHhz7LlK@mail.python.org> http://hg.python.org/jython/rev/b3e0d7ee59fc changeset: 7366:b3e0d7ee59fc user: Stefan Richthofer date: Tue Sep 02 03:42:15 2014 +0200 summary: Changed test_finalizers.py to avoid plain assert statements and use assertIn, assertEqual etc instead. files: Lib/test/test_finalizers.py | 76 ++++++++++++------------ 1 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Lib/test/test_finalizers.py b/Lib/test/test_finalizers.py --- a/Lib/test/test_finalizers.py +++ b/Lib/test/test_finalizers.py @@ -198,14 +198,14 @@ A = DummyClassDel("A") A = None runGCIfJython() - assert("A finalized (DummyClassDel)" in finalizeMsgList) + self.assertIn("A finalized (DummyClassDel)", finalizeMsgList) def test_classAcquiresFinalizer_beforeInstanciation_oldStyleClass(self): DummyClass.__del__ = delClass B = DummyClass("B") B = None runGCIfJython() - assert("B finalized (acquired by class)" in finalizeMsgList) + self.assertIn("B finalized (acquired by class)", finalizeMsgList) del DummyClass.__del__ def test_classAcquiresFinalizer_afterInstanciation_oldStyleClass(self): @@ -218,7 +218,7 @@ pass C = None runGCIfJython() - assert("C finalized (acquired by class)" in finalizeMsgList) + self.assertIn("C finalized (acquired by class)", finalizeMsgList) del DummyClass.__del__ def test_instanceAcquiresFinalizer_bound_oldStyleClass(self): @@ -227,21 +227,21 @@ D.__del__ = dl D = None runGCIfJython() - assert("D finalized (DummyClassDel)" not in finalizeMsgList) - assert("D finalized (acquired by object)" in finalizeMsgList) + self.assertNotIn("D finalized (DummyClassDel)", finalizeMsgList) + self.assertIn("D finalized (acquired by object)", finalizeMsgList) def test_finalizer_builtin_newStyleClass(self): E = DummyClassDelNew("E") E = None runGCIfJython() - assert("E finalized (DummyClassDelNew)" in finalizeMsgList) + self.assertIn("E finalized (DummyClassDelNew)", finalizeMsgList) def test_classAcquiresFinalizer_beforeInstanciation_newStyleClass(self): DummyClassNew.__del__ = delClass F = DummyClassNew("F") F = None runGCIfJython() - assert("F finalized (acquired by class)" in finalizeMsgList) + self.assertIn("F finalized (acquired by class)", finalizeMsgList) del DummyClassNew.__del__ def test_classAcquiresFinalizer_afterInstanciation_newStyleClass(self): @@ -254,7 +254,7 @@ pass G = None runGCIfJython() - assert("G finalized (acquired by class)" in finalizeMsgList) + self.assertIn("G finalized (acquired by class)", finalizeMsgList) del DummyClassNew.__del__ def test_instanceAcquiresFinalizer_bound_newStyleClass(self): @@ -265,8 +265,8 @@ H.__del__ = types.MethodType(delObject, H.name) H = None runGCIfJython() - assert("H finalized (DummyClassDelNew)" in finalizeMsgList) - assert("H finalized (acquired by object)" not in finalizeMsgList) + self.assertIn("H finalized (DummyClassDelNew)", finalizeMsgList) + self.assertNotIn("H finalized (acquired by object)", finalizeMsgList) def test_instanceAcquiresFinalizer_bound_newStyleClass2(self): """ @@ -279,16 +279,16 @@ H.__del__() H = None runGCIfJython() - assert("H2 finalized (DummyClassDelNew)" in finalizeMsgList) - assert("H2 finalized (acquired by object)" in finalizeMsgList) + self.assertIn("H2 finalized (DummyClassDelNew)", finalizeMsgList) + self.assertIn("H2 finalized (acquired by object)", finalizeMsgList) def test_objectResurrection_oldStyleClass(self): ResurrectableDummyClass.__del__ = delI I = ResurrectableDummyClass("I") I = None runGCIfJython() - assert("I finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_I) == "I") + self.assertIn("I finalized (ResurrectableDummyClass)", finalizeMsgList) + self.assertEqual(str(resurrectedObject_I), "I") def test_objectDoubleResurrection_oldStyleClass(self): #okay to fail in Jython without the manual ensureFinalizer calls @@ -297,12 +297,12 @@ J = None runGCIfJython() - assert("J finalized (ResurrectableDummyClass)" in finalizeMsgList) + self.assertIn("J finalized (ResurrectableDummyClass)", finalizeMsgList) global resurrectedObject_J - assert(str(resurrectedObject_J) == "J") + self.assertEqual(str(resurrectedObject_J), "J") J = resurrectedObject_J resurrectedObject_J = None - assert(resurrectedObject_J is None) + self.assertIsNone(resurrectedObject_J) try: #For Jython one can restore the finalizer manually. #This is offered as an easy fix if the CPython behavior @@ -313,7 +313,7 @@ J = None runGCIfJython() - assert(str(resurrectedObject_J) == "J") + self.assertEqual(str(resurrectedObject_J), "J") resurrectedObject_J.doResurrection = False try: #again... @@ -323,7 +323,7 @@ resurrectedObject_J = None runGCIfJython() - assert(resurrectedObject_J is None) + self.assertIsNone(resurrectedObject_J) def test_objectDoubleResurrectionAndFinalize_oldStyleClass(self): @@ -333,14 +333,14 @@ K = None runGCIfJython() - assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) + self.assertIn("K finalized (ResurrectableDummyClass)", finalizeMsgList) finalizeMsgList.remove("K finalized (ResurrectableDummyClass)") - assert("K finalized (ResurrectableDummyClass)" not in finalizeMsgList) + self.assertNotIn("K finalized (ResurrectableDummyClass)", finalizeMsgList) global resurrectedObject_K - assert(str(resurrectedObject_K) == "K") + self.assertEqual(str(resurrectedObject_K), "K") K = resurrectedObject_K resurrectedObject_K = None - assert(resurrectedObject_K is None) + self.assertIsNone(resurrectedObject_K) try: K.__ensure_finalizer__() except: @@ -348,16 +348,16 @@ K = None runGCIfJython() - assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_K) == "K") + self.assertIn("K finalized (ResurrectableDummyClass)", finalizeMsgList) + self.assertEqual(str(resurrectedObject_K), "K") def test_objectResurrection_newStyleClass(self): ResurrectableDummyClassNew.__del__ = delL L = ResurrectableDummyClassNew("L") L = None runGCIfJython() - assert("L finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_L) == "L") + self.assertIn("L finalized (ResurrectableDummyClass)", finalizeMsgList) + self.assertEqual(str(resurrectedObject_L), "L") def test_objectDoubleResurrection_newStyleClass(self): #okay to fail in Jython without the manual ensureFinalizer calls @@ -366,12 +366,12 @@ M = None runGCIfJython() - assert("M finalized (ResurrectableDummyClass)" in finalizeMsgList) + self.assertIn("M finalized (ResurrectableDummyClass)", finalizeMsgList) global resurrectedObject_M - assert(str(resurrectedObject_M) == "M") + self.assertEqual(str(resurrectedObject_M), "M") M = resurrectedObject_M resurrectedObject_M = None - assert(resurrectedObject_M is None) + self.assertIsNone(resurrectedObject_M, None) try: M.__ensure_finalizer__() except: @@ -379,7 +379,7 @@ M = None runGCIfJython() - assert(str(resurrectedObject_M) == "M") + self.assertEqual(str(resurrectedObject_M), "M") def test_objectDoubleResurrectionAndFinalize_newStyleClass(self): #okay to fail in Jython without the manual ensureFinalizer calls @@ -388,14 +388,14 @@ N = None runGCIfJython() - assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) + self.assertIn("N finalized (ResurrectableDummyClass)", finalizeMsgList) finalizeMsgList.remove("N finalized (ResurrectableDummyClass)") - assert("N finalized (ResurrectableDummyClass)" not in finalizeMsgList) + self.assertNotIn("N finalized (ResurrectableDummyClass)", finalizeMsgList) global resurrectedObject_N - assert(str(resurrectedObject_N) == "N") + self.assertEqual(str(resurrectedObject_N), "N") N = resurrectedObject_N resurrectedObject_N = None - assert(resurrectedObject_N is None) + self.assertIsNone(resurrectedObject_N) try: N.__ensure_finalizer__() except: @@ -403,15 +403,15 @@ N = None runGCIfJython() - assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_N) == "N") + self.assertIn("N finalized (ResurrectableDummyClass)", finalizeMsgList) + self.assertEqual(str(resurrectedObject_N), "N") def test_file_overwrite_del(self): O = DummyFileClassNew("O") O = None runGCIfJython() - assert("O finalized (DummyFileClassNew)" in finalizeMsgList) + self.assertIn("O finalized (DummyFileClassNew)", finalizeMsgList) if __name__ == '__main__': unittest.main() -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Thu Sep 4 06:35:49 2014 From: jython-checkins at python.org (jim.baker) Date: Thu, 4 Sep 2014 06:35:49 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython_=28merge_default_-=3E_default?= =?utf-8?q?=29=3A_Updated_merge_of_newstyle_finalization_support?= Message-ID: <3hpTjK4S7wz7Lkx@mail.python.org> http://hg.python.org/jython/rev/6953968b2638 changeset: 7367:6953968b2638 parent: 7363:61081b8859c1 parent: 7366:b3e0d7ee59fc user: Jim Baker date: Wed Sep 03 22:02:03 2014 -0600 summary: Updated merge of newstyle finalization support files: Lib/test/test_finalizers.py | 76 +++++----- src/org/python/antlr/ast/AssertDerived.java | 2 +- src/org/python/antlr/ast/AssignDerived.java | 2 +- src/org/python/antlr/ast/AttributeDerived.java | 2 +- src/org/python/antlr/ast/AugAssignDerived.java | 2 +- src/org/python/antlr/ast/BinOpDerived.java | 2 +- src/org/python/antlr/ast/BoolOpDerived.java | 2 +- src/org/python/antlr/ast/BreakDerived.java | 2 +- src/org/python/antlr/ast/CallDerived.java | 2 +- src/org/python/antlr/ast/ClassDefDerived.java | 2 +- src/org/python/antlr/ast/CompareDerived.java | 2 +- src/org/python/antlr/ast/ContinueDerived.java | 2 +- src/org/python/antlr/ast/DeleteDerived.java | 2 +- src/org/python/antlr/ast/DictDerived.java | 2 +- src/org/python/antlr/ast/EllipsisDerived.java | 2 +- src/org/python/antlr/ast/ExceptHandlerDerived.java | 2 +- src/org/python/antlr/ast/ExecDerived.java | 2 +- src/org/python/antlr/ast/ExprDerived.java | 2 +- src/org/python/antlr/ast/ExpressionDerived.java | 2 +- src/org/python/antlr/ast/ExtSliceDerived.java | 2 +- src/org/python/antlr/ast/ForDerived.java | 2 +- src/org/python/antlr/ast/FunctionDefDerived.java | 2 +- src/org/python/antlr/ast/GeneratorExpDerived.java | 2 +- src/org/python/antlr/ast/GlobalDerived.java | 2 +- src/org/python/antlr/ast/IfDerived.java | 2 +- src/org/python/antlr/ast/IfExpDerived.java | 2 +- src/org/python/antlr/ast/ImportDerived.java | 2 +- src/org/python/antlr/ast/ImportFromDerived.java | 2 +- src/org/python/antlr/ast/IndexDerived.java | 2 +- src/org/python/antlr/ast/InteractiveDerived.java | 2 +- src/org/python/antlr/ast/LambdaDerived.java | 2 +- src/org/python/antlr/ast/ListCompDerived.java | 2 +- src/org/python/antlr/ast/ListDerived.java | 2 +- src/org/python/antlr/ast/ModuleDerived.java | 2 +- src/org/python/antlr/ast/NameDerived.java | 2 +- src/org/python/antlr/ast/NumDerived.java | 2 +- src/org/python/antlr/ast/PassDerived.java | 2 +- src/org/python/antlr/ast/PrintDerived.java | 2 +- src/org/python/antlr/ast/RaiseDerived.java | 2 +- src/org/python/antlr/ast/ReprDerived.java | 2 +- src/org/python/antlr/ast/ReturnDerived.java | 2 +- src/org/python/antlr/ast/SliceDerived.java | 2 +- src/org/python/antlr/ast/StrDerived.java | 2 +- src/org/python/antlr/ast/SubscriptDerived.java | 2 +- src/org/python/antlr/ast/SuiteDerived.java | 2 +- src/org/python/antlr/ast/TryExceptDerived.java | 2 +- src/org/python/antlr/ast/TryFinallyDerived.java | 2 +- src/org/python/antlr/ast/TupleDerived.java | 2 +- src/org/python/antlr/ast/UnaryOpDerived.java | 2 +- src/org/python/antlr/ast/WhileDerived.java | 2 +- src/org/python/antlr/ast/WithDerived.java | 2 +- src/org/python/antlr/ast/YieldDerived.java | 2 +- src/org/python/antlr/ast/aliasDerived.java | 2 +- src/org/python/antlr/ast/argumentsDerived.java | 2 +- src/org/python/antlr/ast/comprehensionDerived.java | 2 +- src/org/python/antlr/ast/keywordDerived.java | 2 +- src/org/python/antlr/op/AddDerived.java | 2 +- src/org/python/antlr/op/AndDerived.java | 2 +- src/org/python/antlr/op/AugLoadDerived.java | 2 +- src/org/python/antlr/op/AugStoreDerived.java | 2 +- src/org/python/antlr/op/BitAndDerived.java | 2 +- src/org/python/antlr/op/BitOrDerived.java | 2 +- src/org/python/antlr/op/BitXorDerived.java | 2 +- src/org/python/antlr/op/DelDerived.java | 2 +- src/org/python/antlr/op/DivDerived.java | 2 +- src/org/python/antlr/op/EqDerived.java | 2 +- src/org/python/antlr/op/FloorDivDerived.java | 2 +- src/org/python/antlr/op/GtDerived.java | 2 +- src/org/python/antlr/op/GtEDerived.java | 2 +- src/org/python/antlr/op/InDerived.java | 2 +- src/org/python/antlr/op/InvertDerived.java | 2 +- src/org/python/antlr/op/IsDerived.java | 2 +- src/org/python/antlr/op/IsNotDerived.java | 2 +- src/org/python/antlr/op/LShiftDerived.java | 2 +- src/org/python/antlr/op/LoadDerived.java | 2 +- src/org/python/antlr/op/LtDerived.java | 2 +- src/org/python/antlr/op/LtEDerived.java | 2 +- src/org/python/antlr/op/ModDerived.java | 2 +- src/org/python/antlr/op/MultDerived.java | 2 +- src/org/python/antlr/op/NotDerived.java | 2 +- src/org/python/antlr/op/NotEqDerived.java | 2 +- src/org/python/antlr/op/NotInDerived.java | 2 +- src/org/python/antlr/op/OrDerived.java | 2 +- src/org/python/antlr/op/ParamDerived.java | 2 +- src/org/python/antlr/op/PowDerived.java | 2 +- src/org/python/antlr/op/RShiftDerived.java | 2 +- src/org/python/antlr/op/StoreDerived.java | 2 +- src/org/python/antlr/op/SubDerived.java | 2 +- src/org/python/antlr/op/UAddDerived.java | 2 +- src/org/python/antlr/op/USubDerived.java | 2 +- src/org/python/core/ClasspathPyImporterDerived.java | 2 +- src/org/python/core/PyArrayDerived.java | 2 +- src/org/python/core/PyBaseExceptionDerived.java | 2 +- src/org/python/core/PyByteArrayDerived.java | 2 +- src/org/python/core/PyClassMethodDerived.java | 2 +- src/org/python/core/PyComplexDerived.java | 2 +- src/org/python/core/PyDictionaryDerived.java | 2 +- src/org/python/core/PyEnumerateDerived.java | 2 +- src/org/python/core/PyFileDerived.java | 2 +- src/org/python/core/PyFloatDerived.java | 2 +- src/org/python/core/PyFrozenSetDerived.java | 2 +- src/org/python/core/PyInstance.java | 5 +- src/org/python/core/PyIntegerDerived.java | 2 +- src/org/python/core/PyListDerived.java | 2 +- src/org/python/core/PyLongDerived.java | 2 +- src/org/python/core/PyModuleDerived.java | 2 +- src/org/python/core/PyObjectDerived.java | 2 +- src/org/python/core/PyPropertyDerived.java | 2 +- src/org/python/core/PySetDerived.java | 2 +- src/org/python/core/PyStringDerived.java | 2 +- src/org/python/core/PySuperDerived.java | 2 +- src/org/python/core/PyTupleDerived.java | 2 +- src/org/python/core/PyTypeDerived.java | 2 +- src/org/python/core/PyUnicodeDerived.java | 2 +- src/org/python/core/finalization/FinalizablePyObject.java | 21 ++- src/org/python/core/finalization/FinalizeTrigger.java | 5 +- src/org/python/core/finalization/FinalizeTriggerFactory.java | 7 +- src/org/python/modules/PyStructDerived.java | 2 +- src/org/python/modules/_collections/PyDefaultDictDerived.java | 2 +- src/org/python/modules/_collections/PyDequeDerived.java | 2 +- src/org/python/modules/_csv/PyDialectDerived.java | 2 +- src/org/python/modules/_functools/PyPartialDerived.java | 2 +- src/org/python/modules/_io/PyFileIODerived.java | 2 +- src/org/python/modules/_io/PyIOBaseDerived.java | 2 +- src/org/python/modules/_io/PyRawIOBaseDerived.java | 2 +- src/org/python/modules/_weakref/ReferenceTypeDerived.java | 2 +- src/org/python/modules/bz2/PyBZ2CompressorDerived.java | 2 +- src/org/python/modules/bz2/PyBZ2DecompressorDerived.java | 2 +- src/org/python/modules/bz2/PyBZ2FileDerived.java | 2 +- src/org/python/modules/itertools/PyTeeIteratorDerived.java | 2 +- src/org/python/modules/itertools/chainDerived.java | 2 +- src/org/python/modules/itertools/combinationsDerived.java | 2 +- src/org/python/modules/itertools/combinationsWithReplacementDerived.java | 2 +- src/org/python/modules/itertools/compressDerived.java | 2 +- src/org/python/modules/itertools/countDerived.java | 2 +- src/org/python/modules/itertools/cycleDerived.java | 2 +- src/org/python/modules/itertools/dropwhileDerived.java | 2 +- src/org/python/modules/itertools/groupbyDerived.java | 2 +- src/org/python/modules/itertools/ifilterDerived.java | 2 +- src/org/python/modules/itertools/ifilterfalseDerived.java | 2 +- src/org/python/modules/itertools/isliceDerived.java | 2 +- src/org/python/modules/itertools/izipDerived.java | 2 +- src/org/python/modules/itertools/izipLongestDerived.java | 2 +- src/org/python/modules/itertools/permutationsDerived.java | 2 +- src/org/python/modules/itertools/productDerived.java | 2 +- src/org/python/modules/itertools/repeatDerived.java | 2 +- src/org/python/modules/itertools/starmapDerived.java | 2 +- src/org/python/modules/itertools/takewhileDerived.java | 2 +- src/org/python/modules/random/PyRandomDerived.java | 2 +- src/org/python/modules/thread/PyLocalDerived.java | 2 +- src/org/python/modules/zipimport/zipimporterDerived.java | 2 +- src/templates/gderived-defs | 12 +- 152 files changed, 221 insertions(+), 197 deletions(-) diff --git a/Lib/test/test_finalizers.py b/Lib/test/test_finalizers.py --- a/Lib/test/test_finalizers.py +++ b/Lib/test/test_finalizers.py @@ -198,14 +198,14 @@ A = DummyClassDel("A") A = None runGCIfJython() - assert("A finalized (DummyClassDel)" in finalizeMsgList) + self.assertIn("A finalized (DummyClassDel)", finalizeMsgList) def test_classAcquiresFinalizer_beforeInstanciation_oldStyleClass(self): DummyClass.__del__ = delClass B = DummyClass("B") B = None runGCIfJython() - assert("B finalized (acquired by class)" in finalizeMsgList) + self.assertIn("B finalized (acquired by class)", finalizeMsgList) del DummyClass.__del__ def test_classAcquiresFinalizer_afterInstanciation_oldStyleClass(self): @@ -218,7 +218,7 @@ pass C = None runGCIfJython() - assert("C finalized (acquired by class)" in finalizeMsgList) + self.assertIn("C finalized (acquired by class)", finalizeMsgList) del DummyClass.__del__ def test_instanceAcquiresFinalizer_bound_oldStyleClass(self): @@ -227,21 +227,21 @@ D.__del__ = dl D = None runGCIfJython() - assert("D finalized (DummyClassDel)" not in finalizeMsgList) - assert("D finalized (acquired by object)" in finalizeMsgList) + self.assertNotIn("D finalized (DummyClassDel)", finalizeMsgList) + self.assertIn("D finalized (acquired by object)", finalizeMsgList) def test_finalizer_builtin_newStyleClass(self): E = DummyClassDelNew("E") E = None runGCIfJython() - assert("E finalized (DummyClassDelNew)" in finalizeMsgList) + self.assertIn("E finalized (DummyClassDelNew)", finalizeMsgList) def test_classAcquiresFinalizer_beforeInstanciation_newStyleClass(self): DummyClassNew.__del__ = delClass F = DummyClassNew("F") F = None runGCIfJython() - assert("F finalized (acquired by class)" in finalizeMsgList) + self.assertIn("F finalized (acquired by class)", finalizeMsgList) del DummyClassNew.__del__ def test_classAcquiresFinalizer_afterInstanciation_newStyleClass(self): @@ -254,7 +254,7 @@ pass G = None runGCIfJython() - assert("G finalized (acquired by class)" in finalizeMsgList) + self.assertIn("G finalized (acquired by class)", finalizeMsgList) del DummyClassNew.__del__ def test_instanceAcquiresFinalizer_bound_newStyleClass(self): @@ -265,8 +265,8 @@ H.__del__ = types.MethodType(delObject, H.name) H = None runGCIfJython() - assert("H finalized (DummyClassDelNew)" in finalizeMsgList) - assert("H finalized (acquired by object)" not in finalizeMsgList) + self.assertIn("H finalized (DummyClassDelNew)", finalizeMsgList) + self.assertNotIn("H finalized (acquired by object)", finalizeMsgList) def test_instanceAcquiresFinalizer_bound_newStyleClass2(self): """ @@ -279,16 +279,16 @@ H.__del__() H = None runGCIfJython() - assert("H2 finalized (DummyClassDelNew)" in finalizeMsgList) - assert("H2 finalized (acquired by object)" in finalizeMsgList) + self.assertIn("H2 finalized (DummyClassDelNew)", finalizeMsgList) + self.assertIn("H2 finalized (acquired by object)", finalizeMsgList) def test_objectResurrection_oldStyleClass(self): ResurrectableDummyClass.__del__ = delI I = ResurrectableDummyClass("I") I = None runGCIfJython() - assert("I finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_I) == "I") + self.assertIn("I finalized (ResurrectableDummyClass)", finalizeMsgList) + self.assertEqual(str(resurrectedObject_I), "I") def test_objectDoubleResurrection_oldStyleClass(self): #okay to fail in Jython without the manual ensureFinalizer calls @@ -297,12 +297,12 @@ J = None runGCIfJython() - assert("J finalized (ResurrectableDummyClass)" in finalizeMsgList) + self.assertIn("J finalized (ResurrectableDummyClass)", finalizeMsgList) global resurrectedObject_J - assert(str(resurrectedObject_J) == "J") + self.assertEqual(str(resurrectedObject_J), "J") J = resurrectedObject_J resurrectedObject_J = None - assert(resurrectedObject_J is None) + self.assertIsNone(resurrectedObject_J) try: #For Jython one can restore the finalizer manually. #This is offered as an easy fix if the CPython behavior @@ -313,7 +313,7 @@ J = None runGCIfJython() - assert(str(resurrectedObject_J) == "J") + self.assertEqual(str(resurrectedObject_J), "J") resurrectedObject_J.doResurrection = False try: #again... @@ -323,7 +323,7 @@ resurrectedObject_J = None runGCIfJython() - assert(resurrectedObject_J is None) + self.assertIsNone(resurrectedObject_J) def test_objectDoubleResurrectionAndFinalize_oldStyleClass(self): @@ -333,14 +333,14 @@ K = None runGCIfJython() - assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) + self.assertIn("K finalized (ResurrectableDummyClass)", finalizeMsgList) finalizeMsgList.remove("K finalized (ResurrectableDummyClass)") - assert("K finalized (ResurrectableDummyClass)" not in finalizeMsgList) + self.assertNotIn("K finalized (ResurrectableDummyClass)", finalizeMsgList) global resurrectedObject_K - assert(str(resurrectedObject_K) == "K") + self.assertEqual(str(resurrectedObject_K), "K") K = resurrectedObject_K resurrectedObject_K = None - assert(resurrectedObject_K is None) + self.assertIsNone(resurrectedObject_K) try: K.__ensure_finalizer__() except: @@ -348,16 +348,16 @@ K = None runGCIfJython() - assert("K finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_K) == "K") + self.assertIn("K finalized (ResurrectableDummyClass)", finalizeMsgList) + self.assertEqual(str(resurrectedObject_K), "K") def test_objectResurrection_newStyleClass(self): ResurrectableDummyClassNew.__del__ = delL L = ResurrectableDummyClassNew("L") L = None runGCIfJython() - assert("L finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_L) == "L") + self.assertIn("L finalized (ResurrectableDummyClass)", finalizeMsgList) + self.assertEqual(str(resurrectedObject_L), "L") def test_objectDoubleResurrection_newStyleClass(self): #okay to fail in Jython without the manual ensureFinalizer calls @@ -366,12 +366,12 @@ M = None runGCIfJython() - assert("M finalized (ResurrectableDummyClass)" in finalizeMsgList) + self.assertIn("M finalized (ResurrectableDummyClass)", finalizeMsgList) global resurrectedObject_M - assert(str(resurrectedObject_M) == "M") + self.assertEqual(str(resurrectedObject_M), "M") M = resurrectedObject_M resurrectedObject_M = None - assert(resurrectedObject_M is None) + self.assertIsNone(resurrectedObject_M, None) try: M.__ensure_finalizer__() except: @@ -379,7 +379,7 @@ M = None runGCIfJython() - assert(str(resurrectedObject_M) == "M") + self.assertEqual(str(resurrectedObject_M), "M") def test_objectDoubleResurrectionAndFinalize_newStyleClass(self): #okay to fail in Jython without the manual ensureFinalizer calls @@ -388,14 +388,14 @@ N = None runGCIfJython() - assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) + self.assertIn("N finalized (ResurrectableDummyClass)", finalizeMsgList) finalizeMsgList.remove("N finalized (ResurrectableDummyClass)") - assert("N finalized (ResurrectableDummyClass)" not in finalizeMsgList) + self.assertNotIn("N finalized (ResurrectableDummyClass)", finalizeMsgList) global resurrectedObject_N - assert(str(resurrectedObject_N) == "N") + self.assertEqual(str(resurrectedObject_N), "N") N = resurrectedObject_N resurrectedObject_N = None - assert(resurrectedObject_N is None) + self.assertIsNone(resurrectedObject_N) try: N.__ensure_finalizer__() except: @@ -403,15 +403,15 @@ N = None runGCIfJython() - assert("N finalized (ResurrectableDummyClass)" in finalizeMsgList) - assert(str(resurrectedObject_N) == "N") + self.assertIn("N finalized (ResurrectableDummyClass)", finalizeMsgList) + self.assertEqual(str(resurrectedObject_N), "N") def test_file_overwrite_del(self): O = DummyFileClassNew("O") O = None runGCIfJython() - assert("O finalized (DummyFileClassNew)" in finalizeMsgList) + self.assertIn("O finalized (DummyFileClassNew)", finalizeMsgList) if __name__ == '__main__': unittest.main() diff --git a/src/org/python/antlr/ast/AssertDerived.java b/src/org/python/antlr/ast/AssertDerived.java --- a/src/org/python/antlr/ast/AssertDerived.java +++ b/src/org/python/antlr/ast/AssertDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/AssignDerived.java b/src/org/python/antlr/ast/AssignDerived.java --- a/src/org/python/antlr/ast/AssignDerived.java +++ b/src/org/python/antlr/ast/AssignDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/AttributeDerived.java b/src/org/python/antlr/ast/AttributeDerived.java --- a/src/org/python/antlr/ast/AttributeDerived.java +++ b/src/org/python/antlr/ast/AttributeDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/AugAssignDerived.java b/src/org/python/antlr/ast/AugAssignDerived.java --- a/src/org/python/antlr/ast/AugAssignDerived.java +++ b/src/org/python/antlr/ast/AugAssignDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/BinOpDerived.java b/src/org/python/antlr/ast/BinOpDerived.java --- a/src/org/python/antlr/ast/BinOpDerived.java +++ b/src/org/python/antlr/ast/BinOpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/BoolOpDerived.java b/src/org/python/antlr/ast/BoolOpDerived.java --- a/src/org/python/antlr/ast/BoolOpDerived.java +++ b/src/org/python/antlr/ast/BoolOpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/BreakDerived.java b/src/org/python/antlr/ast/BreakDerived.java --- a/src/org/python/antlr/ast/BreakDerived.java +++ b/src/org/python/antlr/ast/BreakDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/CallDerived.java b/src/org/python/antlr/ast/CallDerived.java --- a/src/org/python/antlr/ast/CallDerived.java +++ b/src/org/python/antlr/ast/CallDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ClassDefDerived.java b/src/org/python/antlr/ast/ClassDefDerived.java --- a/src/org/python/antlr/ast/ClassDefDerived.java +++ b/src/org/python/antlr/ast/ClassDefDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/CompareDerived.java b/src/org/python/antlr/ast/CompareDerived.java --- a/src/org/python/antlr/ast/CompareDerived.java +++ b/src/org/python/antlr/ast/CompareDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ContinueDerived.java b/src/org/python/antlr/ast/ContinueDerived.java --- a/src/org/python/antlr/ast/ContinueDerived.java +++ b/src/org/python/antlr/ast/ContinueDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/DeleteDerived.java b/src/org/python/antlr/ast/DeleteDerived.java --- a/src/org/python/antlr/ast/DeleteDerived.java +++ b/src/org/python/antlr/ast/DeleteDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/DictDerived.java b/src/org/python/antlr/ast/DictDerived.java --- a/src/org/python/antlr/ast/DictDerived.java +++ b/src/org/python/antlr/ast/DictDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/EllipsisDerived.java b/src/org/python/antlr/ast/EllipsisDerived.java --- a/src/org/python/antlr/ast/EllipsisDerived.java +++ b/src/org/python/antlr/ast/EllipsisDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExceptHandlerDerived.java b/src/org/python/antlr/ast/ExceptHandlerDerived.java --- a/src/org/python/antlr/ast/ExceptHandlerDerived.java +++ b/src/org/python/antlr/ast/ExceptHandlerDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExecDerived.java b/src/org/python/antlr/ast/ExecDerived.java --- a/src/org/python/antlr/ast/ExecDerived.java +++ b/src/org/python/antlr/ast/ExecDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExprDerived.java b/src/org/python/antlr/ast/ExprDerived.java --- a/src/org/python/antlr/ast/ExprDerived.java +++ b/src/org/python/antlr/ast/ExprDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExpressionDerived.java b/src/org/python/antlr/ast/ExpressionDerived.java --- a/src/org/python/antlr/ast/ExpressionDerived.java +++ b/src/org/python/antlr/ast/ExpressionDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ExtSliceDerived.java b/src/org/python/antlr/ast/ExtSliceDerived.java --- a/src/org/python/antlr/ast/ExtSliceDerived.java +++ b/src/org/python/antlr/ast/ExtSliceDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ForDerived.java b/src/org/python/antlr/ast/ForDerived.java --- a/src/org/python/antlr/ast/ForDerived.java +++ b/src/org/python/antlr/ast/ForDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/FunctionDefDerived.java b/src/org/python/antlr/ast/FunctionDefDerived.java --- a/src/org/python/antlr/ast/FunctionDefDerived.java +++ b/src/org/python/antlr/ast/FunctionDefDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/GeneratorExpDerived.java b/src/org/python/antlr/ast/GeneratorExpDerived.java --- a/src/org/python/antlr/ast/GeneratorExpDerived.java +++ b/src/org/python/antlr/ast/GeneratorExpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/GlobalDerived.java b/src/org/python/antlr/ast/GlobalDerived.java --- a/src/org/python/antlr/ast/GlobalDerived.java +++ b/src/org/python/antlr/ast/GlobalDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/IfDerived.java b/src/org/python/antlr/ast/IfDerived.java --- a/src/org/python/antlr/ast/IfDerived.java +++ b/src/org/python/antlr/ast/IfDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/IfExpDerived.java b/src/org/python/antlr/ast/IfExpDerived.java --- a/src/org/python/antlr/ast/IfExpDerived.java +++ b/src/org/python/antlr/ast/IfExpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ImportDerived.java b/src/org/python/antlr/ast/ImportDerived.java --- a/src/org/python/antlr/ast/ImportDerived.java +++ b/src/org/python/antlr/ast/ImportDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ImportFromDerived.java b/src/org/python/antlr/ast/ImportFromDerived.java --- a/src/org/python/antlr/ast/ImportFromDerived.java +++ b/src/org/python/antlr/ast/ImportFromDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/IndexDerived.java b/src/org/python/antlr/ast/IndexDerived.java --- a/src/org/python/antlr/ast/IndexDerived.java +++ b/src/org/python/antlr/ast/IndexDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/InteractiveDerived.java b/src/org/python/antlr/ast/InteractiveDerived.java --- a/src/org/python/antlr/ast/InteractiveDerived.java +++ b/src/org/python/antlr/ast/InteractiveDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/LambdaDerived.java b/src/org/python/antlr/ast/LambdaDerived.java --- a/src/org/python/antlr/ast/LambdaDerived.java +++ b/src/org/python/antlr/ast/LambdaDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ListCompDerived.java b/src/org/python/antlr/ast/ListCompDerived.java --- a/src/org/python/antlr/ast/ListCompDerived.java +++ b/src/org/python/antlr/ast/ListCompDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ListDerived.java b/src/org/python/antlr/ast/ListDerived.java --- a/src/org/python/antlr/ast/ListDerived.java +++ b/src/org/python/antlr/ast/ListDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ModuleDerived.java b/src/org/python/antlr/ast/ModuleDerived.java --- a/src/org/python/antlr/ast/ModuleDerived.java +++ b/src/org/python/antlr/ast/ModuleDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/NameDerived.java b/src/org/python/antlr/ast/NameDerived.java --- a/src/org/python/antlr/ast/NameDerived.java +++ b/src/org/python/antlr/ast/NameDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/NumDerived.java b/src/org/python/antlr/ast/NumDerived.java --- a/src/org/python/antlr/ast/NumDerived.java +++ b/src/org/python/antlr/ast/NumDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/PassDerived.java b/src/org/python/antlr/ast/PassDerived.java --- a/src/org/python/antlr/ast/PassDerived.java +++ b/src/org/python/antlr/ast/PassDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/PrintDerived.java b/src/org/python/antlr/ast/PrintDerived.java --- a/src/org/python/antlr/ast/PrintDerived.java +++ b/src/org/python/antlr/ast/PrintDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/RaiseDerived.java b/src/org/python/antlr/ast/RaiseDerived.java --- a/src/org/python/antlr/ast/RaiseDerived.java +++ b/src/org/python/antlr/ast/RaiseDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ReprDerived.java b/src/org/python/antlr/ast/ReprDerived.java --- a/src/org/python/antlr/ast/ReprDerived.java +++ b/src/org/python/antlr/ast/ReprDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/ReturnDerived.java b/src/org/python/antlr/ast/ReturnDerived.java --- a/src/org/python/antlr/ast/ReturnDerived.java +++ b/src/org/python/antlr/ast/ReturnDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/SliceDerived.java b/src/org/python/antlr/ast/SliceDerived.java --- a/src/org/python/antlr/ast/SliceDerived.java +++ b/src/org/python/antlr/ast/SliceDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/StrDerived.java b/src/org/python/antlr/ast/StrDerived.java --- a/src/org/python/antlr/ast/StrDerived.java +++ b/src/org/python/antlr/ast/StrDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/SubscriptDerived.java b/src/org/python/antlr/ast/SubscriptDerived.java --- a/src/org/python/antlr/ast/SubscriptDerived.java +++ b/src/org/python/antlr/ast/SubscriptDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/SuiteDerived.java b/src/org/python/antlr/ast/SuiteDerived.java --- a/src/org/python/antlr/ast/SuiteDerived.java +++ b/src/org/python/antlr/ast/SuiteDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/TryExceptDerived.java b/src/org/python/antlr/ast/TryExceptDerived.java --- a/src/org/python/antlr/ast/TryExceptDerived.java +++ b/src/org/python/antlr/ast/TryExceptDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/TryFinallyDerived.java b/src/org/python/antlr/ast/TryFinallyDerived.java --- a/src/org/python/antlr/ast/TryFinallyDerived.java +++ b/src/org/python/antlr/ast/TryFinallyDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/TupleDerived.java b/src/org/python/antlr/ast/TupleDerived.java --- a/src/org/python/antlr/ast/TupleDerived.java +++ b/src/org/python/antlr/ast/TupleDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/UnaryOpDerived.java b/src/org/python/antlr/ast/UnaryOpDerived.java --- a/src/org/python/antlr/ast/UnaryOpDerived.java +++ b/src/org/python/antlr/ast/UnaryOpDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/WhileDerived.java b/src/org/python/antlr/ast/WhileDerived.java --- a/src/org/python/antlr/ast/WhileDerived.java +++ b/src/org/python/antlr/ast/WhileDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/WithDerived.java b/src/org/python/antlr/ast/WithDerived.java --- a/src/org/python/antlr/ast/WithDerived.java +++ b/src/org/python/antlr/ast/WithDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/YieldDerived.java b/src/org/python/antlr/ast/YieldDerived.java --- a/src/org/python/antlr/ast/YieldDerived.java +++ b/src/org/python/antlr/ast/YieldDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/aliasDerived.java b/src/org/python/antlr/ast/aliasDerived.java --- a/src/org/python/antlr/ast/aliasDerived.java +++ b/src/org/python/antlr/ast/aliasDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/argumentsDerived.java b/src/org/python/antlr/ast/argumentsDerived.java --- a/src/org/python/antlr/ast/argumentsDerived.java +++ b/src/org/python/antlr/ast/argumentsDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/comprehensionDerived.java b/src/org/python/antlr/ast/comprehensionDerived.java --- a/src/org/python/antlr/ast/comprehensionDerived.java +++ b/src/org/python/antlr/ast/comprehensionDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/ast/keywordDerived.java b/src/org/python/antlr/ast/keywordDerived.java --- a/src/org/python/antlr/ast/keywordDerived.java +++ b/src/org/python/antlr/ast/keywordDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/AddDerived.java b/src/org/python/antlr/op/AddDerived.java --- a/src/org/python/antlr/op/AddDerived.java +++ b/src/org/python/antlr/op/AddDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/AndDerived.java b/src/org/python/antlr/op/AndDerived.java --- a/src/org/python/antlr/op/AndDerived.java +++ b/src/org/python/antlr/op/AndDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/AugLoadDerived.java b/src/org/python/antlr/op/AugLoadDerived.java --- a/src/org/python/antlr/op/AugLoadDerived.java +++ b/src/org/python/antlr/op/AugLoadDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/AugStoreDerived.java b/src/org/python/antlr/op/AugStoreDerived.java --- a/src/org/python/antlr/op/AugStoreDerived.java +++ b/src/org/python/antlr/op/AugStoreDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/BitAndDerived.java b/src/org/python/antlr/op/BitAndDerived.java --- a/src/org/python/antlr/op/BitAndDerived.java +++ b/src/org/python/antlr/op/BitAndDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/BitOrDerived.java b/src/org/python/antlr/op/BitOrDerived.java --- a/src/org/python/antlr/op/BitOrDerived.java +++ b/src/org/python/antlr/op/BitOrDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/BitXorDerived.java b/src/org/python/antlr/op/BitXorDerived.java --- a/src/org/python/antlr/op/BitXorDerived.java +++ b/src/org/python/antlr/op/BitXorDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/DelDerived.java b/src/org/python/antlr/op/DelDerived.java --- a/src/org/python/antlr/op/DelDerived.java +++ b/src/org/python/antlr/op/DelDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/DivDerived.java b/src/org/python/antlr/op/DivDerived.java --- a/src/org/python/antlr/op/DivDerived.java +++ b/src/org/python/antlr/op/DivDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/EqDerived.java b/src/org/python/antlr/op/EqDerived.java --- a/src/org/python/antlr/op/EqDerived.java +++ b/src/org/python/antlr/op/EqDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/FloorDivDerived.java b/src/org/python/antlr/op/FloorDivDerived.java --- a/src/org/python/antlr/op/FloorDivDerived.java +++ b/src/org/python/antlr/op/FloorDivDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/GtDerived.java b/src/org/python/antlr/op/GtDerived.java --- a/src/org/python/antlr/op/GtDerived.java +++ b/src/org/python/antlr/op/GtDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/GtEDerived.java b/src/org/python/antlr/op/GtEDerived.java --- a/src/org/python/antlr/op/GtEDerived.java +++ b/src/org/python/antlr/op/GtEDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/InDerived.java b/src/org/python/antlr/op/InDerived.java --- a/src/org/python/antlr/op/InDerived.java +++ b/src/org/python/antlr/op/InDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/InvertDerived.java b/src/org/python/antlr/op/InvertDerived.java --- a/src/org/python/antlr/op/InvertDerived.java +++ b/src/org/python/antlr/op/InvertDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/IsDerived.java b/src/org/python/antlr/op/IsDerived.java --- a/src/org/python/antlr/op/IsDerived.java +++ b/src/org/python/antlr/op/IsDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/IsNotDerived.java b/src/org/python/antlr/op/IsNotDerived.java --- a/src/org/python/antlr/op/IsNotDerived.java +++ b/src/org/python/antlr/op/IsNotDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/LShiftDerived.java b/src/org/python/antlr/op/LShiftDerived.java --- a/src/org/python/antlr/op/LShiftDerived.java +++ b/src/org/python/antlr/op/LShiftDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/LoadDerived.java b/src/org/python/antlr/op/LoadDerived.java --- a/src/org/python/antlr/op/LoadDerived.java +++ b/src/org/python/antlr/op/LoadDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/LtDerived.java b/src/org/python/antlr/op/LtDerived.java --- a/src/org/python/antlr/op/LtDerived.java +++ b/src/org/python/antlr/op/LtDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/LtEDerived.java b/src/org/python/antlr/op/LtEDerived.java --- a/src/org/python/antlr/op/LtEDerived.java +++ b/src/org/python/antlr/op/LtEDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/ModDerived.java b/src/org/python/antlr/op/ModDerived.java --- a/src/org/python/antlr/op/ModDerived.java +++ b/src/org/python/antlr/op/ModDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/MultDerived.java b/src/org/python/antlr/op/MultDerived.java --- a/src/org/python/antlr/op/MultDerived.java +++ b/src/org/python/antlr/op/MultDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/NotDerived.java b/src/org/python/antlr/op/NotDerived.java --- a/src/org/python/antlr/op/NotDerived.java +++ b/src/org/python/antlr/op/NotDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/NotEqDerived.java b/src/org/python/antlr/op/NotEqDerived.java --- a/src/org/python/antlr/op/NotEqDerived.java +++ b/src/org/python/antlr/op/NotEqDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/NotInDerived.java b/src/org/python/antlr/op/NotInDerived.java --- a/src/org/python/antlr/op/NotInDerived.java +++ b/src/org/python/antlr/op/NotInDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/OrDerived.java b/src/org/python/antlr/op/OrDerived.java --- a/src/org/python/antlr/op/OrDerived.java +++ b/src/org/python/antlr/op/OrDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/ParamDerived.java b/src/org/python/antlr/op/ParamDerived.java --- a/src/org/python/antlr/op/ParamDerived.java +++ b/src/org/python/antlr/op/ParamDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/PowDerived.java b/src/org/python/antlr/op/PowDerived.java --- a/src/org/python/antlr/op/PowDerived.java +++ b/src/org/python/antlr/op/PowDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/RShiftDerived.java b/src/org/python/antlr/op/RShiftDerived.java --- a/src/org/python/antlr/op/RShiftDerived.java +++ b/src/org/python/antlr/op/RShiftDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/StoreDerived.java b/src/org/python/antlr/op/StoreDerived.java --- a/src/org/python/antlr/op/StoreDerived.java +++ b/src/org/python/antlr/op/StoreDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/SubDerived.java b/src/org/python/antlr/op/SubDerived.java --- a/src/org/python/antlr/op/SubDerived.java +++ b/src/org/python/antlr/op/SubDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/UAddDerived.java b/src/org/python/antlr/op/UAddDerived.java --- a/src/org/python/antlr/op/UAddDerived.java +++ b/src/org/python/antlr/op/UAddDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/antlr/op/USubDerived.java b/src/org/python/antlr/op/USubDerived.java --- a/src/org/python/antlr/op/USubDerived.java +++ b/src/org/python/antlr/op/USubDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/ClasspathPyImporterDerived.java b/src/org/python/core/ClasspathPyImporterDerived.java --- a/src/org/python/core/ClasspathPyImporterDerived.java +++ b/src/org/python/core/ClasspathPyImporterDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public ClasspathPyImporterDerived(PyType subtype) { diff --git a/src/org/python/core/PyArrayDerived.java b/src/org/python/core/PyArrayDerived.java --- a/src/org/python/core/PyArrayDerived.java +++ b/src/org/python/core/PyArrayDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyBaseExceptionDerived.java b/src/org/python/core/PyBaseExceptionDerived.java --- a/src/org/python/core/PyBaseExceptionDerived.java +++ b/src/org/python/core/PyBaseExceptionDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyBaseExceptionDerived(PyType subtype) { diff --git a/src/org/python/core/PyByteArrayDerived.java b/src/org/python/core/PyByteArrayDerived.java --- a/src/org/python/core/PyByteArrayDerived.java +++ b/src/org/python/core/PyByteArrayDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyClassMethodDerived.java b/src/org/python/core/PyClassMethodDerived.java --- a/src/org/python/core/PyClassMethodDerived.java +++ b/src/org/python/core/PyClassMethodDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyComplexDerived.java b/src/org/python/core/PyComplexDerived.java --- a/src/org/python/core/PyComplexDerived.java +++ b/src/org/python/core/PyComplexDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyDictionaryDerived.java b/src/org/python/core/PyDictionaryDerived.java --- a/src/org/python/core/PyDictionaryDerived.java +++ b/src/org/python/core/PyDictionaryDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyEnumerateDerived.java b/src/org/python/core/PyEnumerateDerived.java --- a/src/org/python/core/PyEnumerateDerived.java +++ b/src/org/python/core/PyEnumerateDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyFileDerived.java b/src/org/python/core/PyFileDerived.java --- a/src/org/python/core/PyFileDerived.java +++ b/src/org/python/core/PyFileDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyFloatDerived.java b/src/org/python/core/PyFloatDerived.java --- a/src/org/python/core/PyFloatDerived.java +++ b/src/org/python/core/PyFloatDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyFrozenSetDerived.java b/src/org/python/core/PyFrozenSetDerived.java --- a/src/org/python/core/PyFrozenSetDerived.java +++ b/src/org/python/core/PyFrozenSetDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyInstance.java b/src/org/python/core/PyInstance.java --- a/src/org/python/core/PyInstance.java +++ b/src/org/python/core/PyInstance.java @@ -154,9 +154,10 @@ } public static void ensureFinalizer(PyObject[] args, String[] kws) { - FinalizeTrigger.ensureFinalizer((PyInstance) args[0]); + ((PyInstance) args[0]).finalizeTrigger = FinalizeTrigger.makeTrigger( + (PyInstance) args[0]); } - + private static JavaFunc makeFunction__ensure_finalizer__() { try { return new JavaFunc( diff --git a/src/org/python/core/PyIntegerDerived.java b/src/org/python/core/PyIntegerDerived.java --- a/src/org/python/core/PyIntegerDerived.java +++ b/src/org/python/core/PyIntegerDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyListDerived.java b/src/org/python/core/PyListDerived.java --- a/src/org/python/core/PyListDerived.java +++ b/src/org/python/core/PyListDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyLongDerived.java b/src/org/python/core/PyLongDerived.java --- a/src/org/python/core/PyLongDerived.java +++ b/src/org/python/core/PyLongDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyModuleDerived.java b/src/org/python/core/PyModuleDerived.java --- a/src/org/python/core/PyModuleDerived.java +++ b/src/org/python/core/PyModuleDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyModuleDerived(PyType subtype) { diff --git a/src/org/python/core/PyObjectDerived.java b/src/org/python/core/PyObjectDerived.java --- a/src/org/python/core/PyObjectDerived.java +++ b/src/org/python/core/PyObjectDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyPropertyDerived.java b/src/org/python/core/PyPropertyDerived.java --- a/src/org/python/core/PyPropertyDerived.java +++ b/src/org/python/core/PyPropertyDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PySetDerived.java b/src/org/python/core/PySetDerived.java --- a/src/org/python/core/PySetDerived.java +++ b/src/org/python/core/PySetDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyStringDerived.java b/src/org/python/core/PyStringDerived.java --- a/src/org/python/core/PyStringDerived.java +++ b/src/org/python/core/PyStringDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PySuperDerived.java b/src/org/python/core/PySuperDerived.java --- a/src/org/python/core/PySuperDerived.java +++ b/src/org/python/core/PySuperDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyTupleDerived.java b/src/org/python/core/PyTupleDerived.java --- a/src/org/python/core/PyTupleDerived.java +++ b/src/org/python/core/PyTupleDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/PyTypeDerived.java b/src/org/python/core/PyTypeDerived.java --- a/src/org/python/core/PyTypeDerived.java +++ b/src/org/python/core/PyTypeDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyTypeDerived(PyType subtype) { diff --git a/src/org/python/core/PyUnicodeDerived.java b/src/org/python/core/PyUnicodeDerived.java --- a/src/org/python/core/PyUnicodeDerived.java +++ b/src/org/python/core/PyUnicodeDerived.java @@ -28,7 +28,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/core/finalization/FinalizablePyObject.java b/src/org/python/core/finalization/FinalizablePyObject.java --- a/src/org/python/core/finalization/FinalizablePyObject.java +++ b/src/org/python/core/finalization/FinalizablePyObject.java @@ -58,10 +58,14 @@ *
  • * (optional)
    * If your finalizer resurrects the object (Python allows this) and you wish the - * finalizer to run again on next collection of the object:
    + * finalizer to run again on next collection of the object:
    * In the block where the resurrection occurs, let your {@code __del__}- or * {@code __del_builtin__}-method call
    * {@code FinalizeTrigger.ensureFinalizer(this);}. + * If you implement {@code __del__} in Python and need this functionality, you can + * simply call {@code someObject.__ensure_finalizer__()}
    + * Note that this is Jython specific and should be surrounded by a {@code try/except} + * block to ensure compatibility with other Python implementations. *
  • * *

    @@ -73,6 +77,21 @@ * achieve this manually via step 5). *

    *

    + * The built-in function {@code __ensure_finalizer__} is also useful if a class acquires a + * finalizer after instances have already been created. Usually only those instances that were + * created after their class acquired the finalizer will actually be finalized (in contrast to + * CPython). + * However, one can manually tell earlier created instances to become finalizable by + * calling {@code __ensure_finalizer__()} on them. As mentioned above, it is recommended to + * surround this with a {@code try/except} block to ensure compatibility with other Python + * implementations. + *

    + *

    + * Note that it is not possible to overwrite {@code __ensure_finalizer__} on Python side. + * If one overwrites {@code __ensure_finalizer__} on Python side, Jython will ignore the + * overwrite-implementation and still call the original one. + *

    + *

    * It is possible to switch finalization on and off at any desired time for a certain object. * This can be helpful if it is only necessary to have {@code __del__} or * {@code __del_builtin__} called for certain configurations of an object. diff --git a/src/org/python/core/finalization/FinalizeTrigger.java b/src/org/python/core/finalization/FinalizeTrigger.java --- a/src/org/python/core/finalization/FinalizeTrigger.java +++ b/src/org/python/core/finalization/FinalizeTrigger.java @@ -9,8 +9,9 @@ public class FinalizeTrigger { /** - * This optional factory hook allows to replace the - * default {@code FinalizeTrigger}. It is f.i. needed by JyNI. + * This factory hook is reserved for use by JyNI. + * It allows to replace the default {@code FinalizeTrigger}. + * JyNI needs it to support garbage collection. */ public static FinalizeTriggerFactory factory; diff --git a/src/org/python/core/finalization/FinalizeTriggerFactory.java b/src/org/python/core/finalization/FinalizeTriggerFactory.java --- a/src/org/python/core/finalization/FinalizeTriggerFactory.java +++ b/src/org/python/core/finalization/FinalizeTriggerFactory.java @@ -1,6 +1,9 @@ package org.python.core.finalization; +/** + * Reserved for use by JyNI. + */ public interface FinalizeTriggerFactory { - - public FinalizeTrigger makeTrigger(HasFinalizeTrigger toFinalize); + + public FinalizeTrigger makeTrigger(HasFinalizeTrigger toFinalize); } diff --git a/src/org/python/modules/PyStructDerived.java b/src/org/python/modules/PyStructDerived.java --- a/src/org/python/modules/PyStructDerived.java +++ b/src/org/python/modules/PyStructDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/_collections/PyDefaultDictDerived.java b/src/org/python/modules/_collections/PyDefaultDictDerived.java --- a/src/org/python/modules/_collections/PyDefaultDictDerived.java +++ b/src/org/python/modules/_collections/PyDefaultDictDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/_collections/PyDequeDerived.java b/src/org/python/modules/_collections/PyDequeDerived.java --- a/src/org/python/modules/_collections/PyDequeDerived.java +++ b/src/org/python/modules/_collections/PyDequeDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/_csv/PyDialectDerived.java b/src/org/python/modules/_csv/PyDialectDerived.java --- a/src/org/python/modules/_csv/PyDialectDerived.java +++ b/src/org/python/modules/_csv/PyDialectDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyDialectDerived(PyType subtype) { diff --git a/src/org/python/modules/_functools/PyPartialDerived.java b/src/org/python/modules/_functools/PyPartialDerived.java --- a/src/org/python/modules/_functools/PyPartialDerived.java +++ b/src/org/python/modules/_functools/PyPartialDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/_io/PyFileIODerived.java b/src/org/python/modules/_io/PyFileIODerived.java --- a/src/org/python/modules/_io/PyFileIODerived.java +++ b/src/org/python/modules/_io/PyFileIODerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyFileIODerived(PyType subtype,PyObject file,OpenMode mode,boolean closefd) { diff --git a/src/org/python/modules/_io/PyIOBaseDerived.java b/src/org/python/modules/_io/PyIOBaseDerived.java --- a/src/org/python/modules/_io/PyIOBaseDerived.java +++ b/src/org/python/modules/_io/PyIOBaseDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyIOBaseDerived(PyType subtype) { diff --git a/src/org/python/modules/_io/PyRawIOBaseDerived.java b/src/org/python/modules/_io/PyRawIOBaseDerived.java --- a/src/org/python/modules/_io/PyRawIOBaseDerived.java +++ b/src/org/python/modules/_io/PyRawIOBaseDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyRawIOBaseDerived(PyType subtype) { diff --git a/src/org/python/modules/_weakref/ReferenceTypeDerived.java b/src/org/python/modules/_weakref/ReferenceTypeDerived.java --- a/src/org/python/modules/_weakref/ReferenceTypeDerived.java +++ b/src/org/python/modules/_weakref/ReferenceTypeDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2CompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2CompressorDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java --- a/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java +++ b/src/org/python/modules/bz2/PyBZ2DecompressorDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/bz2/PyBZ2FileDerived.java b/src/org/python/modules/bz2/PyBZ2FileDerived.java --- a/src/org/python/modules/bz2/PyBZ2FileDerived.java +++ b/src/org/python/modules/bz2/PyBZ2FileDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/PyTeeIteratorDerived.java b/src/org/python/modules/itertools/PyTeeIteratorDerived.java --- a/src/org/python/modules/itertools/PyTeeIteratorDerived.java +++ b/src/org/python/modules/itertools/PyTeeIteratorDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/chainDerived.java b/src/org/python/modules/itertools/chainDerived.java --- a/src/org/python/modules/itertools/chainDerived.java +++ b/src/org/python/modules/itertools/chainDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/combinationsDerived.java b/src/org/python/modules/itertools/combinationsDerived.java --- a/src/org/python/modules/itertools/combinationsDerived.java +++ b/src/org/python/modules/itertools/combinationsDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java --- a/src/org/python/modules/itertools/combinationsWithReplacementDerived.java +++ b/src/org/python/modules/itertools/combinationsWithReplacementDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/compressDerived.java b/src/org/python/modules/itertools/compressDerived.java --- a/src/org/python/modules/itertools/compressDerived.java +++ b/src/org/python/modules/itertools/compressDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/countDerived.java b/src/org/python/modules/itertools/countDerived.java --- a/src/org/python/modules/itertools/countDerived.java +++ b/src/org/python/modules/itertools/countDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/cycleDerived.java b/src/org/python/modules/itertools/cycleDerived.java --- a/src/org/python/modules/itertools/cycleDerived.java +++ b/src/org/python/modules/itertools/cycleDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/dropwhileDerived.java b/src/org/python/modules/itertools/dropwhileDerived.java --- a/src/org/python/modules/itertools/dropwhileDerived.java +++ b/src/org/python/modules/itertools/dropwhileDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/groupbyDerived.java b/src/org/python/modules/itertools/groupbyDerived.java --- a/src/org/python/modules/itertools/groupbyDerived.java +++ b/src/org/python/modules/itertools/groupbyDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/ifilterDerived.java b/src/org/python/modules/itertools/ifilterDerived.java --- a/src/org/python/modules/itertools/ifilterDerived.java +++ b/src/org/python/modules/itertools/ifilterDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/ifilterfalseDerived.java b/src/org/python/modules/itertools/ifilterfalseDerived.java --- a/src/org/python/modules/itertools/ifilterfalseDerived.java +++ b/src/org/python/modules/itertools/ifilterfalseDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/isliceDerived.java b/src/org/python/modules/itertools/isliceDerived.java --- a/src/org/python/modules/itertools/isliceDerived.java +++ b/src/org/python/modules/itertools/isliceDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/izipDerived.java b/src/org/python/modules/itertools/izipDerived.java --- a/src/org/python/modules/itertools/izipDerived.java +++ b/src/org/python/modules/itertools/izipDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/izipLongestDerived.java b/src/org/python/modules/itertools/izipLongestDerived.java --- a/src/org/python/modules/itertools/izipLongestDerived.java +++ b/src/org/python/modules/itertools/izipLongestDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/permutationsDerived.java b/src/org/python/modules/itertools/permutationsDerived.java --- a/src/org/python/modules/itertools/permutationsDerived.java +++ b/src/org/python/modules/itertools/permutationsDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/productDerived.java b/src/org/python/modules/itertools/productDerived.java --- a/src/org/python/modules/itertools/productDerived.java +++ b/src/org/python/modules/itertools/productDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/repeatDerived.java b/src/org/python/modules/itertools/repeatDerived.java --- a/src/org/python/modules/itertools/repeatDerived.java +++ b/src/org/python/modules/itertools/repeatDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/starmapDerived.java b/src/org/python/modules/itertools/starmapDerived.java --- a/src/org/python/modules/itertools/starmapDerived.java +++ b/src/org/python/modules/itertools/starmapDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/itertools/takewhileDerived.java b/src/org/python/modules/itertools/takewhileDerived.java --- a/src/org/python/modules/itertools/takewhileDerived.java +++ b/src/org/python/modules/itertools/takewhileDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/random/PyRandomDerived.java b/src/org/python/modules/random/PyRandomDerived.java --- a/src/org/python/modules/random/PyRandomDerived.java +++ b/src/org/python/modules/random/PyRandomDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/org/python/modules/thread/PyLocalDerived.java b/src/org/python/modules/thread/PyLocalDerived.java --- a/src/org/python/modules/thread/PyLocalDerived.java +++ b/src/org/python/modules/thread/PyLocalDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } public PyLocalDerived(PyType subtype) { diff --git a/src/org/python/modules/zipimport/zipimporterDerived.java b/src/org/python/modules/zipimport/zipimporterDerived.java --- a/src/org/python/modules/zipimport/zipimporterDerived.java +++ b/src/org/python/modules/zipimport/zipimporterDerived.java @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger=FinalizeTrigger.makeTrigger(this); } private PyObject dict; diff --git a/src/templates/gderived-defs b/src/templates/gderived-defs --- a/src/templates/gderived-defs +++ b/src/templates/gderived-defs @@ -17,11 +17,11 @@ public void setSlot(int index, PyObject value) { slots[index] = value; } - + private PyObject[] slots; - + public void __del_derived__() { - PyType self_type = getType(); + PyType self_type = getType(); PyObject impl = self_type.lookup("__del__"); if (impl != null) { impl.__get__(this, self_type).__call__(); @@ -29,7 +29,7 @@ } public void __ensure_finalizer__() { - FinalizeTrigger.ensureFinalizer(this); + finalizeTrigger = FinalizeTrigger.makeTrigger(this); } `decls; @@ -44,7 +44,7 @@ if (impl != null) { PyObject res = impl.__get__(this,self_type).__call__(other); if (res == Py.NotImplemented) - return null; + return null; return res; } return super.`binary(other); @@ -56,7 +56,7 @@ if (impl != null) { PyObject res = impl.__get__(this,self_type).__call__(other); if (res == Py.NotImplemented) - return null; + return null; return res; } return super.`binary(other); -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Fri Sep 5 18:19:58 2014 From: jython-checkins at python.org (jim.baker) Date: Fri, 5 Sep 2014 18:19:58 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Add_new_jythonlib_module_to?= =?utf-8?q?_support_libraries_in_stdlib_that_are?= Message-ID: <3hqPHL0vh4z7Ljp@mail.python.org> http://hg.python.org/jython/rev/7a96264b09ab changeset: 7368:7a96264b09ab user: Jim Baker date: Fri Sep 05 10:19:32 2014 -0600 summary: Add new jythonlib module to support libraries in stdlib that are written in Python (examples: _socket, threading) that need more precise integration from Java and Jython's runtime. For now, this includes building dicts with arbitrary ConcurrentMap backing, especially for Google Guava's MapMaker, without seeing boxing/unboxing issues moving between Java and Python code. Fixes http://bugs.jython.org/issue2192 Unblocks http://bugs.jython.org/issue1631 files: Lib/_socket.py | 9 +- Lib/jythonlib.py | 16 ++ Lib/test/test_threading_jy.py | 2 +- Lib/threading.py | 19 ++- build.xml | 2 +- src/org/python/core/PyDictionary.java | 7 +- src/org/python/modules/Setup.java | 59 +++++---- src/org/python/modules/_jythonlib/_jythonlib.java | 23 +++ src/org/python/modules/_jythonlib/dict_builder.java | 40 ++++++ src/org/python/modules/_threading/_threading.java | 19 +-- 10 files changed, 141 insertions(+), 55 deletions(-) diff --git a/Lib/_socket.py b/Lib/_socket.py --- a/Lib/_socket.py +++ b/Lib/_socket.py @@ -13,11 +13,11 @@ from contextlib import contextmanager from functools import partial, wraps from itertools import chain +from jythonlib import MapMaker, dict_builder from numbers import Number from StringIO import StringIO from threading import Condition, Lock from types import MethodType, NoneType -from weakref import WeakKeyDictionary import java from java.io import IOException, InterruptedIOException @@ -428,7 +428,7 @@ def __init__(self): self.queue = LinkedBlockingQueue() self.registered = dict() # fd -> eventmask - self.socks2fd = WeakKeyDictionary() # sock -> fd + self.socks2fd = dict_builder(MapMaker().weakKeys().makeMap)() # sock -> fd def notify(self, sock, exception=None, hangup=False): notification = _PollNotification( @@ -566,7 +566,6 @@ def exceptionCaught(self, ctx, cause): log.debug("Channel caught exception %s", cause, extra={"sock": self.sock}) self.sock._notify_selectors(exception=cause) - ctx.fireExceptionCaught(cause) class ChildSocketHandler(ChannelInitializer): @@ -885,8 +884,8 @@ self.accepted_children = 1 # include the parent as well to simplify close logic b = ServerBootstrap() - self.parent_group = NioEventLoopGroup(2, DaemonThreadFactory("Jython-Netty-Parent-%s")) - self.child_group = NioEventLoopGroup(2, DaemonThreadFactory("Jython-Netty-Child-%s")) + self.parent_group = NioEventLoopGroup(10, DaemonThreadFactory("Jython-Netty-Parent-%s")) + self.child_group = NioEventLoopGroup(10, DaemonThreadFactory("Jython-Netty-Child-%s")) b.group(self.parent_group, self.child_group) b.channel(NioServerSocketChannel) b.option(ChannelOption.SO_BACKLOG, backlog) diff --git a/Lib/jythonlib.py b/Lib/jythonlib.py new file mode 100644 --- /dev/null +++ b/Lib/jythonlib.py @@ -0,0 +1,16 @@ +from _jythonlib import * + +# Convenience imports, since this is the most common case for using +# jythonlib, especially with MapMaker + +try: + # jarjar-ed version + import org.python.google.common as guava + from org.python.google.common.collect import MapMaker + from org.python.google.common.cache import CacheBuilder, CacheLoader +except ImportError: + # dev version from extlibs + import com.google.common as guava + from com.google.common.collect import MapMaker + from com.google.common.cache import CacheBuilder, CacheLoader + diff --git a/Lib/test/test_threading_jy.py b/Lib/test/test_threading_jy.py --- a/Lib/test/test_threading_jy.py +++ b/Lib/test/test_threading_jy.py @@ -112,7 +112,7 @@ def test_main(): test_support.run_unittest( JavaIntegrationTestCase, - MemoryLeakTestCase, + #MemoryLeakTestCase, ThreadingTestCase, TwistedTestCase) diff --git a/Lib/threading.py b/Lib/threading.py --- a/Lib/threading.py +++ b/Lib/threading.py @@ -4,13 +4,15 @@ from java.util.concurrent.locks import ReentrantLock from org.python.util import jython from org.python.core import Py +from jythonlib import CacheBuilder, CacheLoader, MapMaker, dict_builder from thread import _newFunctionThread from thread import _local as local -from _threading import Lock, RLock, Condition, _Lock, _RLock, _threads, _active, _jthread_to_pythread, _register_thread, _unregister_thread +from _threading import Lock, RLock, Condition, _Lock, _RLock import java.lang.Thread import sys as _sys from traceback import print_exc as _print_exc + # Rename some stuff so "from threading import *" is safe __all__ = ['activeCount', 'active_count', 'Condition', 'currentThread', 'current_thread', 'enumerate', 'Event', @@ -57,6 +59,8 @@ _trace_hook = func + + class Semaphore(object): def __init__(self, value=1): if value < 0: @@ -175,6 +179,17 @@ return Py.NoConversion +_threads = dict_builder(MapMaker().weakValues().makeMap)() +_active = _threads + +def _register_thread(jthread, pythread): + _threads[jthread.getId()] = pythread + +def _unregister_thread(jthread): + _threads.pop(jthread.getId(), None) + + + class Thread(JavaThread): def __init__(self, group=None, target=None, name=None, args=None, kwargs=None): assert group is None, "group argument must be None for now" @@ -284,7 +299,7 @@ def currentThread(): jthread = java.lang.Thread.currentThread() - pythread = _jthread_to_pythread[jthread] + pythread = _threads.get(jthread.getId()) if pythread is None: pythread = JavaThread(jthread) return pythread diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -475,7 +475,7 @@ debug="${debug}" deprecation="${deprecation}" nowarn="${nowarn}" - memoryMaximumSize="512m" + memoryMaximumSize="1024m" fork="true" encoding="UTF-8"> diff --git a/src/org/python/core/PyDictionary.java b/src/org/python/core/PyDictionary.java --- a/src/org/python/core/PyDictionary.java +++ b/src/org/python/core/PyDictionary.java @@ -69,6 +69,11 @@ this(TYPE, map); } + public PyDictionary(ConcurrentMap backingMap, boolean useBackingMap) { + super(TYPE); + internalMap = backingMap; + } + /** * Create a new dictionary which is populated with entries the given map. */ @@ -460,7 +465,7 @@ updateCommon(args, keywords, "update"); } - private void updateCommon(PyObject[] args, String[] keywords, String methName) { + public void updateCommon(PyObject[] args, String[] keywords, String methName) { int nargs = args.length - keywords.length; if (nargs > 1) { throw PyBuiltinCallable.DefaultInfo.unexpectedCall(nargs, false, methName, 0, 1); diff --git a/src/org/python/modules/Setup.java b/src/org/python/modules/Setup.java --- a/src/org/python/modules/Setup.java +++ b/src/org/python/modules/Setup.java @@ -27,41 +27,42 @@ // python.modules.builtin for details. public static String[] builtinModules = { - "jarray", - "math", - "thread:org.python.modules.thread.thread", - "operator", - "time:org.python.modules.time.Time", + "_ast:org.python.antlr.ast.AstModule", + "_codecs", + "_collections:org.python.modules._collections.Collections", + "_csv:org.python.modules._csv._csv", + "_functools:org.python.modules._functools._functools", + "_hashlib", + "_io:org.python.modules._io._io", + "_jythonlib:org.python.modules._jythonlib._jythonlib", + "_marshal", "_py_compile", + "_random:org.python.modules.random.RandomModule", "_sre", - "synchronize", + "_systemrestart", + "_threading:org.python.modules._threading._threading", + "_weakref:org.python.modules._weakref.WeakrefModule", + "array:org.python.modules.ArrayModule", + "binascii", + "bz2:org.python.modules.bz2.bz2", "cPickle", "cStringIO", + "cmath", + "errno", + "exceptions:org.python.core.exceptions", + "gc", + "imp", + "itertools:org.python.modules.itertools.itertools", + "jarray", + "jffi:org.python.modules.jffi.jffi", + "math", + "operator", "struct", - "binascii", - "exceptions:org.python.core.exceptions", - "_codecs", - "imp", + "synchronize", + "thread:org.python.modules.thread.thread", + "time:org.python.modules.time.Time", "ucnhash", - "_weakref:org.python.modules._weakref.WeakrefModule", - "errno", - "array:org.python.modules.ArrayModule", - "_random:org.python.modules.random.RandomModule", - "cmath", - "itertools:org.python.modules.itertools.itertools", "zipimport:org.python.modules.zipimport.zipimport", - "_collections:org.python.modules._collections.Collections", - "gc", - "_hashlib", - "_functools:org.python.modules._functools._functools", - "_csv:org.python.modules._csv._csv", - "_systemrestart", - "_ast:org.python.antlr.ast.AstModule", - "_marshal", - "_threading:org.python.modules._threading._threading", - PosixModule.getOSName() + ":org.python.modules.posix.PosixModule", - "jffi:org.python.modules.jffi.jffi", - "_io:org.python.modules._io._io", - "bz2:org.python.modules.bz2.bz2" + PosixModule.getOSName() + ":org.python.modules.posix.PosixModule" }; } diff --git a/src/org/python/modules/_jythonlib/_jythonlib.java b/src/org/python/modules/_jythonlib/_jythonlib.java new file mode 100644 --- /dev/null +++ b/src/org/python/modules/_jythonlib/_jythonlib.java @@ -0,0 +1,23 @@ +/* Copyright (c) Jython Developers */ +package org.python.modules._jythonlib; + +import org.python.core.ClassDictInit; +import org.python.core.PyObject; +import org.python.core.PyString; + + +public class _jythonlib implements ClassDictInit { + + public static final PyString __doc__ = new PyString("jythonlib module"); + + public static void classDictInit(PyObject dict) { + dict.__setitem__("__name__", new PyString("_jythonlib")); + dict.__setitem__("__doc__", __doc__); + dict.__setitem__("__module__", new PyString("_jythonlib")); + dict.__setitem__("dict_builder", dict_builder.TYPE); + + // Hide from Python + dict.__setitem__("classDictInit", null); + } + +} diff --git a/src/org/python/modules/_jythonlib/dict_builder.java b/src/org/python/modules/_jythonlib/dict_builder.java new file mode 100644 --- /dev/null +++ b/src/org/python/modules/_jythonlib/dict_builder.java @@ -0,0 +1,40 @@ +/* Copyright (c) Jython Developers */ +package org.python.modules._jythonlib; + +import org.python.core.PyDictionary; +import org.python.core.PyObject; +import org.python.core.PyType; + +import java.util.concurrent.ConcurrentMap; + + +/* Support building PyDictionary objects with arbitrary backing ConcurrentMap objects + * Uses a factory for efficiency. + * Usage from Python: _threads = dict_builder(MapMaker().weakValues().makeMap)() + * + * Such usage avoids problems with converting from boxed Python objects to their unboxed + * versions, compared to building this in Java and exporting to Python via PyJavaType. + * So in the above example_threads dict maps from thread ID to JavaThread. + * But thread ID is a long, which meant that we did not have equality between long/int, as in Python + * JavaThread also exposes __java__ to convert to the backing thread, but this meant this would + * also be unboxed this way, so the wrapping thread could not be looked up! + */ + +public class dict_builder extends PyObject { + + public static final PyType TYPE = PyType.fromClass(dict_builder.class); + private final PyObject factory; + + public dict_builder(PyObject factory) { + super(); + this.factory = factory; + } + + public PyObject __call__(PyObject[] args, String[] keywords) { + ConcurrentMap map = (ConcurrentMap) (factory.__call__().__tojava__(ConcurrentMap.class)); + PyDictionary dict = new PyDictionary(map, true); + dict.updateCommon(args, keywords, "dict"); + return dict; + } + +} diff --git a/src/org/python/modules/_threading/_threading.java b/src/org/python/modules/_threading/_threading.java --- a/src/org/python/modules/_threading/_threading.java +++ b/src/org/python/modules/_threading/_threading.java @@ -3,8 +3,7 @@ import org.python.core.ClassDictInit; import org.python.core.Py; import org.python.core.PyObject; -import com.google.common.collect.MapMaker; -import java.util.Map; + public class _threading implements ClassDictInit { @@ -15,21 +14,9 @@ dict.__setitem__("_Lock", Lock.TYPE); dict.__setitem__("_RLock", Lock.TYPE); dict.__setitem__("Condition", Condition.TYPE); -// dict.__setitem__("JavaThread", JavaThread.TYPE); - } - // internals to support threading.py, test_threading.py - public static Map _threads = new MapMaker().weakValues().makeMap(); - public static Map _jthread_to_pythread = new MapMaker().weakKeys().weakValues().makeMap(); - public static Map _active = _threads; - - public static void _register_thread(Thread jthread, PyObject pythread) { - _threads.put(jthread.getId(), pythread); - _jthread_to_pythread.put(jthread, pythread); - } - - public static void _unregister_thread(Thread jthread) { - _threads.remove(jthread.getId()); + // Hide from Python + dict.__setitem__("classDictInit", null); } } -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sun Sep 7 05:56:58 2014 From: jython-checkins at python.org (jim.baker) Date: Sun, 7 Sep 2014 05:56:58 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fix_minor_test_failures_in_?= =?utf-8?q?test=5Fdescrtut=2C_test=5Ffloat=5Fjy=2C?= Message-ID: <3hrJj60hsZz7Ljd@mail.python.org> http://hg.python.org/jython/rev/7fbbad825be4 changeset: 7369:7fbbad825be4 user: Jim Baker date: Sat Sep 06 21:56:50 2014 -0600 summary: Fix minor test failures in test_descrtut, test_float_jy, test_isinstance, test_pbcvm, test_platform, test_pwd, test_select_new, test_sysconfig, and test_unicodedata, in some cases by better skips. files: Lib/platform.py | 1 + Lib/pwd.py | 3 +++ Lib/test/regrtest.py | 1 + Lib/test/test_descrtut.py | 1 + Lib/test/test_float_jy.py | 2 +- Lib/test/test_pbcvm.py | 5 ++++- Lib/test/test_platform.py | 3 +++ Lib/test/test_sysconfig.py | 1 + Lib/test/test_unicodedata.py | 24 +++++++++++++++++------- 9 files changed, 32 insertions(+), 9 deletions(-) diff --git a/Lib/platform.py b/Lib/platform.py --- a/Lib/platform.py +++ b/Lib/platform.py @@ -777,6 +777,7 @@ return release,versioninfo,machine def _mac_ver_xml(): + return None # Jython patch fn = '/System/Library/CoreServices/SystemVersion.plist' if not os.path.exists(fn): return None diff --git a/Lib/pwd.py b/Lib/pwd.py --- a/Lib/pwd.py +++ b/Lib/pwd.py @@ -12,6 +12,7 @@ from os import _name, _posix_impl from org.python.core.Py import newString +import sys if _name == 'nt': raise ImportError, 'pwd module not supported on Windows' @@ -48,6 +49,8 @@ Return the password database entry for the given numeric user ID. See pwd.__doc__ for more on password database entries. """ + if uid > sys.maxint or uid < 0: + raise KeyError entry = _posix_impl.getpwuid(uid) if not entry: raise KeyError(uid) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -1307,6 +1307,7 @@ test_peepholer test_pyclbr test_pyexpat + test_select_new test_stringprep test_threadsignals test_transformer diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py --- a/Lib/test/test_descrtut.py +++ b/Lib/test/test_descrtut.py @@ -182,6 +182,7 @@ '__delitem__', '__delslice__', '__doc__', + '__ensure_finalizer__', '__eq__', '__format__', '__ge__', diff --git a/Lib/test/test_float_jy.py b/Lib/test/test_float_jy.py --- a/Lib/test/test_float_jy.py +++ b/Lib/test/test_float_jy.py @@ -14,7 +14,7 @@ def test_float_repr(self): self.assertEqual(repr(12345678.000000005), '12345678.000000006') self.assertEqual(repr(12345678.0000000005), '12345678.0') - self.assertEqual(repr(math.pi**-100), '1.9275814160560206e-50') + self.assertRegexpMatches(repr(math.pi**-100), '1.927581416056020[0-9]e-50') self.assertEqual(repr(-1.0), '-1.0') self.assertEqual(repr(-9876.543210), '-9876.54321') self.assertEqual(repr(0.123456789e+35), '1.23456789e+34') diff --git a/Lib/test/test_pbcvm.py b/Lib/test/test_pbcvm.py --- a/Lib/test/test_pbcvm.py +++ b/Lib/test/test_pbcvm.py @@ -66,7 +66,10 @@ def test_main(): - test_support.run_unittest(PyBytecodeTest, AdhocRegrtest) + test_support.run_unittest( + PyBytecodeTest, + # AdhocRegrtest # reinstate once we have Python bytecode compilation, too hard to coordinate otherwise + ) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -5,12 +5,14 @@ import subprocess from test import test_support +from test.test_support import is_jython class PlatformTest(unittest.TestCase): def test_architecture(self): res = platform.architecture() if hasattr(os, "symlink"): + @unittest.skipIf(is_jython, "Cannot just symlink Jython startup script") def test_architecture_via_symlink(self): # issue3762 def get(python): cmd = [python, '-c', @@ -162,6 +164,7 @@ def test_win32_ver(self): res = platform.win32_ver() + @unittest.skipIf(is_jython, "No uname support in Jython") def test_mac_ver(self): res = platform.mac_ver() diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -240,6 +240,7 @@ 'java_user'} self.assertEqual({name for name in get_scheme_names()}, wanted) + @unittest.skipIf(is_jython, "Cannot just symlink Jython startup script") def test_symlink(self): # Issue 7880 symlink = get_attribute(os, "symlink") diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -17,15 +17,23 @@ ### Run tests + +def all_codepoints(): + for i in xrange(sys.maxunicode+1): + if i >= 0xD800 and i <= 0xDFFF: + continue + yield i + + class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes expectedchecksum = '4504dffd035baea02c5b9de82bebc3d65e0e0baf' - @unittest.skipIf(test.test_support.is_jython, "Jython uses ICU4J") + @unittest.skipIf(test.test_support.is_jython, "Jython uses ICU4J, so checksum tests are not meaningful") def test_method_checksum(self): h = hashlib.sha1() - for i in range(0x10000): + for i in all_codepoints(): char = unichr(i) data = [ # Predicates (single char) @@ -82,7 +90,7 @@ # update this, if the database changes expectedchecksum = '6ccf1b1a36460d2694f9b0b0f0324942fe70ede6' - @unittest.skipIf(test.test_support.is_jython, "Jython uses ICU4J") + @unittest.skipIf(test.test_support.is_jython, "Jython uses ICU4J, so checksum tests are not meaningful") def test_function_checksum(self): data = [] h = hashlib.sha1() @@ -246,7 +254,7 @@ # i.e. if a character has a decimal value, # its numeric value should be the same. count = 0 - for i in xrange(0x10000): + for i in all_codepoints(): c = unichr(i) dec = self.db.decimal(c, -1) if dec != -1: @@ -259,7 +267,7 @@ # i.e. if a character has a digit value, # its numeric value should be the same. count = 0 - for i in xrange(0x10000): + for i in all_codepoints(): c = unichr(i) dec = self.db.digit(c, -1) if dec != -1: @@ -282,12 +290,14 @@ self.assertTrue(u"\u1d79".upper()==u'\ua77d') self.assertTrue(u".".upper()==u".") + + def test_bug_5828(self): self.assertEqual(u"\u1d79".lower(), u"\u1d79") # Only U+0000 should have U+0000 as its upper/lower/titlecase variant self.assertEqual( [ - c for c in range(sys.maxunicode+1) + c for c in all_codepoints() if u"\x00" in unichr(c).lower()+unichr(c).upper()+unichr(c).title() ], [0] @@ -300,7 +310,7 @@ self.assertEqual(u"\u01c6".title(), u"\u01c5") def test_linebreak_7643(self): - for i in range(0x10000): + for i in all_codepoints(): lines = (unichr(i) + u'A').splitlines() if i in (0x0a, # 0x0b, -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Tue Sep 9 03:05:50 2014 From: jython-checkins at python.org (jim.baker) Date: Tue, 9 Sep 2014 03:05:50 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Support_standard_Python_sem?= =?utf-8?q?antics_for_proxied_java_objects_that?= Message-ID: <3hsSpk58C0z7LjN@mail.python.org> http://hg.python.org/jython/rev/864bbec6ddb5 changeset: 7370:864bbec6ddb5 user: Santoso Wijaya date: Mon Sep 08 18:39:48 2014 -0600 summary: Support standard Python semantics for proxied java objects that implement java.util.Map. Such maps may or may not be concurrent. Note that d[key_not_present] no longer returns None, but raises KeyError, which means this behavior now matches standard dict semantics. Fixes http://bugs.jython.org/issue1631 files: Lib/test/test_dict.py | 115 ++-- Lib/test/test_dict_jy.py | 51 ++- src/org/python/core/PyJavaType.java | 376 +++++++++++++++- 3 files changed, 478 insertions(+), 64 deletions(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -6,13 +6,17 @@ class DictTest(unittest.TestCase): + + _class = None + + def _make_dict(self, pydict): + return pydict if not self._class else self._class(pydict) + def test_constructor(self): # calling built-in types without argument must return empty - self.assertEqual(dict(), {}) - self.assertIsNot(dict(), {}) + self.assertEqual(self._make_dict(dict()), {}) + self.assertIsNot(self._make_dict(dict()), {}) - @unittest.skipIf(test_support.is_jython, - "FIXME: check Jython again when __format__ works better.") def test_literal_constructor(self): # check literal constructor for different sized dicts # (to exercise the BUILD_MAP oparg). @@ -22,16 +26,16 @@ random.shuffle(items) formatted_items = ('{!r}: {:d}'.format(k, v) for k, v in items) dictliteral = '{' + ', '.join(formatted_items) + '}' - self.assertEqual(eval(dictliteral), dict(items)) + self.assertEqual(self._make_dict(eval(dictliteral)), dict(items)) def test_bool(self): - self.assertIs(not {}, True) - self.assertTrue({1: 2}) - self.assertIs(bool({}), False) - self.assertIs(bool({1: 2}), True) + self.assertIs(not self._make_dict({}), True) + self.assertTrue(self._make_dict({1: 2})) + self.assertIs(bool(self._make_dict({})), False) + self.assertIs(bool(self._make_dict({1: 2})), True) def test_keys(self): - d = {} + d = self._make_dict({}) self.assertEqual(d.keys(), []) d = {'a': 1, 'b': 2} k = d.keys() @@ -41,26 +45,28 @@ self.assertRaises(TypeError, d.keys, None) def test_values(self): - d = {} + d = self._make_dict({}) self.assertEqual(d.values(), []) - d = {1:2} + + d = self._make_dict({1:2}) self.assertEqual(d.values(), [2]) self.assertRaises(TypeError, d.values, None) def test_items(self): - d = {} + d = self._make_dict({}) self.assertEqual(d.items(), []) - d = {1:2} + d = self._make_dict({1:2}) self.assertEqual(d.items(), [(1, 2)]) self.assertRaises(TypeError, d.items, None) def test_has_key(self): - d = {} + d = self._make_dict({}) self.assertFalse(d.has_key('a')) - d = {'a': 1, 'b': 2} + + d = self._make_dict({'a': 1, 'b': 2}) k = d.keys() k.sort() self.assertEqual(k, ['a', 'b']) @@ -68,11 +74,12 @@ self.assertRaises(TypeError, d.has_key) def test_contains(self): - d = {} + d = self._make_dict({}) self.assertNotIn('a', d) self.assertFalse('a' in d) self.assertTrue('a' not in d) - d = {'a': 1, 'b': 2} + + d = self._make_dict({'a': 1, 'b': 2}) self.assertIn('a', d) self.assertIn('b', d) self.assertNotIn('c', d) @@ -80,13 +87,14 @@ self.assertRaises(TypeError, d.__contains__) def test_len(self): - d = {} + d = self._make_dict({}) self.assertEqual(len(d), 0) - d = {'a': 1, 'b': 2} + + d = self._make_dict({'a': 1, 'b': 2}) self.assertEqual(len(d), 2) def test_getitem(self): - d = {'a': 1, 'b': 2} + d = self._make_dict({'a': 1, 'b': 2}) self.assertEqual(d['a'], 1) self.assertEqual(d['b'], 2) d['c'] = 3 @@ -104,7 +112,7 @@ def __hash__(self): return 24 - d = {} + d = self._make_dict({}) d[BadEq()] = 42 self.assertRaises(KeyError, d.__getitem__, 23) @@ -124,14 +132,14 @@ self.assertRaises(Exc, d.__getitem__, x) def test_clear(self): - d = {1:1, 2:2, 3:3} + d = self._make_dict({1:1, 2:2, 3:3}) d.clear() self.assertEqual(d, {}) self.assertRaises(TypeError, d.clear, None) def test_update(self): - d = {} + d = self._make_dict({}) d.update({1:100}) d.update({2:20}) d.update({1:1, 2:2, 3:3}) @@ -202,13 +210,13 @@ def next(self): raise Exc() - self.assertRaises(Exc, {}.update, badseq()) - - self.assertRaises(ValueError, {}.update, [(1, 2, 3)]) + d = self._make_dict({}) + self.assertRaises(Exc, d.update, badseq()) + self.assertRaises(ValueError, d.update, [(1, 2, 3)]) def test_fromkeys(self): self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) - d = {} + d = self._make_dict({}) self.assertIsNot(d.fromkeys('abc'), d) self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0}) @@ -257,16 +265,17 @@ self.assertEqual(dict.fromkeys(d, 0), dict(zip(range(6), [0]*6))) def test_copy(self): - d = {1:1, 2:2, 3:3} + d = self._make_dict({1:1, 2:2, 3:3}) self.assertEqual(d.copy(), {1:1, 2:2, 3:3}) - self.assertEqual({}.copy(), {}) + self.assertEqual(self._make_dict({}).copy(), {}) self.assertRaises(TypeError, d.copy, None) def test_get(self): - d = {} + d = self._make_dict({}) self.assertIs(d.get('c'), None) self.assertEqual(d.get('c', 3), 3) - d = {'a': 1, 'b': 2} + + d = self._make_dict({'a': 1, 'b': 2}) self.assertIs(d.get('c'), None) self.assertEqual(d.get('c', 3), 3) self.assertEqual(d.get('a'), 1) @@ -276,7 +285,7 @@ def test_setdefault(self): # dict.setdefault() - d = {} + d = self._make_dict({}) self.assertIs(d.setdefault('key0'), None) d.setdefault('key0', []) self.assertIs(d.setdefault('key0'), None) @@ -314,7 +323,7 @@ self.eq_count += 1 return id(self) == id(other) hashed1 = Hashed() - y = {hashed1: 5} + y = self._make_dict({hashed1: 5}) hashed2 = Hashed() y.setdefault(hashed2, []) self.assertEqual(hashed1.hash_count, 1) @@ -345,12 +354,12 @@ self.assertFalse(a) self.assertFalse(b) - d = {} + d = self._make_dict({}) self.assertRaises(KeyError, d.popitem) def test_pop(self): # Tests for pop with specified key - d = {} + d = self._make_dict({}) k, v = 'abc', 'def' d[k] = v self.assertRaises(KeyError, d.pop, 'ghi') @@ -364,7 +373,7 @@ # (for 64-bit archs). See SF bug #689659. x = 4503599627370496L y = 4503599627370496 - h = {x: 'anything', y: 'something else'} + h = self._make_dict({x: 'anything', y: 'something else'}) self.assertEqual(h[x], h[y]) self.assertEqual(d.pop(k, v), v) @@ -390,18 +399,19 @@ def test_mutatingiteration(self): # changing dict size during iteration - d = {} + d = self._make_dict({}) d[1] = 1 with self.assertRaises(RuntimeError): for i in d: d[i+1] = 1 def test_repr(self): - d = {} + d = self._make_dict({}) self.assertEqual(repr(d), '{}') d[1] = 2 self.assertEqual(repr(d), '{1: 2}') - d = {} + + d = self._make_dict({}) d[1] = d self.assertEqual(repr(d), '{1: {...}}') @@ -411,12 +421,12 @@ def __repr__(self): raise Exc() - d = {1: BadRepr()} + d = self._make_dict({1: BadRepr()}) self.assertRaises(Exc, repr, d) def test_le(self): - self.assertFalse({} < {}) - self.assertFalse({1: 2} < {1L: 2L}) + self.assertFalse(self._make_dict({}) < {}) + self.assertFalse(self._make_dict({1: 2}) < {1L: 2L}) class Exc(Exception): pass @@ -426,8 +436,8 @@ def __hash__(self): return 42 - d1 = {BadCmp(): 1} - d2 = {1: 1} + d1 = self._make_dict({BadCmp(): 1}) + d2 = self._make_dict({1: 1}) with self.assertRaises(Exc): d1 < d2 @@ -435,7 +445,7 @@ def test_missing(self): # Make sure dict doesn't have a __missing__ method self.assertFalse(hasattr(dict, "__missing__")) - self.assertFalse(hasattr({}, "__missing__")) + self.assertFalse(hasattr(self._make_dict({}), "__missing__")) # Test several cases: # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError @@ -477,7 +487,7 @@ def test_tuple_keyerror(self): # SF #1576657 - d = {} + d = self._make_dict({}) with self.assertRaises(KeyError) as c: d[(1,)] self.assertEqual(c.exception.args, ((1,),)) @@ -496,7 +506,7 @@ raise CustomException return other - d = {} + d = self._make_dict({}) x1 = BadDictKey() x2 = BadDictKey() d[x1] = 1 @@ -519,7 +529,7 @@ # exactly the right order, and I can't think of a randomized approach # that would be *likely* to hit a failing case in reasonable time. - d = {} + d = self._make_dict({}) for i in range(5): d[i] = i for i in range(5): @@ -538,7 +548,7 @@ if resizing: d.clear() return False - d = {} + d = self._make_dict({}) resizing = False d[X()] = 1 d[X()] = 2 @@ -553,8 +563,9 @@ # Bug #3537: if an empty but presized dict with a size larger # than 7 was in the freelist, it triggered an assertion failure with self.assertRaises(ZeroDivisionError): - d = {'a': 1 // 0, 'b': None, 'c': None, 'd': None, 'e': None, - 'f': None, 'g': None, 'h': None} + d = self._make_dict( + {'a': 1 // 0, 'b': None, 'c': None, 'd': None, 'e': None, + 'f': None, 'g': None, 'h': None}) d = {} def test_container_iterator(self): diff --git a/Lib/test/test_dict_jy.py b/Lib/test/test_dict_jy.py --- a/Lib/test/test_dict_jy.py +++ b/Lib/test/test_dict_jy.py @@ -2,6 +2,7 @@ import java import unittest from collections import defaultdict +import test_dict class DictInitTest(unittest.TestCase): def testInternalSetitemInInit(self): @@ -120,6 +121,27 @@ x.put((1,2), "xyz") y = dict(x) self.assertEqual(set(y.items()), set([('a', 1), ('b', 2), ('c', 3), ((1,2), "xyz")])) + + def test_hashmap_builtin_pymethods(self): + x = java.util.HashMap() + x['a'] = 1 + x[(1, 2)] = 'xyz' + self.assertEqual({tup for tup in x.iteritems()}, {('a', 1), ((1, 2), 'xyz')}) + self.assertEqual(str(x), repr(x)) + self.assertEqual(type(str(x)), type(repr(x))) + + def test_hashtable_equal(self): + for d in ({}, {1:2}): + x = java.util.Hashtable(d) + self.assertEqual(x, d) + self.assertEqual(d, x) + self.assertEqual(x, java.util.HashMap(d)) + + def test_hashtable_remove(self): + x = java.util.Hashtable({}) + with self.assertRaises(KeyError): + del x[0] + def test_hashtable(self): x = java.util.Hashtable() x.put('a', 1) @@ -130,9 +152,36 @@ self.assertEqual(set(y.items()), set([('a', 1), ('b', 2), ('c', 3), ((1,2), "xyz")])) +class JavaDictTest(test_dict.DictTest): + + _class = java.util.HashMap + + def test_copy_java_hashtable(self): + x = java.util.Hashtable() + xc = x.copy() + self.assertEqual(type(x), type(xc)) + + def test_fromkeys(self): + super(JavaDictTest, self).test_fromkeys() + self.assertEqual(self._class.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) + + def test_repr_value_None(self): + x = self._class({1:None}) + self.assertEqual(repr(x), '{1: None}') + + def test_set_return_None(self): + x = self._class({1:2}) + self.assertEqual(x.__setitem__(1, 3), None) + self.assertEqual(x.__getitem__(1), 3) + + def test_del_return_None(self): + x = self._class({1:2}) + self.assertEqual(x.__delitem__(1), None) + self.assertEqual(len(x), 0) + def test_main(): - test_support.run_unittest(DictInitTest, DictCmpTest, DerivedDictTest, JavaIntegrationTest) + test_support.run_unittest(DictInitTest, DictCmpTest, DerivedDictTest, JavaIntegrationTest, JavaDictTest) if __name__ == '__main__': test_main() diff --git a/src/org/python/core/PyJavaType.java b/src/org/python/core/PyJavaType.java --- a/src/org/python/core/PyJavaType.java +++ b/src/org/python/core/PyJavaType.java @@ -67,6 +67,7 @@ java.util.concurrent.TimeUnit.class); private static Map, PyBuiltinMethod[]> collectionProxies; + private static Map, PyBuiltinMethod[]> postCollectionProxies; /** * Other Java classes this type has MRO conflicts with. This doesn't matter for Java method @@ -531,9 +532,16 @@ } else { dict.__setitem__("__init__", reflctr); } - for (Map.Entry, PyBuiltinMethod[]> entry : getCollectionProxies().entrySet()) { - if (entry.getKey() == forClass) { - for (PyBuiltinMethod meth : entry.getValue()) { + PyBuiltinMethod[] collectionProxyMethods = getCollectionProxies().get(forClass); + if (collectionProxyMethods != null) { + for (PyBuiltinMethod meth : collectionProxyMethods) { + addMethod(meth); + } + } + // allow for some methods to override the Java type's as a late injection + for (Class type : getPostCollectionProxies().keySet()) { + if (type.isAssignableFrom(forClass)) { + for (PyBuiltinMethod meth : getPostCollectionProxies().get(type)) { addMethod(meth); } } @@ -896,11 +904,25 @@ super(name, numArgs); } + protected MapMethod(String name, int minArgs, int maxArgs) { + super(name, minArgs, maxArgs); + } + protected Map asMap(){ return (Map)self.getJavaProxy(); } } + private static class MapClassMethod extends PyBuiltinClassMethodNarrow { + protected MapClassMethod(String name, int minArgs, int maxArgs) { + super(name, minArgs, maxArgs); + } + + protected Class asClass() { + return (Class) self.getJavaProxy(); + } + } + private static abstract class ComparableMethod extends PyBuiltinMethodNarrow { protected ComparableMethod(String name, int numArgs) { super(name, numArgs); @@ -920,9 +942,17 @@ protected abstract boolean getResult(int comparison); } + /** + * Build a map of common Java collection base types (Map, Iterable, etc) that need to be + * injected with Python's equivalent types' builtin methods (__len__, __iter__, iteritems, etc). + * + * @return A map whose key is the base Java collection types and whose entry is a list of + * injected methods. + */ private static Map, PyBuiltinMethod[]> getCollectionProxies() { if (collectionProxies == null) { collectionProxies = Generic.map(); + postCollectionProxies = Generic.map(); PyBuiltinMethodNarrow iterableProxy = new PyBuiltinMethodNarrow("__iter__") { @Override @@ -939,7 +969,7 @@ } }; - PyBuiltinMethodNarrow containsProxy = new PyBuiltinMethodNarrow("__contains__") { + PyBuiltinMethodNarrow containsProxy = new PyBuiltinMethodNarrow("__contains__", 1) { @Override public PyObject __call__(PyObject obj) { Object other = obj.__tojava__(Object.class); @@ -973,6 +1003,56 @@ return Py.java2py(asMap().size()); } }; + PyBuiltinMethodNarrow mapReprProxy = new MapMethod("__repr__", 0) { + @Override + public PyObject __call__() { + StringBuilder repr = new StringBuilder("{"); + for (Map.Entry entry : asMap().entrySet()) { + Object jkey = entry.getKey(); + Object jval = entry.getValue(); + repr.append(jkey.toString()); + repr.append(": "); + repr.append(jval == asMap() ? "{...}" : (jval == null ? "None" : jval.toString())); + repr.append(", "); + } + int lastindex = repr.lastIndexOf(", "); + if (lastindex > -1) { + repr.delete(lastindex, lastindex + 2); + } + repr.append("}"); + return new PyString(repr.toString()); + } + }; + PyBuiltinMethodNarrow mapEqProxy = new MapMethod("__eq__", 1) { + @Override + public PyObject __call__(PyObject other) { + if (other.getType().isSubType(PyDictionary.TYPE)) { + PyDictionary oDict = (PyDictionary) other; + if (asMap().size() != oDict.size()) { + return Py.False; + } + for (Object jkey : asMap().keySet()) { + Object jval = asMap().get(jkey); + PyObject oVal = oDict.__finditem__(Py.java2py(jkey)); + if (oVal == null) { + return Py.False; + } + if (!Py.java2py(jval)._eq(oVal).__nonzero__()) { + return Py.False; + } + } + return Py.True; + } else { + Object oj = other.getJavaProxy(); + if (oj instanceof Map) { + Map oMap = (Map) oj; + return asMap().equals(oMap) ? Py.True : Py.False; + } else { + return null; + } + } + } + }; PyBuiltinMethodNarrow mapIterProxy = new MapMethod("__iter__", 0) { @Override public PyObject __call__() { @@ -986,32 +1066,299 @@ return asMap().containsKey(other) ? Py.True : Py.False; } }; - PyBuiltinMethodNarrow mapGetProxy = new MapMethod("__getitem__", 1) { + // "get" needs to override java.util.Map#get() in its subclasses, too, so this needs to be injected last + // (i.e. when HashMap is loaded not when it is recursively loading its super-type Map) + PyBuiltinMethodNarrow mapGetProxy = new MapMethod("get", 1, 2) { @Override public PyObject __call__(PyObject key) { - return Py.java2py(asMap().get(Py.tojava(key, Object.class))); + return __call__(key, Py.None); + } + @Override + public PyObject __call__(PyObject key, PyObject _default) { + Object jkey = Py.tojava(key, Object.class); + if (asMap().containsKey(jkey)) { + return Py.java2py(asMap().get(jkey)); + } else { + return _default; + } + } + }; + PyBuiltinMethodNarrow mapGetItemProxy = new MapMethod("__getitem__", 1) { + @Override + public PyObject __call__(PyObject key) { + Object jkey = Py.tojava(key, Object.class); + if (asMap().containsKey(jkey)) { + return Py.java2py(asMap().get(jkey)); + } else { + throw Py.KeyError(key); + } } }; PyBuiltinMethodNarrow mapPutProxy = new MapMethod("__setitem__", 2) { @Override public PyObject __call__(PyObject key, PyObject value) { - return Py.java2py(asMap().put(Py.tojava(key, Object.class), - Py.tojava(value, Object.class))); + asMap().put(Py.tojava(key, Object.class), + value == Py.None ? Py.None : Py.tojava(value, Object.class)); + return Py.None; } }; PyBuiltinMethodNarrow mapRemoveProxy = new MapMethod("__delitem__", 1) { @Override public PyObject __call__(PyObject key) { - return Py.java2py(asMap().remove(Py.tojava(key, Object.class))); + Object jkey = Py.tojava(key, Object.class); + if (asMap().remove(jkey) == null) { + throw Py.KeyError(key); + } + return Py.None; + } + }; + PyBuiltinMethodNarrow mapIterItemsProxy = new MapMethod("iteritems", 0) { + @Override + public PyObject __call__() { + final Iterator> entrySetIterator = asMap().entrySet().iterator(); + return new PyIterator() { + @Override + public PyObject __iternext__() { + if (entrySetIterator.hasNext()) { + Map.Entry nextEntry = entrySetIterator.next(); + // yield a Python tuple object (key, value) + return new PyTuple(Py.java2py(nextEntry.getKey()), + Py.java2py(nextEntry.getValue())); + } + return null; + } + }; + } + }; + PyBuiltinMethodNarrow mapHasKeyProxy = new MapMethod("has_key", 1) { + @Override + public PyObject __call__(PyObject key) { + return asMap().containsKey(Py.tojava(key, Object.class)) ? Py.True : Py.False; + } + }; + PyBuiltinMethodNarrow mapKeysProxy = new MapMethod("keys", 0) { + @Override + public PyObject __call__() { + PyList keys = new PyList(); + for (Object key : asMap().keySet()) { + keys.add(Py.java2py(key)); + } + return keys; + } + }; + PyBuiltinMethod mapValuesProxy = new MapMethod("values", 0) { + @Override + public PyObject __call__() { + PyList values = new PyList(); + for (Object value : asMap().values()) { + values.add(Py.java2py(value)); + } + return values; + } + }; + PyBuiltinMethodNarrow mapSetDefaultProxy = new MapMethod("setdefault", 1, 2) { + @Override + public PyObject __call__(PyObject key) { + return __call__(key, Py.None); + } + @Override + public PyObject __call__(PyObject key, PyObject _default) { + Object jkey = Py.tojava(key, Object.class); + Object jval = asMap().get(jkey); + if (jval == null) { + asMap().put(jkey, _default == Py.None? Py.None : Py.tojava(_default, Object.class)); + return _default; + } + return Py.java2py(jval); + } + }; + PyBuiltinMethodNarrow mapPopProxy = new MapMethod("pop", 1, 2) { + @Override + public PyObject __call__(PyObject key) { + return __call__(key, null); + } + @Override + public PyObject __call__(PyObject key, PyObject _default) { + Object jkey = Py.tojava(key, Object.class); + if (asMap().containsKey(jkey)) { + PyObject value = Py.java2py(asMap().remove(jkey)); + assert (value != null); + return Py.java2py(value); + } else { + if (_default == null) { + throw Py.KeyError(key); + } + return _default; + } + } + }; + PyBuiltinMethodNarrow mapPopItemProxy = new MapMethod("popitem", 0) { + @Override + public PyObject __call__() { + if (asMap().size() == 0) { + throw Py.KeyError("popitem(): map is empty"); + } + Object key = asMap().keySet().toArray()[0]; + Object val = asMap().remove(key); + return Py.java2py(val); + } + }; + PyBuiltinMethodNarrow mapItemsProxy = new MapMethod("items", 0) { + @Override + public PyObject __call__() { + PyList items = new PyList(); + for (Map.Entry entry : asMap().entrySet()) { + items.add(new PyTuple(Py.java2py(entry.getKey()), + Py.java2py(entry.getValue()))); + } + return items; + } + }; + PyBuiltinMethodNarrow mapCopyProxy = new MapMethod("copy", 0) { + @Override + public PyObject __call__() { + Map jmap = asMap(); + Map jclone; + try { + jclone = (Map) jmap.getClass().newInstance(); + } catch (IllegalAccessException e) { + throw Py.JavaError(e); + } catch (InstantiationException e) { + throw Py.JavaError(e); + } + for (Map.Entry entry : jmap.entrySet()) { + jclone.put(entry.getKey(), entry.getValue()); + } + return Py.java2py(jclone); + } + }; + PyBuiltinMethodNarrow mapUpdateProxy = new MapMethod("update", 0, 1) { + private Map jmap; + @Override + public PyObject __call__() { + return Py.None; + } + @Override + public PyObject __call__(PyObject other) { + // `other` is either another dict-like object, or an iterable of key/value pairs (as tuples + // or other iterables of length two) + return __call__(new PyObject[]{other}, new String[]{}); + } + @Override + public PyObject __call__(PyObject[] args, String[] keywords) { + if ((args.length - keywords.length) != 1) { + throw info.unexpectedCall(args.length, false); + } + jmap = asMap(); + PyObject other = args[0]; + // update with entries from `other` (adapted from their equivalent in PyDictionary#update) + Object proxy = other.getJavaProxy(); + if (proxy instanceof Map) { + merge((Map)proxy); + } + else if (other.__findattr__("keys") != null) { + merge(other); + } else { + mergeFromSeq(other); + } + // update with entries from keyword arguments + for (int i = 0; i < keywords.length; i++) { + String jkey = keywords[i]; + PyObject value = args[1+i]; + jmap.put(jkey, Py.tojava(value, Object.class)); + } + return Py.None; + } + private void merge(Map other) { + for (Map.Entry entry : other.entrySet()) { + jmap.put(entry.getKey(), entry.getValue()); + } + } + private void merge(PyObject other) { + if (other instanceof PyDictionary) { + jmap.putAll(((PyDictionary) other).getMap()); + } else if (other instanceof PyStringMap) { + mergeFromKeys(other, ((PyStringMap)other).keys()); + } else { + mergeFromKeys(other, other.invoke("keys")); + } + } + private void mergeFromKeys(PyObject other, PyObject keys) { + for (PyObject key : keys.asIterable()) { + jmap.put(Py.tojava(key, Object.class), + Py.tojava(other.__getitem__(key), Object.class)); + } + } + private void mergeFromSeq(PyObject other) { + PyObject pairs = other.__iter__(); + PyObject pair; + + for (int i = 0; (pair = pairs.__iternext__()) != null; i++) { + try { + pair = PySequence.fastSequence(pair, ""); + } catch(PyException pye) { + if (pye.match(Py.TypeError)) { + throw Py.TypeError(String.format("cannot convert dictionary update sequence " + + "element #%d to a sequence", i)); + } + throw pye; + } + int n; + if ((n = pair.__len__()) != 2) { + throw Py.ValueError(String.format("dictionary update sequence element #%d " + + "has length %d; 2 is required", i, n)); + } + jmap.put(Py.tojava(pair.__getitem__(0), Object.class), + Py.tojava(pair.__getitem__(1), Object.class)); + } + } + }; + PyBuiltinClassMethodNarrow mapFromKeysProxy = new MapClassMethod("fromkeys", 1, 2) { + @Override + public PyObject __call__(PyObject keys) { + return __call__(keys, null); + } + @Override + public PyObject __call__(PyObject keys, PyObject _default) { + Object defobj = _default == null ? Py.None : Py.tojava(_default, Object.class); + Class theClass = asClass(); + try { + // always injected to java.util.Map, so we know the class object we get from asClass is subtype of java.util.Map + Map theMap = (Map) theClass.newInstance(); + for (PyObject key : keys.asIterable()) { + theMap.put(Py.tojava(key, Object.class), defobj); + } + return Py.java2py(theMap); + } catch (InstantiationException e) { + throw Py.JavaError(e); + } catch (IllegalAccessException e) { + throw Py.JavaError(e); + } } }; collectionProxies.put(Map.class, new PyBuiltinMethod[] {mapLenProxy, // map IterProxy can conflict with Iterable.class; fix after the fact in handleMroError mapIterProxy, + mapReprProxy, + mapEqProxy, mapContainsProxy, - mapGetProxy, + mapGetItemProxy, + //mapGetProxy, mapPutProxy, - mapRemoveProxy}); + mapRemoveProxy, + mapIterItemsProxy, + mapHasKeyProxy, + mapKeysProxy, + //mapValuesProxy, + mapSetDefaultProxy, + mapPopProxy, + mapPopItemProxy, + mapItemsProxy, + mapCopyProxy, + mapUpdateProxy, + mapFromKeysProxy}); // class method + postCollectionProxies.put(Map.class, new PyBuiltinMethod[] {mapGetProxy, + mapValuesProxy}); PyBuiltinMethodNarrow listGetProxy = new ListMethod("__getitem__", 1) { @Override @@ -1040,6 +1387,13 @@ return collectionProxies; } + private static Map, PyBuiltinMethod[]> getPostCollectionProxies() { + getCollectionProxies(); + assert (postCollectionProxies != null); + return postCollectionProxies; + } + + protected static class ListIndexDelegate extends SequenceIndexDelegate { private final List list; -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Tue Sep 9 03:05:51 2014 From: jython-checkins at python.org (jim.baker) Date: Tue, 9 Sep 2014 03:05:51 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Skip_a_couple_of_dict_tests?= =?utf-8?q?_not_relevant_to_proxied_java=2Eutil=2EMap_objects=2E?= Message-ID: <3hsSpl6XjSz7Ljd@mail.python.org> http://hg.python.org/jython/rev/dcd3d1800fc4 changeset: 7371:dcd3d1800fc4 user: Jim Baker date: Mon Sep 08 19:05:34 2014 -0600 summary: Skip a couple of dict tests not relevant to proxied java.util.Map objects. Still need to implement comparisons for such proxied objects other than __eq__. files: Lib/test/test_dict.py | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1,5 +1,7 @@ import unittest from test import test_support +from java.util import Map +from java.util.concurrent import ConcurrentMap import UserDict, random, string import gc, weakref @@ -324,6 +326,8 @@ return id(self) == id(other) hashed1 = Hashed() y = self._make_dict({hashed1: 5}) + if isinstance(y, Map) and not isinstance(y, ConcurrentMap): + raise unittest.SkipTest("java.util.Map objects that do not implement ConcurrentMap have no concurrency guarantees") hashed2 = Hashed() y.setdefault(hashed2, []) self.assertEqual(hashed1.hash_count, 1) @@ -400,6 +404,8 @@ def test_mutatingiteration(self): # changing dict size during iteration d = self._make_dict({}) + if isinstance(d, Map): + raise unittest.SkipTest("java.util.Map objects do not raise exceptions if mutated over iteration") d[1] = 1 with self.assertRaises(RuntimeError): for i in d: -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Tue Sep 9 21:30:21 2014 From: jython-checkins at python.org (alex.gronholm) Date: Tue, 9 Sep 2014 21:30:21 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Added_the_necessary_modules?= =?utf-8?q?_to_the_minimal_install_to_get_the_command_line?= Message-ID: <3hsxK92jhpzSSQ@mail.python.org> http://hg.python.org/jython/rev/69c5761b87e6 changeset: 7372:69c5761b87e6 user: Alex Gr?nholm date: Tue Sep 09 22:29:11 2014 +0300 summary: Added the necessary modules to the minimal install to get the command line interpreter to work (fixes #2204) files: installer/src/java/org/python/util/install/JarInstaller.java | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/installer/src/java/org/python/util/install/JarInstaller.java b/installer/src/java/org/python/util/install/JarInstaller.java --- a/installer/src/java/org/python/util/install/JarInstaller.java +++ b/installer/src/java/org/python/util/install/JarInstaller.java @@ -227,12 +227,14 @@ List coreLibFiles = new ArrayList(); coreLibFiles.add("__future__.py"); coreLibFiles.add("copy.py"); + coreLibFiles.add("copy_reg.py"); coreLibFiles.add("dbexts.py"); coreLibFiles.add("imaplib.py"); coreLibFiles.add("isql.py"); coreLibFiles.add("javaos.py"); coreLibFiles.add("javapath.py"); coreLibFiles.add("jreload.py"); + coreLibFiles.add("linecache.py"); coreLibFiles.add("marshal.py"); coreLibFiles.add("ntpath.py"); coreLibFiles.add("os.py"); @@ -248,7 +250,10 @@ coreLibFiles.add("sre_parse.py"); coreLibFiles.add("stat.py"); coreLibFiles.add("string.py"); + coreLibFiles.add("sysconfig.py"); coreLibFiles.add("threading.py"); + coreLibFiles.add("traceback.py"); + coreLibFiles.add("types.py"); coreLibFiles.add("UserDict.py"); coreLibFiles.add("zipfile.py"); coreLibFiles.add("zlib.py"); -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 10 07:13:46 2014 From: jython-checkins at python.org (jim.baker) Date: Wed, 10 Sep 2014 07:13:46 +0200 (CEST) Subject: [Jython-checkins] =?utf-8?q?jython=3A_Update_inspect=2C_test=5Fin?= =?utf-8?q?spect_to_2=2E7=2C_then_add_Jython_fixes=2E_There_are?= Message-ID: <3htBGL3RFmz7LjT@mail.python.org> http://hg.python.org/jython/rev/68aaff268c3c changeset: 7373:68aaff268c3c user: Jim Baker date: Tue Sep 09 22:13:34 2014 -0700 summary: Update inspect, test_inspect to 2.7, then add Jython fixes. There are some outstanding tests to fix, but inspect on Jython now supports anonymous tuples in function parameters. Fixes http://bugs.jython.org/issue2184 by adding support for inspect.getcallargs files: Lib/inspect.py | 263 +++++++++---- Lib/test/test_inspect.py | 534 +++++++++++++++++++++----- 2 files changed, 607 insertions(+), 190 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -17,7 +17,7 @@ getmodule() - determine the module that an object came from getclasstree() - arrange classes so as to represent their hierarchy - getargspec(), getargvalues() - get info about function arguments + getargspec(), getargvalues(), getcallargs() - get info about function arguments formatargspec(), formatargvalues() - format an argument spec getouterframes(), getinnerframes() - get info about frames currentframe() - get the current stack frame @@ -65,7 +65,7 @@ Class objects provide these attributes: __doc__ documentation string __module__ name of module in which this class was defined""" - return isinstance(object, types.ClassType) or hasattr(object, '__bases__') + return isinstance(object, (type, types.ClassType)) def ismethod(object): """Return true if the object is an instance method. @@ -160,7 +160,7 @@ Generator function objects provides same attributes as functions. - See isfunction.__doc__ for attributes listing.""" + See help(isfunction) for attributes listing.""" return bool((isfunction(object) or ismethod(object)) and object.func_code.co_flags & CO_GENERATOR) @@ -246,14 +246,17 @@ def isabstract(object): """Return true if the object is an abstract base class (ABC).""" - return isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT + return bool(isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT) def getmembers(object, predicate=None): """Return all members of an object as (name, value) pairs sorted by name. Optionally, only return members that satisfy a given predicate.""" results = [] for key in dir(object): - value = getattr(object, key) + try: + value = getattr(object, key) + except AttributeError: + continue if not predicate or predicate(value): results.append((key, value)) results.sort() @@ -289,30 +292,21 @@ names = dir(cls) result = [] for name in names: - # Get the object associated with the name. + # Get the object associated with the name, and where it was defined. # Getting an obj from the __dict__ sometimes reveals more than # using getattr. Static and class methods are dramatic examples. - if name in cls.__dict__: - obj = cls.__dict__[name] + # Furthermore, some objects may raise an Exception when fetched with + # getattr(). This is the case with some descriptors (bug #1785). + # Thus, we only use getattr() as a last resort. + homecls = None + for base in (cls,) + mro: + if name in base.__dict__: + obj = base.__dict__[name] + homecls = base + break else: obj = getattr(cls, name) - - # Figure out where it was defined. - homecls = getattr(obj, "__objclass__", None) - if homecls is None: - # search the dicts. - for base in mro: - if name in base.__dict__: - homecls = base - break - - # Get the object again, in order to get it from the defining - # __dict__ instead of via getattr (if possible). - if homecls is not None and name in homecls.__dict__: - obj = homecls.__dict__[name] - - # Also get the object via getattr. - obj_via_getattr = getattr(cls, name) + homecls = getattr(obj, "__objclass__", homecls) # Classify the object. if isinstance(obj, staticmethod): @@ -321,11 +315,18 @@ kind = "class method" elif isinstance(obj, property): kind = "property" - elif (ismethod(obj_via_getattr) or - ismethoddescriptor(obj_via_getattr)): + elif ismethoddescriptor(obj): kind = "method" + elif isdatadescriptor(obj): + kind = "data" else: - kind = "data" + obj_via_getattr = getattr(cls, name) + if (ismethod(obj_via_getattr) or + ismethoddescriptor(obj_via_getattr)): + kind = "method" + else: + kind = "data" + obj = obj_via_getattr result.append(Attribute(name, kind, homecls, obj)) @@ -403,12 +404,12 @@ if ismodule(object): if hasattr(object, '__file__'): return object.__file__ - raise TypeError('arg is a built-in module') + raise TypeError('{!r} is a built-in module'.format(object)) if isclass(object): object = sys.modules.get(object.__module__) if hasattr(object, '__file__'): return object.__file__ - raise TypeError('arg is a built-in class') + raise TypeError('{!r} is a built-in class'.format(object)) if ismethod(object): object = object.im_func if isfunction(object): @@ -419,8 +420,8 @@ object = object.f_code if iscode(object): return object.co_filename - raise TypeError('arg is not a module, class, method, ' - 'function, traceback, frame, or code object') + raise TypeError('{!r} is not a module, class, method, ' + 'function, traceback, frame, or code object'.format(object)) ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type') @@ -441,7 +442,9 @@ if info: return info[0] def getsourcefile(object): - """Return the Python source file an object was defined in, if it exists.""" + """Return the filename that can be used to locate an object's source. + Return None if no way can be identified to get the source. + """ filename = getfile(object) if string.lower(filename[-4:]) in ('.pyc', '.pyo'): filename = filename[:-4] + '.py' @@ -456,6 +459,9 @@ # only return a non-existent filename if the module has a PEP 302 loader if hasattr(getmodule(object, filename), '__loader__'): return filename + # or it is in the linecache + if filename in linecache.cache: + return filename def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. @@ -522,7 +528,13 @@ or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" - file = getsourcefile(object) or getfile(object) + + file = getfile(object) + sourcefile = getsourcefile(object) + if not sourcefile and file[0] + file[-1] != '<>': + raise IOError('source code not available') + file = sourcefile if sourcefile else file + module = getmodule(object, file) if module: lines = linecache.getlines(file, module.__dict__) @@ -742,60 +754,62 @@ 'varargs' and 'varkw' are the names of the * and ** arguments or None.""" if not iscode(co): - raise TypeError('arg is not a code object') - - if not _jython: - # Jython doesn't have co_code - code = co.co_code + raise TypeError('{!r} is not a code object'.format(co)) nargs = co.co_argcount names = co.co_varnames - args = list(names[:nargs]) - step = 0 - # The following acrobatics are for anonymous (tuple) arguments. - for i in range(nargs): - if args[i][:1] in ('', '.'): - stack, remain, count = [], [], [] - while step < len(code): - op = ord(code[step]) - step = step + 1 - if op >= dis.HAVE_ARGUMENT: - opname = dis.opname[op] - value = ord(code[step]) + ord(code[step+1])*256 - step = step + 2 - if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'): - remain.append(value) - count.append(value) - elif opname == 'STORE_FAST': - stack.append(names[value]) - - # Special case for sublists of length 1: def foo((bar)) - # doesn't generate the UNPACK_TUPLE bytecode, so if - # `remain` is empty here, we have such a sublist. - if not remain: - stack[0] = [stack[0]] - break - else: - remain[-1] = remain[-1] - 1 - while remain[-1] == 0: - remain.pop() - size = count.pop() - stack[-size:] = [stack[-size:]] - if not remain: break - remain[-1] = remain[-1] - 1 - if not remain: break - args[i] = stack[0] + # Jython manages anonymous tuple args differently, and arguably + # with less acrobatics, than CPython which interrogates Python + # bytecode. Look at lib-python/2.7/inspect.py for those specifics, + # which are removed for clarity of presentation and complete lack + # of relevance here. varargs = None if co.co_flags & CO_VARARGS: varargs = co.co_varnames[nargs] - nargs = nargs + 1 varkw = None if co.co_flags & CO_VARKEYWORDS: - varkw = co.co_varnames[nargs] + varkw = co.co_varnames[nargs + (1 if varargs else 0)] + + # Jython specific - different style acrobatics for anonymous (tuple) arguments + # for example: + # + # >>> def spam(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h): return 42 + # >>> spam.func_code.co_varnames + # ('a', 'b', 'c', 'd', '(e, (f))', 'g', 'h', 'e', 'f') + args = [] + for name in names[:nargs]: + if name.startswith('(') and name.endswith(')'): + args.append(_parse_anonymous_tuple_arg(name[1:-1])) + else: + args.append(name) return Arguments(args, varargs, varkw) +def _parse_anonymous_tuple_arg(tuple_arg): + # simple recursive descent parser, assumes no error checking necessary + names = tuple_arg.split(", ") + args = [] + i = 0 + while i < len(names): + name = names[i] + if name.startswith('('): + if name.endswith(')'): + args.append(list(name[1:-1])) + i += 1 + else: + # need to recurse. find closing paren. + for j in xrange(len(names) - 1, i, -1): + if names[j].endswith(')'): + joined = (", ".join(names[i:j+1]))[1:-1] + args.append(_parse_anonymous_tuple_arg(joined)) + i = j + 1 + break + else: + args.append(name) + i += 1 + return args + ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') def getargspec(func): @@ -810,7 +824,7 @@ if ismethod(func): func = func.im_func if not isfunction(func): - raise TypeError('arg is not a Python function') + raise TypeError('{!r} is not a Python function'.format(func)) args, varargs, varkw = getargs(func.func_code) return ArgSpec(args, varargs, varkw, func.func_defaults) @@ -854,8 +868,8 @@ specs = [] if defaults: firstdefault = len(args) - len(defaults) - for i in range(len(args)): - spec = strseq(args[i], formatarg, join) + for i, arg in enumerate(args): + spec = strseq(arg, formatarg, join) if defaults and i >= firstdefault: spec = spec + formatvalue(defaults[i - firstdefault]) specs.append(spec) @@ -889,6 +903,95 @@ specs.append(formatvarkw(varkw) + formatvalue(locals[varkw])) return '(' + string.join(specs, ', ') + ')' +def getcallargs(func, *positional, **named): + """Get the mapping of arguments to values. + + A dict is returned, with keys the function argument names (including the + names of the * and ** arguments, if any), and values the respective bound + values from 'positional' and 'named'.""" + args, varargs, varkw, defaults = getargspec(func) + f_name = func.__name__ + arg2value = {} + + # The following closures are basically because of tuple parameter unpacking. + assigned_tuple_params = [] + def assign(arg, value): + if isinstance(arg, str): + arg2value[arg] = value + else: + assigned_tuple_params.append(arg) + value = iter(value) + for i, subarg in enumerate(arg): + try: + subvalue = next(value) + except StopIteration: + raise ValueError('need more than %d %s to unpack' % + (i, 'values' if i > 1 else 'value')) + assign(subarg,subvalue) + try: + next(value) + except StopIteration: + pass + else: + raise ValueError('too many values to unpack') + def is_assigned(arg): + if isinstance(arg,str): + return arg in arg2value + return arg in assigned_tuple_params + if ismethod(func) and func.im_self is not None: + # implicit 'self' (or 'cls' for classmethods) argument + positional = (func.im_self,) + positional + num_pos = len(positional) + num_total = num_pos + len(named) + num_args = len(args) + num_defaults = len(defaults) if defaults else 0 + for arg, value in zip(args, positional): + assign(arg, value) + if varargs: + if num_pos > num_args: + assign(varargs, positional[-(num_pos-num_args):]) + else: + assign(varargs, ()) + elif 0 < num_args < num_pos: + raise TypeError('%s() takes %s %d %s (%d given)' % ( + f_name, 'at most' if defaults else 'exactly', num_args, + 'arguments' if num_args > 1 else 'argument', num_total)) + elif num_args == 0 and num_total: + if varkw: + if num_pos: + # XXX: We should use num_pos, but Python also uses num_total: + raise TypeError('%s() takes exactly 0 arguments ' + '(%d given)' % (f_name, num_total)) + else: + raise TypeError('%s() takes no arguments (%d given)' % + (f_name, num_total)) + for arg in args: + if isinstance(arg, str) and arg in named: + if is_assigned(arg): + raise TypeError("%s() got multiple values for keyword " + "argument '%s'" % (f_name, arg)) + else: + assign(arg, named.pop(arg)) + if defaults: # fill in any missing values with the defaults + for arg, value in zip(args[-num_defaults:], defaults): + if not is_assigned(arg): + assign(arg, value) + if varkw: + assign(varkw, named) + elif named: + unexpected = next(iter(named)) + if isinstance(unexpected, unicode): + unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace') + raise TypeError("%s() got an unexpected keyword argument '%s'" % + (f_name, unexpected)) + unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) + if unassigned: + num_required = num_args - num_defaults + raise TypeError('%s() takes %s %d %s (%d given)' % ( + f_name, 'at least' if defaults else 'exactly', num_required, + 'arguments' if num_required > 1 else 'argument', num_total)) + return arg2value + # -------------------------------------------------- stack frame extraction Traceback = namedtuple('Traceback', 'filename lineno function code_context index') @@ -907,7 +1010,7 @@ else: lineno = frame.f_lineno if not isframe(frame): - raise TypeError('arg is not a frame or traceback object') + raise TypeError('{!r} is not a frame or traceback object'.format(frame)) filename = getsourcefile(frame) or getfile(frame) if context > 0: diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1,10 +1,14 @@ +import re import sys import types import unittest import inspect +import linecache import datetime +from UserList import UserList +from UserDict import UserDict -from test.test_support import is_jython, run_unittest, check_py3k_warnings +from test.test_support import run_unittest, check_py3k_warnings, is_jython with check_py3k_warnings( ("tuple parameter unpacking has been removed", SyntaxWarning), @@ -12,6 +16,9 @@ from test import inspect_fodder as mod from test import inspect_fodder2 as mod2 +# C module for test_findsource_binary, but note it's not C for Jython :) +import unicodedata + # Functions tested in this suite: # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode, # isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers, @@ -37,15 +44,6 @@ git = mod.StupidGit() -def na_for_jython(fn): - if is_jython: - def do_nothing(*args, **kw): - pass - return do_nothing - else: - return fn - - class IsTestBase(unittest.TestCase): predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode, inspect.isframe, inspect.isfunction, inspect.ismethod, @@ -54,13 +52,13 @@ def istest(self, predicate, exp): obj = eval(exp) - self.failUnless(predicate(obj), '%s(%s)' % (predicate.__name__, exp)) + self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp)) for other in self.predicates - set([predicate]): if predicate == inspect.isgeneratorfunction and\ other == inspect.isfunction: continue - self.failIf(other(obj), 'not %s(%s)' % (other.__name__, exp)) + self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp)) def generator_function_example(self): for i in xrange(2): @@ -77,12 +75,8 @@ def test_excluding_predicates(self): - # XXX: Jython's PySystemState needs more work before this will - # be doable. - if not is_jython: - self.istest(inspect.isbuiltin, 'sys.exit') + #self.istest(inspect.isbuiltin, 'sys.exit') # Not valid for Jython self.istest(inspect.isbuiltin, '[].append') - self.istest(inspect.isclass, 'mod.StupidGit') self.istest(inspect.iscode, 'mod.spam.func_code') self.istest(inspect.isframe, 'tb.tb_frame') self.istest(inspect.isfunction, 'mod.spam') @@ -98,17 +92,63 @@ self.istest(inspect.isgetsetdescriptor, 'type(tb.tb_frame).f_locals') else: - self.failIf(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals)) - - #FIXME: not working in Jython: - #if hasattr(types, 'MemberDescriptorType'): - # self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days') - #else: - # self.failIf(inspect.ismemberdescriptor(datetime.timedelta.days)) + self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals)) + if hasattr(types, 'MemberDescriptorType'): + # Not valid for Jython + # self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days') + pass + else: + self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days)) def test_isroutine(self): - self.assert_(inspect.isroutine(mod.spam)) - self.assert_(inspect.isroutine([].count)) + self.assertTrue(inspect.isroutine(mod.spam)) + self.assertTrue(inspect.isroutine([].count)) + + def test_isclass(self): + self.istest(inspect.isclass, 'mod.StupidGit') + self.assertTrue(inspect.isclass(list)) + + class newstyle(object): pass + self.assertTrue(inspect.isclass(newstyle)) + + class CustomGetattr(object): + def __getattr__(self, attr): + return None + self.assertFalse(inspect.isclass(CustomGetattr())) + + def test_get_slot_members(self): + class C(object): + __slots__ = ("a", "b") + + x = C() + x.a = 42 + members = dict(inspect.getmembers(x)) + self.assertIn('a', members) + self.assertNotIn('b', members) + + def test_isabstract(self): + from abc import ABCMeta, abstractmethod + + class AbstractClassExample(object): + __metaclass__ = ABCMeta + + @abstractmethod + def foo(self): + pass + + class ClassExample(AbstractClassExample): + def foo(self): + pass + + a = ClassExample() + + # Test general behaviour. + self.assertTrue(inspect.isabstract(AbstractClassExample)) + self.assertFalse(inspect.isabstract(ClassExample)) + self.assertFalse(inspect.isabstract(a)) + self.assertFalse(inspect.isabstract(int)) + self.assertFalse(inspect.isabstract(5)) + class TestInterpreterStack(IsTestBase): def __init__(self, *args, **kwargs): @@ -121,7 +161,7 @@ self.istest(inspect.isframe, 'mod.fr') def test_stack(self): - self.assert_(len(mod.st) >= 5) + self.assertTrue(len(mod.st) >= 5) self.assertEqual(mod.st[0][1:], (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0)) self.assertEqual(mod.st[1][1:], @@ -149,11 +189,6 @@ self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals), '(x=11, y=14)') - # TODO - test_previous_frame could be rewritten such that we could - # introspect on the previous frame but without a dependency on - # tuple unpacking - - @na_for_jython def test_previous_frame(self): args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back) self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]]) @@ -169,7 +204,8 @@ def __init__(self, *args, **kwargs): unittest.TestCase.__init__(self, *args, **kwargs) - self.source = file(inspect.getsourcefile(self.fodderFile)).read() + with open(inspect.getsourcefile(self.fodderFile)) as fp: + self.source = fp.read() def sourcerange(self, top, bottom): lines = self.source.split("\n") @@ -205,6 +241,8 @@ self.assertEqual(functions, [('eggs', mod.eggs), ('spam', mod.spam)]) + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") def test_getdoc(self): self.assertEqual(inspect.getdoc(mod), 'A module docstring.') self.assertEqual(inspect.getdoc(mod.StupidGit), @@ -241,6 +279,11 @@ def test_getsourcefile(self): self.assertEqual(inspect.getsourcefile(mod.spam), modfile) self.assertEqual(inspect.getsourcefile(git.abuse), modfile) + fn = "_non_existing_filename_used_for_sourcefile_test.py" + co = compile("None", fn, "exec") + self.assertEqual(inspect.getsourcefile(co), None) + linecache.cache[co.co_filename] = (1, None, "None", co.co_filename) + self.assertEqual(inspect.getsourcefile(co), fn) def test_getfile(self): self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__) @@ -256,6 +299,23 @@ del sys.modules[name] inspect.getmodule(compile('a=10','','single')) + def test_proceed_with_fake_filename(self): + '''doctest monkeypatches linecache to enable inspection''' + fn, source = '', 'def x(): pass\n' + getlines = linecache.getlines + def monkey(filename, module_globals=None): + if filename == fn: + return source.splitlines(True) + else: + return getlines(filename, module_globals) + linecache.getlines = monkey + try: + ns = {} + exec compile(source, fn, 'single') in ns + inspect.getsource(ns["x"]) + finally: + linecache.getlines = getlines + class TestDecorators(GetSourceBase): fodderFile = mod2 @@ -331,10 +391,55 @@ def test_method_in_dynamic_class(self): self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97) + @unittest.skipIf( + not hasattr(unicodedata, '__file__') or + unicodedata.__file__[-4:] in (".pyc", ".pyo") or unicodedata.__file__.endswith('$py.class'), + "unicodedata is not an external binary module") + def test_findsource_binary(self): + self.assertRaises(IOError, inspect.getsource, unicodedata) + self.assertRaises(IOError, inspect.findsource, unicodedata) + + @unittest.skipIf(is_jython, "Not working") + def test_findsource_code_in_linecache(self): + lines = ["x=1"] + co = compile(lines[0], "_dynamically_created_file", "exec") + self.assertRaises(IOError, inspect.findsource, co) + self.assertRaises(IOError, inspect.getsource, co) + linecache.cache[co.co_filename] = (1, None, lines, co.co_filename) + self.assertEqual(inspect.findsource(co), (lines,0)) + self.assertEqual(inspect.getsource(co), lines[0]) + + +class _BrokenDataDescriptor(object): + """ + A broken data descriptor. See bug #1785. + """ + def __get__(*args): + raise AssertionError("should not __get__ data descriptors") + + def __set__(*args): + raise RuntimeError + + def __getattr__(*args): + raise AssertionError("should not __getattr__ data descriptors") + + +class _BrokenMethodDescriptor(object): + """ + A broken method descriptor. See bug #1785. + """ + def __get__(*args): + raise AssertionError("should not __get__ method descriptors") + + def __getattr__(*args): + raise AssertionError("should not __getattr__ method descriptors") + + # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] + class TestClassesAndFunctions(unittest.TestCase): def test_classic_mro(self): # Test classic-class method resolution order. @@ -370,7 +475,6 @@ self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults), formatted) - @na_for_jython def test_getargspec(self): self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)') @@ -385,7 +489,6 @@ pass self.assertArgSpecEquals(A.m, ['self']) - @na_for_jython def test_getargspec_sublistofone(self): with check_py3k_warnings( ("tuple parameter unpacking has been removed", SyntaxWarning), @@ -396,8 +499,18 @@ exec 'def fakeSublistOfOne((foo)): return 1' self.assertArgSpecEquals(fakeSublistOfOne, ['foo']) - def test_classify_oldstyle(self): - class A: + + def _classify_test(self, newstyle): + """Helper for testing that classify_class_attrs finds a bunch of + different kinds of attributes on a given class. + """ + if newstyle: + base = object + else: + class base: + pass + + class A(base): def s(): pass s = staticmethod(s) @@ -413,24 +526,31 @@ datablob = '1' + dd = _BrokenDataDescriptor() + md = _BrokenMethodDescriptor() + attrs = attrs_wo_objs(A) - self.assert_(('s', 'static method', A) in attrs, 'missing static method') - self.assert_(('c', 'class method', A) in attrs, 'missing class method') - self.assert_(('p', 'property', A) in attrs, 'missing property') - self.assert_(('m', 'method', A) in attrs, 'missing plain method') - self.assert_(('m1', 'method', A) in attrs, 'missing plain method') - self.assert_(('datablob', 'data', A) in attrs, 'missing data') + self.assertIn(('s', 'static method', A), attrs, 'missing static method') + self.assertIn(('c', 'class method', A), attrs, 'missing class method') + self.assertIn(('p', 'property', A), attrs, 'missing property') + self.assertIn(('m', 'method', A), attrs, 'missing plain method') + self.assertIn(('m1', 'method', A), attrs, 'missing plain method') + self.assertIn(('datablob', 'data', A), attrs, 'missing data') + self.assertIn(('md', 'method', A), attrs, 'missing method descriptor') + self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor') class B(A): def m(self): pass attrs = attrs_wo_objs(B) - self.assert_(('s', 'static method', A) in attrs, 'missing static method') - self.assert_(('c', 'class method', A) in attrs, 'missing class method') - self.assert_(('p', 'property', A) in attrs, 'missing property') - self.assert_(('m', 'method', B) in attrs, 'missing plain method') - self.assert_(('m1', 'method', A) in attrs, 'missing plain method') - self.assert_(('datablob', 'data', A) in attrs, 'missing data') + self.assertIn(('s', 'static method', A), attrs, 'missing static method') + self.assertIn(('c', 'class method', A), attrs, 'missing class method') + self.assertIn(('p', 'property', A), attrs, 'missing property') + self.assertIn(('m', 'method', B), attrs, 'missing plain method') + self.assertIn(('m1', 'method', A), attrs, 'missing plain method') + self.assertIn(('datablob', 'data', A), attrs, 'missing data') + self.assertIn(('md', 'method', A), attrs, 'missing method descriptor') + self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor') class C(A): @@ -438,93 +558,287 @@ def c(self): pass attrs = attrs_wo_objs(C) - self.assert_(('s', 'static method', A) in attrs, 'missing static method') - self.assert_(('c', 'method', C) in attrs, 'missing plain method') - self.assert_(('p', 'property', A) in attrs, 'missing property') - self.assert_(('m', 'method', C) in attrs, 'missing plain method') - self.assert_(('m1', 'method', A) in attrs, 'missing plain method') - self.assert_(('datablob', 'data', A) in attrs, 'missing data') + self.assertIn(('s', 'static method', A), attrs, 'missing static method') + self.assertIn(('c', 'method', C), attrs, 'missing plain method') + self.assertIn(('p', 'property', A), attrs, 'missing property') + self.assertIn(('m', 'method', C), attrs, 'missing plain method') + self.assertIn(('m1', 'method', A), attrs, 'missing plain method') + self.assertIn(('datablob', 'data', A), attrs, 'missing data') + self.assertIn(('md', 'method', A), attrs, 'missing method descriptor') + self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor') class D(B, C): def m1(self): pass attrs = attrs_wo_objs(D) - self.assert_(('s', 'static method', A) in attrs, 'missing static method') - self.assert_(('c', 'class method', A) in attrs, 'missing class method') - self.assert_(('p', 'property', A) in attrs, 'missing property') - self.assert_(('m', 'method', B) in attrs, 'missing plain method') - self.assert_(('m1', 'method', D) in attrs, 'missing plain method') - self.assert_(('datablob', 'data', A) in attrs, 'missing data') + self.assertIn(('s', 'static method', A), attrs, 'missing static method') + if newstyle: + self.assertIn(('c', 'method', C), attrs, 'missing plain method') + else: + self.assertIn(('c', 'class method', A), attrs, 'missing class method') + self.assertIn(('p', 'property', A), attrs, 'missing property') + self.assertIn(('m', 'method', B), attrs, 'missing plain method') + self.assertIn(('m1', 'method', D), attrs, 'missing plain method') + self.assertIn(('datablob', 'data', A), attrs, 'missing data') + self.assertIn(('md', 'method', A), attrs, 'missing method descriptor') + self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor') - # Repeat all that, but w/ new-style classes. + + def test_classify_oldstyle(self): + """classify_class_attrs finds static methods, class methods, + properties, normal methods, and data attributes on an old-style + class. + """ + self._classify_test(False) + + def test_classify_newstyle(self): - class A(object): + """Just like test_classify_oldstyle, but for a new-style class. + """ + self._classify_test(True) - def s(): pass - s = staticmethod(s) + def test_classify_builtin_types(self): + # Simple sanity check that all built-in types can have their + # attributes classified. + for name in dir(__builtin__): + builtin = getattr(__builtin__, name) + if isinstance(builtin, type): + inspect.classify_class_attrs(builtin) - def c(cls): pass - c = classmethod(c) + def test_getmembers_method(self): + # Old-style classes + class B: + def f(self): + pass - def getp(self): pass - p = property(getp) + self.assertIn(('f', B.f), inspect.getmembers(B)) + # contrary to spec, ismethod() is also True for unbound methods + # (see #1785) + self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod)) + b = B() + self.assertIn(('f', b.f), inspect.getmembers(b)) + self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod)) - def m(self): pass + # New-style classes + class B(object): + def f(self): + pass - def m1(self): pass + self.assertIn(('f', B.f), inspect.getmembers(B)) + self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod)) + b = B() + self.assertIn(('f', b.f), inspect.getmembers(b)) + self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod)) - datablob = '1' - attrs = attrs_wo_objs(A) - self.assert_(('s', 'static method', A) in attrs, 'missing static method') - self.assert_(('c', 'class method', A) in attrs, 'missing class method') - self.assert_(('p', 'property', A) in attrs, 'missing property') - self.assert_(('m', 'method', A) in attrs, 'missing plain method') - self.assert_(('m1', 'method', A) in attrs, 'missing plain method') - self.assert_(('datablob', 'data', A) in attrs, 'missing data') +class TestGetcallargsFunctions(unittest.TestCase): - class B(A): + # tuple parameters are named '.1', '.2', etc. + is_tuplename = re.compile(r'^\.\d+$').match - def m(self): pass + def assertEqualCallArgs(self, func, call_params_string, locs=None): + locs = dict(locs or {}, func=func) + r1 = eval('func(%s)' % call_params_string, None, locs) + r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None, + locs) + self.assertEqual(r1, r2) - attrs = attrs_wo_objs(B) - self.assert_(('s', 'static method', A) in attrs, 'missing static method') - self.assert_(('c', 'class method', A) in attrs, 'missing class method') - self.assert_(('p', 'property', A) in attrs, 'missing property') - self.assert_(('m', 'method', B) in attrs, 'missing plain method') - self.assert_(('m1', 'method', A) in attrs, 'missing plain method') - self.assert_(('datablob', 'data', A) in attrs, 'missing data') + def assertEqualException(self, func, call_param_string, locs=None): + locs = dict(locs or {}, func=func) + try: + eval('func(%s)' % call_param_string, None, locs) + except Exception, ex1: + pass + else: + self.fail('Exception not raised') + try: + eval('inspect.getcallargs(func, %s)' % call_param_string, None, + locs) + except Exception, ex2: + pass + else: + self.fail('Exception not raised') + self.assertIs(type(ex1), type(ex2)) + self.assertEqual(str(ex1), str(ex2)) + def makeCallable(self, signature): + """Create a function that returns its locals(), excluding the + autogenerated '.1', '.2', etc. tuple param names (if any).""" + with check_py3k_warnings( + ("tuple parameter unpacking has been removed", SyntaxWarning), + quiet=True): + code = ("lambda %s: dict(i for i in locals().items() " + "if not is_tuplename(i[0]))") + return eval(code % signature, {'is_tuplename' : self.is_tuplename}) - class C(A): + def test_plain(self): + f = self.makeCallable('a, b=1') + self.assertEqualCallArgs(f, '2') + self.assertEqualCallArgs(f, '2, 3') + self.assertEqualCallArgs(f, 'a=2') + self.assertEqualCallArgs(f, 'b=3, a=2') + self.assertEqualCallArgs(f, '2, b=3') + # expand *iterable / **mapping + self.assertEqualCallArgs(f, '*(2,)') + self.assertEqualCallArgs(f, '*[2]') + self.assertEqualCallArgs(f, '*(2, 3)') + self.assertEqualCallArgs(f, '*[2, 3]') + self.assertEqualCallArgs(f, '**{"a":2}') + self.assertEqualCallArgs(f, 'b=3, **{"a":2}') + self.assertEqualCallArgs(f, '2, **{"b":3}') + self.assertEqualCallArgs(f, '**{"b":3, "a":2}') + # expand UserList / UserDict + self.assertEqualCallArgs(f, '*UserList([2])') + self.assertEqualCallArgs(f, '*UserList([2, 3])') + self.assertEqualCallArgs(f, '**UserDict(a=2)') + self.assertEqualCallArgs(f, '2, **UserDict(b=3)') + self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3)') + # unicode keyword args + self.assertEqualCallArgs(f, '**{u"a":2}') + self.assertEqualCallArgs(f, 'b=3, **{u"a":2}') + self.assertEqualCallArgs(f, '2, **{u"b":3}') + self.assertEqualCallArgs(f, '**{u"b":3, u"a":2}') - def m(self): pass - def c(self): pass + def test_varargs(self): + f = self.makeCallable('a, b=1, *c') + self.assertEqualCallArgs(f, '2') + self.assertEqualCallArgs(f, '2, 3') + self.assertEqualCallArgs(f, '2, 3, 4') + self.assertEqualCallArgs(f, '*(2,3,4)') + self.assertEqualCallArgs(f, '2, *[3,4]') + self.assertEqualCallArgs(f, '2, 3, *UserList([4])') - attrs = attrs_wo_objs(C) - self.assert_(('s', 'static method', A) in attrs, 'missing static method') - self.assert_(('c', 'method', C) in attrs, 'missing plain method') - self.assert_(('p', 'property', A) in attrs, 'missing property') - self.assert_(('m', 'method', C) in attrs, 'missing plain method') - self.assert_(('m1', 'method', A) in attrs, 'missing plain method') - self.assert_(('datablob', 'data', A) in attrs, 'missing data') + def test_varkw(self): + f = self.makeCallable('a, b=1, **c') + self.assertEqualCallArgs(f, 'a=2') + self.assertEqualCallArgs(f, '2, b=3, c=4') + self.assertEqualCallArgs(f, 'b=3, a=2, c=4') + self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}') + self.assertEqualCallArgs(f, '2, c=4, **{"b":3}') + self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}') + self.assertEqualCallArgs(f, '**UserDict(a=2, b=3, c=4)') + self.assertEqualCallArgs(f, '2, c=4, **UserDict(b=3)') + self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3, c=4)') + # unicode keyword args + self.assertEqualCallArgs(f, 'c=4, **{u"a":2, u"b":3}') + self.assertEqualCallArgs(f, '2, c=4, **{u"b":3}') + self.assertEqualCallArgs(f, 'b=2, **{u"a":3, u"c":4}') - class D(B, C): + def test_varkw_only(self): + # issue11256: + f = self.makeCallable('**c') + self.assertEqualCallArgs(f, '') + self.assertEqualCallArgs(f, 'a=1') + self.assertEqualCallArgs(f, 'a=1, b=2') + self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}') + self.assertEqualCallArgs(f, '**UserDict(a=1, b=2)') + self.assertEqualCallArgs(f, 'c=3, **UserDict(a=1, b=2)') - def m1(self): pass + def test_tupleargs(self): + f = self.makeCallable('(b,c), (d,(e,f))=(0,[1,2])') + self.assertEqualCallArgs(f, '(2,3)') + self.assertEqualCallArgs(f, '[2,3]') + self.assertEqualCallArgs(f, 'UserList([2,3])') + self.assertEqualCallArgs(f, '(2,3), (4,(5,6))') + self.assertEqualCallArgs(f, '(2,3), (4,[5,6])') + self.assertEqualCallArgs(f, '(2,3), [4,UserList([5,6])]') - attrs = attrs_wo_objs(D) - self.assert_(('s', 'static method', A) in attrs, 'missing static method') - self.assert_(('c', 'method', C) in attrs, 'missing plain method') - self.assert_(('p', 'property', A) in attrs, 'missing property') - self.assert_(('m', 'method', B) in attrs, 'missing plain method') - self.assert_(('m1', 'method', D) in attrs, 'missing plain method') - self.assert_(('datablob', 'data', A) in attrs, 'missing data') + def test_multiple_features(self): + f = self.makeCallable('a, b=2, (c,(d,e))=(3,[4,5]), *f, **g') + self.assertEqualCallArgs(f, '2, 3, (4,[5,6]), 7') + self.assertEqualCallArgs(f, '2, 3, *[(4,[5,6]), 7], x=8') + self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]') + self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9') + self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9') + self.assertEqualCallArgs(f, 'x=8, *UserList([2, 3, (4,[5,6])]), ' + '**{"y":9, "z":10}') + self.assertEqualCallArgs(f, '2, x=8, *UserList([3, (4,[5,6])]), ' + '**UserDict(y=9, z=10)') + + def test_errors(self): + f0 = self.makeCallable('') + f1 = self.makeCallable('a, b') + f2 = self.makeCallable('a, b=1') + # f0 takes no arguments + self.assertEqualException(f0, '1') + self.assertEqualException(f0, 'x=1') + self.assertEqualException(f0, '1,x=1') + # f1 takes exactly 2 arguments + self.assertEqualException(f1, '') + self.assertEqualException(f1, '1') + self.assertEqualException(f1, 'a=2') + self.assertEqualException(f1, 'b=3') + # f2 takes at least 1 argument + self.assertEqualException(f2, '') + self.assertEqualException(f2, 'b=3') + for f in f1, f2: + # f1/f2 takes exactly/at most 2 arguments + self.assertEqualException(f, '2, 3, 4') + self.assertEqualException(f, '1, 2, 3, a=1') + self.assertEqualException(f, '2, 3, 4, c=5') + self.assertEqualException(f, '2, 3, 4, a=1, c=5') + # f got an unexpected keyword argument + self.assertEqualException(f, 'c=2') + self.assertEqualException(f, '2, c=3') + self.assertEqualException(f, '2, 3, c=4') + self.assertEqualException(f, '2, c=4, b=3') + self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}') + # f got multiple values for keyword argument + self.assertEqualException(f, '1, a=2') + self.assertEqualException(f, '1, **{"a":2}') + self.assertEqualException(f, '1, 2, b=3') + # XXX: Python inconsistency + # - for functions and bound methods: unexpected keyword 'c' + # - for unbound methods: multiple values for keyword 'a' + #self.assertEqualException(f, '1, c=3, a=2') + f = self.makeCallable('(a,b)=(0,1)') + self.assertEqualException(f, '1') + self.assertEqualException(f, '[1]') + self.assertEqualException(f, '(1,2,3)') + # issue11256: + f3 = self.makeCallable('**c') + self.assertEqualException(f3, '1, 2') + self.assertEqualException(f3, '1, 2, a=1, b=2') + +class TestGetcallargsMethods(TestGetcallargsFunctions): + + def setUp(self): + class Foo(object): + pass + self.cls = Foo + self.inst = Foo() + + def makeCallable(self, signature): + assert 'self' not in signature + mk = super(TestGetcallargsMethods, self).makeCallable + self.cls.method = mk('self, ' + signature) + return self.inst.method + +class TestGetcallargsUnboundMethods(TestGetcallargsMethods): + + def makeCallable(self, signature): + super(TestGetcallargsUnboundMethods, self).makeCallable(signature) + return self.cls.method + + def assertEqualCallArgs(self, func, call_params_string, locs=None): + return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs( + *self._getAssertEqualParams(func, call_params_string, locs)) + + def assertEqualException(self, func, call_params_string, locs=None): + return super(TestGetcallargsUnboundMethods, self).assertEqualException( + *self._getAssertEqualParams(func, call_params_string, locs)) + + def _getAssertEqualParams(self, func, call_params_string, locs=None): + assert 'inst' not in call_params_string + locs = dict(locs or {}, inst=self.inst) + return (func, 'inst,' + call_params_string, locs) def test_main(): - run_unittest(TestDecorators, TestRetrievingSourceCode, TestOneliners, - TestBuggyCases, - TestInterpreterStack, TestClassesAndFunctions, TestPredicates) + run_unittest( + TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases, + TestInterpreterStack, TestClassesAndFunctions, TestPredicates, + TestGetcallargsFunctions, TestGetcallargsMethods, + TestGetcallargsUnboundMethods) if __name__ == "__main__": test_main() -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sun Sep 14 05:37:09 2014 From: jython-checkins at python.org (jim.baker) Date: Sun, 14 Sep 2014 03:37:09 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fixed_ABC_support=2C_includ?= =?utf-8?q?ing_for_Java_interfaces=2E?= Message-ID: <20140914033708.117589.69134@mail.hg.python.org> http://hg.python.org/jython/rev/5d0fd036d08b changeset: 7374:5d0fd036d08b user: Jim Baker date: Sat Sep 13 21:35:36 2014 -0600 summary: Fixed ABC support, including for Java interfaces. No longer skips some collection tests, in part by ensuring dict, list, set are not Hashable by having __hash__ set to None. java.util.{Map, List, Set} are now treated as subclasses of the corresponding Python abstract base classes. files: Lib/_abcoll.py | 17 +- Lib/test/test_collections.py | 6 +- Lib/test/test_collections_jy.py | 125 ++++++++++++++ src/org/python/core/PyDictionary.java | 5 + src/org/python/core/PyList.java | 16 +- src/org/python/core/PySet.java | 4 + 6 files changed, 162 insertions(+), 11 deletions(-) diff --git a/Lib/_abcoll.py b/Lib/_abcoll.py --- a/Lib/_abcoll.py +++ b/Lib/_abcoll.py @@ -19,6 +19,8 @@ "Sequence", "MutableSequence", ] +_is_jython = sys.platform.startswith("java") + ### ONE-TRICK PONIES ### def _hasattr(C, attr): @@ -82,7 +84,7 @@ @classmethod def __subclasshook__(cls, C): if cls is Iterator: - if _hasattr(C, "next"): + if _hasattr(C, "next") and _hasattr(C, "__iter__"): return True return NotImplemented @@ -556,8 +558,7 @@ Sequence.register(tuple) Sequence.register(basestring) -if sys.platform[:4] != "java": - Sequence.register(buffer) +Sequence.register(buffer) Sequence.register(xrange) @@ -600,3 +601,13 @@ return self MutableSequence.register(list) + +if _is_jython: + from org.python.core import PyFastSequenceIter + import java + + MutableSequence.register(java.util.List) + MutableMapping.register(java.util.Map) + MutableSet.register(java.util.Set) + Iterator.register(PyFastSequenceIter) + diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -295,10 +295,8 @@ # Check some non-hashables non_samples = [list(), set(), dict()] for x in non_samples: - #FIXME: we need to get __hash__ to be None in non_samples for Jython. - pass - #self.assertNotIsInstance(x, Hashable) - #self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) + self.assertNotIsInstance(x, Hashable) + self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) # Check some hashables samples = [None, int(), float(), complex(), diff --git a/Lib/test/test_collections_jy.py b/Lib/test/test_collections_jy.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_collections_jy.py @@ -0,0 +1,125 @@ +from test import test_support +from test.test_collections import ABCTestCase +from collections import ( + Hashable, Iterable, Iterator, + Sized, Container, Callable, + Set, MutableSet, + Mapping, MutableMapping, + Sequence, MutableSequence) +import sys + +import java + + +class TestJavaInterfaces(ABCTestCase): + + def test_Iterable(self): + # Check some non-iterables + non_samples = [ + java.lang.Integer(42), + java.lang.Long(sys.maxint+1)] + for x in non_samples: + self.assertNotIsInstance(x, Iterable) + self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) + # Check some iterables + samples = [ + java.util.HashMap(), + java.util.ArrayList(), + java.util.LinkedList(), + java.util.HashMap().keys(), + java.util.HashMap().items(), + java.util.HashMap().values()] + for x in samples: + self.assertIsInstance(x, Iterable) + self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) + + def test_Container(self): + # Check some objects that are not containers + non_samples = [ + java.lang.String(), + java.lang.Integer(42), + java.lang.Long(sys.maxint+1)] + for x in non_samples: + self.assertNotIsInstance(x, Container) + self.assertFalse(issubclass(type(x), Container), repr(type(x))) + # Check some containers + samples = [ + java.util.HashMap(), + java.util.ArrayList(), + java.util.LinkedList(), + java.util.HashMap().keys(), + java.util.HashMap().items(), + java.util.HashMap().values()] + for x in samples: + self.assertIsInstance(x, Container) + self.assertTrue(issubclass(type(x), Container), repr(type(x))) + + def test_MutableMapping(self): + # Check some objects that do not support MutableMapping + non_samples = [ + java.util.ArrayList(), + java.util.HashMap().keys(), + java.util.HashSet(), + java.util.LinkedList(), + java.util.TreeSet(), + ] + for x in non_samples: + self.assertNotIsInstance(x, MutableMapping) + self.assertFalse(issubclass(type(x), MutableMapping), repr(type(x))) + # Check some mappables + samples = [ + java.util.HashMap(), + java.util.concurrent.ConcurrentSkipListMap(), + ] + for x in samples: + self.assertIsInstance(x, MutableMapping) + self.assertTrue(issubclass(type(x), MutableMapping), repr(type(x))) + + def test_MutableSequence(self): + # Check some objects that do not support MutableSequence + non_samples = [ + java.util.HashMap(), + java.util.HashSet(), + java.util.TreeSet(), + java.util.concurrent.ConcurrentSkipListMap(), + ] + for x in non_samples: + self.assertNotIsInstance(x, MutableSequence) + self.assertFalse(issubclass(type(x), MutableSequence), repr(type(x))) + # Check some mappables + samples = [ + java.util.ArrayList(), + java.util.LinkedList(), + java.util.HashMap().keys(), + ] + for x in samples: + self.assertIsInstance(x, MutableSequence) + self.assertTrue(issubclass(type(x), MutableSequence), repr(type(x))) + + def test_MutableSet(self): + # Check some objects that are not sets + non_samples = [ + java.util.ArrayList(), + java.util.LinkedList(), + java.util.HashMap(), + java.util.concurrent.ConcurrentSkipListMap(), + ] + for x in non_samples: + self.assertNotIsInstance(x, MutableSet) + self.assertFalse(issubclass(type(x), MutableSet), repr(type(x))) + # Check some sets + samples = [ + java.util.HashSet(), + java.util.TreeSet(), + ] + for x in samples: + self.assertIsInstance(x, MutableSet) + self.assertTrue(issubclass(type(x), MutableSet), repr(type(x))) + + +def test_main(): + test_classes = [TestJavaInterfaces] + test_support.run_unittest(*test_classes) + +if __name__ == "__main__": + test_main() diff --git a/src/org/python/core/PyDictionary.java b/src/org/python/core/PyDictionary.java --- a/src/org/python/core/PyDictionary.java +++ b/src/org/python/core/PyDictionary.java @@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.python.expose.ExposedClassMethod; +import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; @@ -31,6 +32,10 @@ public class PyDictionary extends PyObject implements ConcurrentMap { public static final PyType TYPE = PyType.fromClass(PyDictionary.class); + { + // Ensure dict is not Hashable + TYPE.object___setattr__("__hash__", Py.None); + } private final ConcurrentMap internalMap; diff --git a/src/org/python/core/PyList.java b/src/org/python/core/PyList.java --- a/src/org/python/core/PyList.java +++ b/src/org/python/core/PyList.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.Arrays; + +import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; @@ -23,6 +25,11 @@ public class PyList extends PySequenceList implements List { public static final PyType TYPE = PyType.fromClass(PyList.class); + { + // Ensure list is not Hashable + TYPE.object___setattr__("__hash__", Py.None); + } + private final List list; public volatile int gListAllocatedStatus = -1; @@ -918,12 +925,13 @@ } public int hashCode() { - return list___hash__(); + throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName())); } - @ExposedMethod(doc = BuiltinDocs.list___hash___doc) - final synchronized int list___hash__() { - throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName())); + //@ExposedMethod(doc = BuiltinDocs.list___hash___doc) + @ExposedGet(name = "__hash__") + public PyObject list___hash__() { + return Py.None; } @Override diff --git a/src/org/python/core/PySet.java b/src/org/python/core/PySet.java --- a/src/org/python/core/PySet.java +++ b/src/org/python/core/PySet.java @@ -13,6 +13,10 @@ public class PySet extends BaseSet { public static final PyType TYPE = PyType.fromClass(PySet.class); + { + // Ensure set is not Hashable + TYPE.object___setattr__("__hash__", Py.None); + } public PySet() { this(TYPE); -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sun Sep 14 05:41:35 2014 From: jython-checkins at python.org (jim.baker) Date: Sun, 14 Sep 2014 03:41:35 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Restore_list=5F=5F=5Fhash?= =?utf-8?q?=5F=5F_impl_prior_to_last_commit?= Message-ID: <20140914034134.116487.75694@mail.hg.python.org> http://hg.python.org/jython/rev/4ed83fcdb13e changeset: 7375:4ed83fcdb13e user: Jim Baker date: Sat Sep 13 21:41:30 2014 -0600 summary: Restore list___hash__ impl prior to last commit files: src/org/python/core/PyList.java | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/org/python/core/PyList.java b/src/org/python/core/PyList.java --- a/src/org/python/core/PyList.java +++ b/src/org/python/core/PyList.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.Arrays; -import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; @@ -925,13 +924,12 @@ } public int hashCode() { - throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName())); + return list___hash__(); } - //@ExposedMethod(doc = BuiltinDocs.list___hash___doc) - @ExposedGet(name = "__hash__") - public PyObject list___hash__() { - return Py.None; + @ExposedMethod(doc = BuiltinDocs.list___hash___doc) + final synchronized int list___hash__() { + throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName())); } @Override -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:23 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:23 +0000 Subject: [Jython-checkins] =?utf-8?b?anl0aG9uOiBieXRlYXJyYXkuX19pbXVsX18g?= =?utf-8?q?now_raises_BufferError_when_buffers_are_being_exported=2E?= Message-ID: <20140916225523.109582.34929@mail.hg.python.org> http://hg.python.org/jython/rev/1a8a3a625af7 changeset: 7376:1a8a3a625af7 parent: 7349:f52f81d83a74 user: Jeff Allen date: Wed Jul 30 11:51:19 2014 +0100 summary: bytearray.__imul__ now raises BufferError when buffers are being exported. This corrects a bug (not logged on the tracker) that allowed b *= n to proceed while exporting a buffer. files: Lib/test/test_bytes_jy.py | 44 +++++++++++++++- src/org/python/core/PyByteArray.java | 30 ++++++++++- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_bytes_jy.py b/Lib/test/test_bytes_jy.py --- a/Lib/test/test_bytes_jy.py +++ b/Lib/test/test_bytes_jy.py @@ -12,11 +12,51 @@ class Sub(bytearray): pass s = Sub("abc123") self.assertEqual(len(s), 6) - + + +class SimpleOperationsTest(unittest.TestCase): + # Things the CPython library did not test throughly enough + + def test_irepeat(self) : + + def check_irepeat(a, n) : + # Check in-place multiplication (repeats) + b = bytearray(a) + b *= n + self.assertEquals(b, bytearray(a*n)) + + def irepeat_export(a, n) : + # In-place multiplication with export mostly raises BufferError + b = bytearray(a) + with memoryview(b) as m: + b *= n + # If it doesn't raise, it gets the right answer + self.assertEquals(b, bytearray(a*n)) + + for a in [b'', b'a', b'hello'] : + check_irepeat(a, 7) + check_irepeat(a, 1) + check_irepeat(a, 0) + check_irepeat(a, -1) # -ve treated as 0 + + # Resizing with exports should raise an exception + self.assertRaises(BufferError, irepeat_export, b'a', 5) + self.assertRaises(BufferError, irepeat_export, b'hello', 3) + self.assertRaises(BufferError, irepeat_export, b'hello', 0) + self.assertRaises(BufferError, irepeat_export, b'hello', -1) + + # These don't raise an exception (CPython 2.7.6, 3.4.1) + irepeat_export(b'a', 1) + irepeat_export(b'hello', 1) + for n in range(-1, 3) : + irepeat_export(b'', n) + def test_main(): test.test_support.run_unittest( - ByteArraySubclassTest) + ByteArraySubclassTest, + SimpleOperationsTest, + ) if __name__ == "__main__": diff --git a/src/org/python/core/PyByteArray.java b/src/org/python/core/PyByteArray.java --- a/src/org/python/core/PyByteArray.java +++ b/src/org/python/core/PyByteArray.java @@ -352,7 +352,33 @@ * @param count the number of times to repeat this. */ protected synchronized void irepeat(int count) { - this.setStorage(repeatImpl(count)); + // There are several special cases + if (size == 0 || count == 1) { + // No resize, so no check (consistent with CPython) + // Value is unchanged. + + } else if (count <= 0) { + // Treat as if count == 0. + resizeCheck(); + this.setStorage(emptyStorage); + + } else { + // Open up space (remembering the original size) + int orginalSize = size; + storageExtend(orginalSize * (count - 1)); + if (orginalSize == 1) { + // Do it efficiently for single bytes + byte b = storage[offset]; + for (int i = 1, p = offset + 1; i < count; i++) { + storage[p++] = b; + } + } else { + // General case + for (int i = 1, p = offset + orginalSize; i < count; i++, p += orginalSize) { + System.arraycopy(storage, offset, storage, p, orginalSize); + } + } + } } /** @@ -924,7 +950,7 @@ return bytearray___imul__(n); } - @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.bytearray___mul___doc) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.bytearray___imul___doc) final PyObject bytearray___imul__(PyObject n) { if (!n.isIndex()) { return null; -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:24 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:24 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fix_typos_in_the_buffer_API?= =?utf-8?q?_docs=2E?= Message-ID: <20140916225524.59203.68606@mail.hg.python.org> http://hg.python.org/jython/rev/b7c5602a6f14 changeset: 7378:b7c5602a6f14 user: Jeff Allen date: Fri Aug 08 21:56:26 2014 +0100 summary: Fix typos in the buffer API docs. files: src/org/python/core/PyBUF.java | 4 ++-- src/org/python/core/PyBuffer.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/org/python/core/PyBUF.java b/src/org/python/core/PyBUF.java --- a/src/org/python/core/PyBUF.java +++ b/src/org/python/core/PyBUF.java @@ -218,8 +218,8 @@ /** * A constant used by the consumer in its call to {@link BufferProtocol#getBuffer(int)} to * specify that it expects to access the buffer contents directly as an array (rather than - * through that the purely abstract part of the API). getBuffer will raise an - * exception if the exporter cannot expose its storage as Java array. + * through the purely abstract part of the API). getBuffer will raise an exception + * if the exporter cannot expose its storage as Java array. */ static final int AS_ARRAY = 0x10000000; diff --git a/src/org/python/core/PyBuffer.java b/src/org/python/core/PyBuffer.java --- a/src/org/python/core/PyBuffer.java +++ b/src/org/python/core/PyBuffer.java @@ -273,11 +273,11 @@ // /** - * Determine whether the exporter is able to offer direct access the exported storage as a Java - * byte array (through the API that involves class {@link Pointer}), or only supports the + * Determine whether the exporter is able to offer direct access to the exported storage as a + * Java byte array (through the API that involves class {@link Pointer}), or only supports the * abstract API. See also {@link PyBUF#AS_ARRAY}. * - * @return true if array access is not allowed, false if it is. + * @return true if array access is supported, false if it is not. */ boolean hasArray(); -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:24 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:24 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Regression_and_speed_tests_?= =?utf-8?q?preparatory_to_work_on_PyUnicode_indexing=2E?= Message-ID: <20140916225524.35474.26493@mail.hg.python.org> http://hg.python.org/jython/rev/aed06364c44d changeset: 7379:aed06364c44d user: Jeff Allen date: Sat Aug 16 22:40:18 2014 +0100 summary: Regression and speed tests preparatory to work on PyUnicode indexing. Includes a failing test for unicode.find() and .rfind(), and a complicated benchmark for performance of indexing, slice and (r)find (compatible with CPython 2.7 and 3.4). files: Lib/test/test_unicode_jy.py | 211 +++++++++ tests/python/unicode_index_times.py | 368 ++++++++++++++++ 2 files changed, 579 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_unicode_jy.py b/Lib/test/test_unicode_jy.py --- a/Lib/test/test_unicode_jy.py +++ b/Lib/test/test_unicode_jy.py @@ -3,6 +3,8 @@ Made for Jython. """ +import itertools +import random import re import string import sys @@ -150,6 +152,214 @@ u'f') +class UnicodeMaterial(object): + ''' Object holding a list of single characters and a unicode string + that is their concatenation. The sequence is created from a + background sequence of basic plane characters and random + replacement with supplementary plane characters (those with + point code>0xffff). + ''' + + base = tuple(u'abcdefghijklmnopqrstuvwxyz') + supp = tuple(map(unichr, range(0x10000, 0x1000c))) + used = sorted(set(base+supp)) + + def __init__(self, size=20, pred=None, ran=None): + ''' Create size chars choosing an SP char at i where + pred(ran, i)==True where ran is an instance of + random.Random supplied in the constructor or created + locally (if ran==None). + ''' + + # Generators for the BMP and SP characters + base = itertools.cycle(UnicodeMaterial.base) + supp = itertools.cycle(UnicodeMaterial.supp) + + # Each instance gets a random generator + if ran is None: + ran = random.Random() + self.random = ran + + if pred is None: + pred = lambda ran, j : ran.random() < DEFAULT_RATE + + # Generate the list + r = list() + for i in range(size): + if pred(self.random, i): + c = supp.next() + else: + c = base.next() + r.append(c) + + # The list and its concatenation are our material + self.ref = r + self.size = len(r) + self.text = u''.join(r) + self.target = u'' + + def __len__(self): + return self.size + + def insert(self, target, p=None): + ''' Insert target string at position p (or middle), truncating if + that would make the material any longer + ''' + if p is None: + p = max(0, (self.size-len(target)) // 2) + + n = 0 + for t in target: + if p+n >= self.size: + break; + self.ref[p+n] = t + n += 1 + + self.target = target[:n] + self.text = u''.join(self.ref) + + +class UnicodeIndexMixTest(unittest.TestCase): + # Test indexing where there may be more than one code unit per code point. + # See Jython Issue #2100. + + # Functions defining particular distributions of SP codes + # + def evenly(self, rate=0.2): + 'Evenly distributed at given rate' + def f(ran, i): + return ran.random() < rate + return f + + def evenly_before(self, k, rate=0.2): + 'Evenly distributed on i=k at given rate' + def f(ran, i): + return i >= k and ran.random() < rate + return f + + def at(self, places): + 'Only at specified places' + def f(ran, i): + return i in places + return f + + def setUp(self): + ran = random.Random(1234) # ensure repeatable + mat = list() + mat.append(UnicodeMaterial(10, self.at([2]), ran)) + mat.append(UnicodeMaterial(10, self.at([2, 5]), ran)) + mat.append(UnicodeMaterial(50, self.evenly(), ran)) + mat.append(UnicodeMaterial(200, self.evenly_before(70), ran)) + mat.append(UnicodeMaterial(200, self.evenly_from(130), ran)) + mat.append(UnicodeMaterial(1000, self.evenly(), ran)) + + self.material = mat + + + def test_getitem(self): + # Test map from to code point index to internal representation + # Fails in Jython 2.7b3 + + def check_getitem(m): + # Check indexing the string returns the expected point code + for i in xrange(m.size): + self.assertEqual(m.text[i], m.ref[i]) + + for m in self.material: + check_getitem(m) + + def test_slice(self): + # Test indexing gets the slice ends correct. + # Passes in Jython 2.7b3, but may be touched by #2100 changes. + + def check_slice(m): + # Check a range of slices against slices of the reference. + n = 1 + while n <= m.size: + for i in range(m.size - n): + exp = u''.join(m.ref[i:i+n]) + self.assertEqual(m.text[i:i+n], exp) + n *= 3 + + for m in self.material: + check_slice(m) + + @unittest.skip("Fails on Jython 2.7b3 issue #2100") + def test_find(self): + # Test map from internal find result to code point index + # Fails in Jython 2.7b3 + + def check_find(ref): + # Check find returns indexes for single point codes + for c in set(m.used): + start = 0 + u = m.text + while start < m.size: + i = u.find(c, start) + if i < 0: break + self.assertEqual(u[i], c) + start = i + 1 + + def check_find_str(m, t): + # Check find returns correct index for string target + i = m.text.find(t) + self.assertEqual(list(t), m.ref[i:i+len(t)]) + + targets = [ + u"this", + u"ab\U00010041de", + u"\U00010041\U00010042\U00010042xx", + u"xx\U00010041\U00010042\U00010043yy", + ] + + for m in self.material: + check_find(m) + for t in targets: + # Insert in middle then try to find it + m.insert(t) + check_find_str(m, t) + + @unittest.skip("Fails on Jython 2.7b3 issue #2100") + def test_rfind(self): + # Test map from internal rfind result to code point index + # Fails in Jython 2.7b3 + + def check_rfind(ref): + # Check rfind returns indexes for single point codes + for c in set(m.used): + end = m.size + u = m.text + while True: + end = u.rfind(c, 0, end) + if end < 0: break + self.assertEqual(u[end], c) + + def check_rfind_str(m, t): + # Check rfind returns correct index for string target + i = m.text.rfind(t) + self.assertEqual(list(t), m.ref[i:i+len(t)]) + + targets = [ + u"this", + u"ab\U00010041de", + u"\U00010041\U00010042\U00010042xx", + u"xx\U00010041\U00010042\U00010043yy", + ] + + for m in self.material: + check_rfind(m) + for t in targets: + # Insert in middle then try to find it + m.insert(t) + check_rfind_str(m, t) + + class UnicodeFormatTestCase(unittest.TestCase): def test_unicode_mapping(self): @@ -596,6 +806,7 @@ def test_main(): test_support.run_unittest( UnicodeTestCase, + UnicodeIndexMixTest, UnicodeFormatTestCase, UnicodeStdIOTestCase, UnicodeFormatStrTest, diff --git a/tests/python/unicode_index_times.py b/tests/python/unicode_index_times.py new file mode 100644 --- /dev/null +++ b/tests/python/unicode_index_times.py @@ -0,0 +1,368 @@ +# -*- coding: utf-8 -*- +# unicode speed tests for access operations and find +# This is part of an effort to supply the Jython implementation of +# unicode with efficient, correct translations between the visible index +# of a character and and the index in the implementation array of the +# UTF-16 code unit(s) that represent it. See also test.test_unicode_jy, +# and Jython issue #2100. The presence of characters with Unicode +# code points > 0xffff (supplementary characters), that it takes two +# code units to represent, makes this non-trivial. +# +# The program defines a variety of test strings of differing lengths +# and distribution of supplementary characters, then times some basic +# operations involving index translation: of retrieval, slicing and +# find, to provide an average time per operation. It runs several trials +# of each test case (a combination of an operation and the test material) +# and reports the shortest trial, using the same strategy as the timeit +# module). +# +# It was difficult to get repeatable times from the test under Jython, +# because the JIT compiler (?) is non-deterministic. It proved +# impossible using a strategy that would run the same test case multiple +# times in succession. The approach eventually taken was to run the all +# the test cases once, then repeat this sequence several times, and +# report the minimum time of each case in these widely separated trials. +# This strategy provides stable results with the default JIT behaviour. +# +# Two interesting options are to run with the # JIT compiler disabled: +# $ jython -J-Xint tests/python/unicode_index_times.py +# +# or with it continuously enabled: +# $ jython -J-Xcomp tests/python/unicode_index_times.py +# +from __future__ import print_function +import itertools +import random +import sys +import time + +if sys.platform == "win32" or sys.platform.startswith("java"): + # On Windows and Jython, the best timer is time.clock() + timer = time.clock +else: + # On most other platforms the best timer is time.time() + timer = time.time + +if sys.version_info[0] > 2: + unichr = chr +else: + def next(it) : return it.next() + +# Proportion of characters that are supplementary (if not explicit) +DEFAULT_RATE = 0.2 # 20% + +# We will test performance with these sizes +SHORT = 10 +MEDIUM = 100 +LONG = 1000 +HUGE = 10000 + + +class UnicodeMaterial(object): + ''' Object holding a list of single characters and a unicode string + that is their concatenation. The sequence is created from a + background sequence of basic plane characters and random + replacement with supplementary plane characters (those with + point code>0xffff). + ''' + + base = tuple(u'abcdefghijklmnopqrstuvwxyz') + if sys.maxunicode < 0x10000: + print("Narrow build: all characters from BMP", file=sys.stderr) + supp = tuple(map(unichr, range(0x20, 0x2c))) + else: + # Wide build: we have real supplementary characters + supp = tuple(map(unichr, range(0x10000, 0x1000c))) + used = sorted(set(base+supp)) + + def __init__(self, size=20, pred=None, ran=None): + ''' Create size chars choosing an SP char at i where + pred(ran, i)==True where ran is an instance of + random.Random supplied in the constructor or created + locally (if ran==None). + ''' + + # Generators for the BMP and SP characters + base = itertools.cycle(UnicodeMaterial.base) + supp = itertools.cycle(UnicodeMaterial.supp) + + # Each instance gets a random generator + if ran is None: + ran = random.Random() + self.random = ran + + if pred is None: + pred = lambda ran, j : ran.random() < DEFAULT_RATE + + # Generate the list + r = list() + for i in range(size): + if pred(self.random, i): + c = next(supp) + else: + c = next(base) + r.append(c) + + # The list and its concatenation are our material + self.ref = r + self.size = len(r) + self.text = u''.join(r) + self.target = u'' + + def __len__(self): + return self.size + + def insert(self, target, p=None): + ''' Insert target string at position p (or middle), truncating if + that would make the material any longer + ''' + if p is None: + p = max(0, (self.size-len(target)) // 2) + + n = 0 + for t in target: + if p+n >= self.size: + break; + self.ref[p+n] = t + n += 1 + + self.target = target[:n] + self.text = u''.join(self.ref) + + +class UnicodeActions(UnicodeMaterial): + ''' Provides test material with loops for timing.''' + + def __init__(self, size=20, pred=None, ran=None): + super(UnicodeActions, self).__init__(size, pred, ran) + if self.size <= 0: + raise ValueError("The timings don't work for zero length") + self.used = UnicodeMaterial.used + self.trash = None + # String to find (note 'abcde' in base: nice for false alarms) + self.insert(u"abide") + + + def repeat_getitem(self, mincount): + ''' Access each code point in sequence repeatedly so that at + least mincount operations have been peformed, and return the + actual number of operations. + ''' + n = self.size + t = self.text + opcount = 0 + dummy = None + while opcount < mincount: + # Access each point code + i = 0 + while i < n: + # Avoid optimising away the call + dummy = t[i] + i += 1 + opcount += n + self.trash = dummy + return opcount + + def repeat_slice(self, mincount): + ''' Extract a slice at each feasible position and length, + repeating enough times to do mincount operations, and + return the actual number of operations. + ''' + n = self.size + t = self.text + opcount = 0 + dummy = None + + while opcount < mincount: + m = 1 + while m <= n: + starts = n - m + 1 + for i in range(starts): + dummy = t[i:i+m] + opcount += starts + m *= 5 + + return opcount + + def repeat_find_char(self, mincount): + ''' Do an incremental find of each code point, repeating + enough times to do mincount finds, and return the actual + number of operations. + ''' + opcount = 0 + n = self.size + findop = self.text.find + dummy = 0 + + while opcount < mincount: + # The text is searched for every code c. + for c in self.used: + # ... and every occurrence is found. + start = 0 + while start < n: + i = findop(c, start) + if i < 0: break + # Avoid optimising away the call + dummy += i + start = i + 1 + + # Every character in the text was a hit exactly once. + # And every character was also a miss, except for + # the character that ends the text. So we did: + opcount += n + len(self.used) - 1 + + self.trash = dummy + return opcount + + def repeat_find_str(self, mincount): + ''' Find the target string within the material, repeating + enough times to do mincount finds, and return the actual + number of operations. + ''' + opcount = 0 + s = self.target + findop = self.text.find + dummy = 0 + + while opcount < mincount: + dummy += findop(s) + opcount += 1 + + self.trash = dummy + return opcount + + def repeat_rfind_char(self, mincount): + ''' Do an incremental rfind of each code point, repeating + enough times to do mincount finds, and return the actual + number of operations. + ''' + opcount = 0 + n = self.size + findop = self.text.rfind + + while opcount < mincount: + # The text is searched for every code c. + for c in self.used: + # ... and every occurrence is found. + end = n + while end >= 0: + end = findop(c, 0, end) + + # Every character in the text was a hit exactly once. + # And every character was also a miss. So we did: + opcount += n + len(self.used) + + return opcount + + def repeat_rfind_str(self, mincount): + ''' Find the target string within the material, repeating + enough times to do mincount finds, and return the actual + number of operations. + ''' + opcount = 0 + s = self.target + findop = self.text.rfind + dummy = 0 + + while opcount < mincount: + dummy += findop(s) + opcount += 1 + + self.trash = dummy + return opcount + + +def time_per_op(op, mincount): + ''' Repeat the given operation at least mincount times and + return the time per operation in microseconds. + ''' + t = timer() + opcount = op(mincount) + return (timer() - t) * 1e6 / opcount + +# Functions defining particular distributions of SP codes +# +def evenly(rate=DEFAULT_RATE): + 'Evenly distributed at given rate' + def f(ran, i): + return ran.random() < rate + return f + +def evenly_before(k, rate=DEFAULT_RATE): + 'Evenly distributed on i=k at given rate' + def f(ran, i): + return i >= k and ran.random() < rate + return f + +def time_all(): + + setups = [ + #("empty", UnicodeActions(0)), + ("single bmp", UnicodeActions(1, (lambda ran, i : False))), + ("single", UnicodeActions(1, (lambda ran, i : True))), + ("short bmp", UnicodeActions(SHORT, (lambda ran, i : False))), + ("short 50%", UnicodeActions(SHORT, evenly(0.5))), + ("medium bmp", UnicodeActions(MEDIUM, (lambda ran, i : False))), + ("medium 10%", UnicodeActions(MEDIUM, evenly(0.1))), + ("long bmp", UnicodeActions(LONG, (lambda ran, i : False))), + ("long 1%", UnicodeActions(LONG, evenly(0.01))), + ("long 10%", UnicodeActions(LONG, evenly(0.1))), + ("long 10% low", UnicodeActions(LONG, evenly_before(LONG/4, 0.4))), + ("long 10% high", UnicodeActions(LONG, evenly_from(LONG-(LONG/4), 0.4))), + ("long 50%", UnicodeActions(LONG, evenly(0.5))), + ("huge bmp", UnicodeActions(HUGE, (lambda ran, i : False))), + ("huge 10%", UnicodeActions(HUGE, evenly(0.1))), + ] + + ops = [ + ("[i]", "repeat_getitem"), + ("[i:i+n]", "repeat_slice"), + ("find(c)", "repeat_find_char"), + ("find(str)", "repeat_find_str"), + ("rfind(c)", "repeat_rfind_char"), + ("rfind(str)", "repeat_rfind_str"), + ] + + + print("{:15s}{:>6s}".format("time (us)", "len"), end='') + for title, _ in ops: + print("{:>12s}".format(title), end='') + print() + + mintime = dict() + def save_mintime(k, t): + mintime[k] = min(t, mintime.get(k, 1e9)) + + trashcan = [] + + # Cycle through the cases repeatedly. + for k in range(5): + for name, material in setups: + for _, opname in ops: + # For each case, keep the minimum time + op = material.__getattribute__(opname) + t = time_per_op(op, 1000) + save_mintime((name, opname), t) + + if k == 0: + trashcan.append(material.trash) + + # Cycle through the cases again to print them. + for name, material in setups: + print("{:15s}{:6d}".format(name, material.size), end='') + for _, opname in ops: + t = mintime[(name, opname)] + print("{:12.3f}".format(t), end='') + print() + + print("y =", trashcan) + +if __name__ == "__main__": + + time_all() -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:25 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:25 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Convert_PyUnicode=2Esubstri?= =?utf-8?q?ng_to_use_UTF-16_stranslated_indices=2E?= Message-ID: <20140916225525.87293.49623@mail.hg.python.org> http://hg.python.org/jython/rev/bb69cef6b56c changeset: 7383:bb69cef6b56c user: Jeff Allen date: Sun Sep 07 23:49:49 2014 +0100 summary: Convert PyUnicode.substring to use UTF-16 stranslated indices. files: src/org/python/core/PyString.java | 7 ++++++ src/org/python/core/PyUnicode.java | 19 +++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/org/python/core/PyString.java b/src/org/python/core/PyString.java --- a/src/org/python/core/PyString.java +++ b/src/org/python/core/PyString.java @@ -155,6 +155,13 @@ return pybuf; } + /** + * Return a substring of this object as a Java String. + * + * @param start the beginning index, inclusive. + * @param end the ending index, exclusive. + * @return the specified substring. + */ public String substring(int start, int end) { return getString().substring(start, end); } diff --git a/src/org/python/core/PyUnicode.java b/src/org/python/core/PyUnicode.java --- a/src/org/python/core/PyUnicode.java +++ b/src/org/python/core/PyUnicode.java @@ -238,15 +238,20 @@ // ------------------------------------------------------------------------------------------ - // modified to know something about codepoints; we just need to return the - // corresponding substring; darn UTF16! - // TODO: we could avoid doing this unnecessary copy + /** + * {@inheritDoc} + * The indices are code point indices, not UTF-16 (char) indices. For example: + * + *

    +     * PyUnicode u = new PyUnicode("..\ud800\udc02\ud800\udc03...");
    +     * // (Python) u = u'..\U00010002\U00010003...'
    +     *
    +     * String s = u.substring(2, 4);  // = "\ud800\udc02\ud800\udc03" (Java)
    +     * 
    + */ @Override public String substring(int start, int end) { - if (isBasicPlane()) { - return super.substring(start, end); - } - return new PyUnicode(newSubsequenceIterator(start, end, 1)).getString(); + return super.substring(translator.utf16Index(start), translator.utf16Index(end)); } /** -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:24 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:24 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Add_PyBuffer=2EgetNIOByteBu?= =?utf-8?q?ffer_to_the_buffer_protocol=2E?= Message-ID: <20140916225523.88226.8840@mail.hg.python.org> http://hg.python.org/jython/rev/330839dc597a changeset: 7377:330839dc597a user: Jeff Allen date: Tue Aug 05 23:13:02 2014 +0100 summary: Add PyBuffer.getNIOByteBuffer to the buffer protocol. This is a first implementation of using ByteBuffer in place of byte[] access to objects. Supporting classes now provide an implementation wrapping the array, and where possible, code in the core uses that instead of PyBuffer.Pointer. files: src/org/python/core/PyArray.java | 83 ++++++-- src/org/python/core/PyBUF.java | 10 + src/org/python/core/PyBuffer.java | 53 +++++- src/org/python/core/buffer/BaseBuffer.java | 86 +++++++++- src/org/python/core/buffer/SimpleBuffer.java | 9 + src/org/python/core/buffer/SimpleStringBuffer.java | 11 +- src/org/python/modules/_io/PyFileIO.java | 6 +- src/org/python/modules/posix/PosixModule.java | 9 +- 8 files changed, 220 insertions(+), 47 deletions(-) diff --git a/src/org/python/core/PyArray.java b/src/org/python/core/PyArray.java --- a/src/org/python/core/PyArray.java +++ b/src/org/python/core/PyArray.java @@ -1,7 +1,6 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -11,6 +10,7 @@ import java.io.OutputStream; import java.lang.ref.WeakReference; import java.lang.reflect.Array; +import java.nio.ByteBuffer; import org.python.core.buffer.BaseBuffer; import org.python.core.buffer.SimpleStringBuffer; @@ -1130,19 +1130,17 @@ frombytesInternal(StringUtil.toBytes(s)); } else { - // Access the bytes + // Access the bytes through the abstract API of the BufferProtocol try (PyBuffer pybuf = ((BufferProtocol)input).getBuffer(PyBUF.STRIDED_RO)) { - // Provide argument as stream of bytes for fromstream method if (pybuf.getNdim() == 1) { if (pybuf.getStrides()[0] == 1) { - // Data are contiguous in a byte[] - PyBuffer.Pointer b = pybuf.getBuf(); - frombytesInternal(b.storage, b.offset, pybuf.getLen()); + // Data are contiguous in the buffer + frombytesInternal(pybuf.getNIOByteBuffer()); } else { // As frombytesInternal only knows contiguous bytes, make a copy. byte[] copy = new byte[pybuf.getLen()]; pybuf.copyTo(copy, 0); - frombytesInternal(copy); + frombytesInternal(ByteBuffer.wrap(copy)); } } else { // Currently don't support n-dimensional sources @@ -1158,39 +1156,30 @@ } /** - * Common code supporting Java and Python versions of .fromstring() - * - * @param input string of bytes encoding the array data - */ - private final void fromstringInternal(String input) { - frombytesInternal(StringUtil.toBytes(input)); - } - - /** * Common code supporting Java and Python versions of .fromstring() or * .frombytes() (Python 3.2+ name). * * @param bytes array containing the new array data in machine encoding */ private final void frombytesInternal(byte[] bytes) { - frombytesInternal(bytes, 0, bytes.length); + frombytesInternal(ByteBuffer.wrap(bytes)); } /** - * Common code supporting Java and Python versions of .fromstring() or - * .frombytes() (Python 3.2+ name). + * Copy into this array, the remaining bytes of a ByteBuffer (from the current position to the + * limit). This is common code supporting Java and Python versions of .fromstring() + * or .frombytes() (Python 3.2+ name). * - * @param bytes array containing the new array data in machine encoding - * @param offset of the first byte to read - * @param count of bytes to read + * @param bytes buffer containing the new array data in machine encoding */ - private final void frombytesInternal(byte[] bytes, int offset, int count) { + private final void frombytesInternal(ByteBuffer bytes) { // Access the bytes int origsize = delegate.getSize(); // Check validity wrt array itemsize int itemsize = getStorageSize(); + int count = bytes.remaining(); if ((count % itemsize) != 0) { throw Py.ValueError("string length not a multiple of item size"); } @@ -1201,8 +1190,8 @@ try { // Provide argument as stream of bytes for fromstream method - ByteArrayInputStream bis = new ByteArrayInputStream(bytes, offset, count); - fromStream(bis); + InputStream is = new ByteBufferBackedInputStream(bytes); + fromStream(is); } catch (EOFException e) { // stubbed catch for fromStream throws @@ -2117,4 +2106,48 @@ } } + /** + * Wrap a ByteBuffer in an InputStream. Reference: + * Stackoverflow question 4332264. + */ + private class ByteBufferBackedInputStream extends InputStream { + + ByteBuffer buf; + + public ByteBufferBackedInputStream(ByteBuffer buf) { + this.buf = buf; + } + + /** + * Return the number of bytes remaining in the underlying buffer. + */ + @Override + public int available() throws IOException { + return buf.remaining(); + } + + + @Override + public int read() { + return buf.hasRemaining() ? buf.get() & 0xff : -1; + } + + @Override + public int read(byte[] bytes, int off, int len) { + int n = buf.remaining(); + if (n >= len) { + // There are enough bytes remaining to satisfy the request. + buf.get(bytes, off, len); + return len; + } else if (n > 0) { + // There are some bytes remaining: truncate request. + buf.get(bytes, off, n); + return n; + } else { + // Signal that there are no bytes left + return -1; + } + } + } } diff --git a/src/org/python/core/PyBUF.java b/src/org/python/core/PyBUF.java --- a/src/org/python/core/PyBUF.java +++ b/src/org/python/core/PyBUF.java @@ -213,6 +213,16 @@ */ static final int FULL_RO = INDIRECT | FORMAT; + /* Constants for additional feature(s), not standard for CPython */ + + /** + * A constant used by the consumer in its call to {@link BufferProtocol#getBuffer(int)} to + * specify that it expects to access the buffer contents directly as an array (rather than + * through that the purely abstract part of the API). getBuffer will raise an + * exception if the exporter cannot expose its storage as Java array. + */ + static final int AS_ARRAY = 0x10000000; + /* Constants for readability, not standard for CPython */ /** diff --git a/src/org/python/core/PyBuffer.java b/src/org/python/core/PyBuffer.java --- a/src/org/python/core/PyBuffer.java +++ b/src/org/python/core/PyBuffer.java @@ -1,5 +1,7 @@ package org.python.core; +import java.nio.ByteBuffer; + /** * The Jython buffer API for access to a byte array within an exporting object. This interface is * the counterpart of the CPython Py_buffer struct. Several concrete types implement @@ -237,10 +239,49 @@ */ public PyBuffer getBufferSlice(int flags, int start, int length, int stride); + // java.nio access to actual storage + // + + /** + * Obtain a {@link java.nio.ByteBuffer} giving access to the bytes that hold the data being + * exported to the consumer. For a one-dimensional contiguous buffer, assuming the following + * client code where obj has type BufferProtocol: + * + *
    +     * PyBuffer a = obj.getBuffer(PyBUF.SIMPLE);
    +     * int itemsize = a.getItemsize();
    +     * ByteBuffer bb = a.getNIOBuffer();
    +     * 
    + * + * the item with index bb.pos()+k is in the buffer bb at positions + * bb.pos()+k*itemsize to bb.pos()+(k+1)*itemsize - 1 inclusive. And + * if itemsize==1, the item is simply the byte at position bb.pos()+k. + * The buffer limit is set to the first byte beyond the valid data. A block read or write will + * therefore access the contents sequentially. + *

    + * If the buffer is multidimensional or non-contiguous (strided), the buffer position is still + * the (first byte of) the item at index [0] or [0,...,0], and the + * limit is one item beyond the valid data. However, it is necessary to navigate bb + * using the shape, strides and maybe suboffsets provided + * by the API. + * + * @return a ByteBuffer equivalent to the exported data contents. + */ + ByteBuffer getNIOByteBuffer(); + // Direct access to actual storage // /** + * Determine whether the exporter is able to offer direct access the exported storage as a Java + * byte array (through the API that involves class {@link Pointer}), or only supports the + * abstract API. See also {@link PyBUF#AS_ARRAY}. + * + * @return true if array access is not allowed, false if it is. + */ + boolean hasArray(); + + /** * A class that references a byte[] array and a particular offset within it, as the * return type for methods that give direct access to byte-oriented data exported by a Python * object. In some contexts the consumer will be entitled to make changes to the contents of @@ -270,11 +311,13 @@ * Return a structure describing the slice of a byte array that holds the data being exported to * the consumer. For a one-dimensional contiguous buffer, assuming the following client code * where obj has type BufferProtocol: + * *

    -     * PyBuffer a = obj.getBuffer();
    +     * PyBuffer a = obj.getBuffer(PyBUF.SIMPLE);
          * int itemsize = a.getItemsize();
          * PyBuffer.Pointer b = a.getBuf();
          * 
    + * * the item with index k is in the array b.storage at index * [b.offset + k*itemsize] to [b.offset + (k+1)*itemsize - 1] * inclusive. And if itemsize==1, the item is simply the byte @@ -293,12 +336,14 @@ * Return a structure describing the position in a byte array of a single item from the data * being exported to the consumer. For a one-dimensional contiguous buffer, assuming the * following client code where obj has type BufferProtocol: + * *
          * int k = ... ;
    -     * PyBuffer a = obj.getBuffer();
    +     * PyBuffer a = obj.getBuffer(PyBUF.FULL);
          * int itemsize = a.getItemsize();
          * PyBuffer.Pointer b = a.getPointer(k);
          * 
    + * * the item with index k is in the array b.storage at index * [b.offset] to [b.offset + itemsize - 1] inclusive. And if * itemsize==1, the item is simply the byte b.storage[b.offset] @@ -317,13 +362,15 @@ * being exported to the consumer, in the case that array may be multi-dimensional. For a * 3-dimensional contiguous buffer, assuming the following client code where obj * has type BufferProtocol: + * *
          * int i, j, k;
          * // ... calculation that assigns i, j, k
    -     * PyBuffer a = obj.getBuffer();
    +     * PyBuffer a = obj.getBuffer(PyBUF.FULL);
          * int itemsize = a.getItemsize();
          * PyBuffer.Pointer b = a.getPointer(i,j,k);
          * 
    + * * the item with index [i,j,k] is in the array b.storage at index * [b.offset] to [b.offset + itemsize - 1] inclusive. And if * itemsize==1, the item is simply the byte b.storage[b.offset] diff --git a/src/org/python/core/buffer/BaseBuffer.java b/src/org/python/core/buffer/BaseBuffer.java --- a/src/org/python/core/buffer/BaseBuffer.java +++ b/src/org/python/core/buffer/BaseBuffer.java @@ -1,5 +1,7 @@ package org.python.core.buffer; +import java.nio.ByteBuffer; + import org.python.core.BufferProtocol; import org.python.core.Py; import org.python.core.PyBUF; @@ -126,17 +128,17 @@ * Construct an instance of BaseBuffer in support of a sub-class, specifying the 'feature * flags', or at least a starting set to be adjusted later. These are the features of the buffer * exported, not the flags that form the consumer's request. The buffer will be read-only unless - * {@link PyBUF#WRITABLE} is set in the feature flags. {@link PyBUF#FORMAT} is implicitly added - * to the feature flags. The navigation arrays are all null, awaiting action by the sub-class - * constructor. To complete initialisation, the sub-class normally must assign: the buffer ( - * {@link #storage}, {@link #index0}), and the navigation arrays ({@link #shape}, - * {@link #strides}), and call {@link #checkRequestFlags(int)} passing the consumer's request - * flags. + * {@link PyBUF#WRITABLE} is set in the feature flags. {@link PyBUF#FORMAT} and + * {@link PyBUF#AS_ARRAY} are implicitly added to the feature flags. The navigation arrays are + * all null, awaiting action by the sub-class constructor. To complete initialisation, the + * sub-class normally must assign: the buffer ( {@link #storage}, {@link #index0}), and the + * navigation arrays ({@link #shape}, {@link #strides}), and call + * {@link #checkRequestFlags(int)} passing the consumer's request flags. * * @param featureFlags bit pattern that specifies the actual features allowed/required */ protected BaseBuffer(int featureFlags) { - setFeatureFlags(featureFlags | FORMAT); + setFeatureFlags(featureFlags | FORMAT | AS_ARRAY); } /** @@ -213,6 +215,12 @@ } @Override + public boolean hasArray() { + // AS_ARRAY is a non-navigational flag, so is inverted in gFeatureFlags + return (gFeatureFlags & AS_ARRAY) != 0; + } + + @Override public int getNdim() { return shape.length; } @@ -297,7 +305,7 @@ * accessors. The default implementation here is suited to N-dimensional arrays. * * @param indices of the item from the consumer - * @return index relative to item x[0,...,0] in actual storage + * @return corresponding absolute index in storage */ protected int calcIndex(int... indices) throws IndexOutOfBoundsException { final int N = checkDimension(indices); @@ -313,6 +321,57 @@ } /** + * Calculate the absolute byte index in the storage array of the last item of the exported data + * (if we are not using indirection). This is the greatest value attained by + * {@link #calcIndex(int...)}. The first byte not used will be one itemsize more + * than the returned value. + * + * @return greatest absolute index in storage + */ + protected int calcGreatestIndex() throws IndexOutOfBoundsException { + final int N = shape.length; + // If all the strides are positive, the maximal value is found from: + // index = index0 + sum(k=0,N-1) (shape[k]-1)*strides[k] + // but in general, for any k where strides[k]<=0, the term should be zero. + int index = index0; + if (N > 0) { + int[] strides = getStrides(); + for (int k = 0; k < N; k++) { + int stride = strides[k]; + if (stride > 0) { + index += (shape[k] - 1) * stride; + } + } + } + return index; + } + + /** + * Calculate the absolute byte index in the storage array of the first item of the exported data + * (if we are not using indirection). This is the least value attained by + * {@link #calcIndex(int...)}. + * + * @return least absolute index in storage + */ + protected int calcLeastIndex() throws IndexOutOfBoundsException { + final int N = shape.length; + // If all the strides are positive, the maximal value is just index0, + // but in general, we must allow strides[k]<=0 for some k: + // index = index0 + sum(k=0,N-1) (strides[k]<0) ? (shape[k]-1)*strides[k] : 0 + int index = index0; + if (N > 0) { + int[] strides = getStrides(); + for (int k = 0; k < N; k++) { + int stride = strides[k]; + if (stride < 0) { + index += (shape[k] - 1) * stride; + } + } + } + return index; + } + + /** * {@inheritDoc} *

    * The default implementation in BaseBuffer deals with the general one-dimensional @@ -540,6 +599,15 @@ // @Override public PyBuffer getBufferSlice(int flags, int start, int length, int stride) {} @Override + public ByteBuffer getNIOByteBuffer() { + // Determine the limit of the buffer just beyond the last item. + int length = calcGreatestIndex() + getItemsize() - index0; + ByteBuffer b = ByteBuffer.wrap(storage, index0, length); + // Return as read-only if it is. + return isReadonly() ? b.asReadOnlyBuffer() : b; + } + + @Override public Pointer getBuf() { return new Pointer(storage, index0); } @@ -664,6 +732,8 @@ return bufferRequires("shape array"); } else if ((syndrome & WRITABLE) != 0) { return bufferIsNot("writable"); + } else if ((syndrome & AS_ARRAY) != 0) { + return bufferIsNot("accessible as a Java array"); } else if ((syndrome & C_CONTIGUOUS) != 0) { return bufferIsNot("C-contiguous"); } else if ((syndrome & F_CONTIGUOUS) != 0) { diff --git a/src/org/python/core/buffer/SimpleBuffer.java b/src/org/python/core/buffer/SimpleBuffer.java --- a/src/org/python/core/buffer/SimpleBuffer.java +++ b/src/org/python/core/buffer/SimpleBuffer.java @@ -1,5 +1,7 @@ package org.python.core.buffer; +import java.nio.ByteBuffer; + import org.python.core.PyBuffer; import org.python.core.PyException; import org.python.core.util.StringUtil; @@ -229,6 +231,13 @@ } @Override + public ByteBuffer getNIOByteBuffer() { + // Simplify for one-dimensional contiguous bytes + ByteBuffer b = ByteBuffer.wrap(storage, index0, shape[0]); + return isReadonly() ? b.asReadOnlyBuffer() : b; + } + + @Override public Pointer getPointer(int index) throws IndexOutOfBoundsException { return new Pointer(storage, index0 + index); } diff --git a/src/org/python/core/buffer/SimpleStringBuffer.java b/src/org/python/core/buffer/SimpleStringBuffer.java --- a/src/org/python/core/buffer/SimpleStringBuffer.java +++ b/src/org/python/core/buffer/SimpleStringBuffer.java @@ -1,5 +1,7 @@ package org.python.core.buffer; +import java.nio.ByteBuffer; + import org.python.core.PyBuffer; import org.python.core.util.StringUtil; @@ -112,12 +114,19 @@ return getBufferSlice(flags, start, length); } else { // Force creation of the actual byte array from the String. - getBuf(); + ensureHaveBytes(); // Now we are effectively a SimpleBuffer, return the strided view. return super.getBufferSlice(flags, start, length, stride); } } + @Override + public ByteBuffer getNIOByteBuffer() { + // Force creation of the actual byte array from the String. + ensureHaveBytes(); + return super.getNIOByteBuffer().asReadOnlyBuffer(); + } + /** * This method creates an actual byte array from the underlying String if none yet exists. */ diff --git a/src/org/python/modules/_io/PyFileIO.java b/src/org/python/modules/_io/PyFileIO.java --- a/src/org/python/modules/_io/PyFileIO.java +++ b/src/org/python/modules/_io/PyFileIO.java @@ -251,8 +251,7 @@ PyBuffer pybuf = writablePyBuffer(buf); try { - PyBuffer.Pointer bp = pybuf.getBuf(); - ByteBuffer byteBuffer = ByteBuffer.wrap(bp.storage, bp.offset, pybuf.getLen()); + ByteBuffer byteBuffer = pybuf.getNIOByteBuffer(); synchronized (ioDelegate) { count = ioDelegate.readinto(byteBuffer); } @@ -293,8 +292,7 @@ try { // Access the data as a java.nio.ByteBuffer [pos:limit] within possibly larger array - PyBuffer.Pointer bp = pybuf.getBuf(); - ByteBuffer byteBuffer = ByteBuffer.wrap(bp.storage, bp.offset, pybuf.getLen()); + ByteBuffer byteBuffer = pybuf.getNIOByteBuffer(); synchronized (ioDelegate) { count = ioDelegate.write(byteBuffer); } diff --git a/src/org/python/modules/posix/PosixModule.java b/src/org/python/modules/posix/PosixModule.java --- a/src/org/python/modules/posix/PosixModule.java +++ b/src/org/python/modules/posix/PosixModule.java @@ -29,7 +29,6 @@ import org.python.core.Py; import org.python.core.PyBUF; import org.python.core.PyBuffer; -import org.python.core.PyBuffer.Pointer; import org.python.core.PyBuiltinFunctionNarrow; import org.python.core.PyDictionary; import org.python.core.PyException; @@ -826,10 +825,8 @@ public static int write(PyObject fd, BufferProtocol bytes) { // Get a buffer view: we can cope with N-dimensional data, but not strided data. try (PyBuffer buf = bytes.getBuffer(PyBUF.ND)) { - // Get the array and offset of the first real byte. - Pointer p = buf.getBuf(); - // Make a ByteBuffer of that array, setting the position and limit to the real data. - ByteBuffer bb = ByteBuffer.wrap(p.storage, p.offset, buf.getLen()); + // Get a ByteBuffer of that data, setting the position and limit to the real data. + ByteBuffer bb = buf.getNIOByteBuffer(); try { // Write the data (returning the count of bytes). return FileDescriptors.get(fd).write(bb); @@ -902,7 +899,7 @@ } /** - * Return a path as a String from a PyObject + * Return a path as a String from a PyObject * * @param path a PyObject, raising a TypeError if an invalid path type * @return a String path -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:24 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:24 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Add_index_translation_deleg?= =?utf-8?q?ate_to_PyUnicode=2C_fixes_=232100_at_O=28N=29_cost=2E?= Message-ID: <20140916225524.62043.2204@mail.hg.python.org> http://hg.python.org/jython/rev/191a9854396d changeset: 7380:191a9854396d user: Jeff Allen date: Sat Sep 06 13:21:12 2014 +0100 summary: Add index translation delegate to PyUnicode, fixes #2100 at O(N) cost. Access operations [i], slice and find operations take a time proportional to the length of the string, when it contains supplementary characters. files: Lib/test/test_unicode_jy.py | 11 +- src/org/python/core/PyString.java | 246 ++++++++++------ src/org/python/core/PyUnicode.java | 221 ++++++++++++-- 3 files changed, 335 insertions(+), 143 deletions(-) diff --git a/Lib/test/test_unicode_jy.py b/Lib/test/test_unicode_jy.py --- a/Lib/test/test_unicode_jy.py +++ b/Lib/test/test_unicode_jy.py @@ -290,7 +290,6 @@ for m in self.material: check_slice(m) - @unittest.skip("Fails on Jython 2.7b3 issue #2100") def test_find(self): # Test map from internal find result to code point index # Fails in Jython 2.7b3 @@ -304,6 +303,7 @@ i = u.find(c, start) if i < 0: break self.assertEqual(u[i], c) + self.assertGreaterEqual(i, start) start = i + 1 def check_find_str(m, t): @@ -325,7 +325,6 @@ m.insert(t) check_find_str(m, t) - @unittest.skip("Fails on Jython 2.7b3 issue #2100") def test_rfind(self): # Test map from internal rfind result to code point index # Fails in Jython 2.7b3 @@ -336,9 +335,11 @@ end = m.size u = m.text while True: - end = u.rfind(c, 0, end) - if end < 0: break - self.assertEqual(u[end], c) + i = u.rfind(c, 0, end) + if i < 0: break + self.assertLess(i, end) + self.assertEqual(u[i], c) + end = i def check_rfind_str(m, t): # Check rfind returns correct index for string target diff --git a/src/org/python/core/PyString.java b/src/org/python/core/PyString.java --- a/src/org/python/core/PyString.java +++ b/src/org/python/core/PyString.java @@ -72,6 +72,17 @@ return str; } + /** + * Determine whether the string consists entirely of basic-plane characters. For a + * {@link PyString}, of course, it is always true, but this is useful in cases + * where either a PyString or a {@link PyUnicode} is acceptable. + * + * @return true + */ + public boolean isBasicPlane() { + return true; + } + @ExposedNew static PyObject str_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { @@ -153,7 +164,7 @@ return str___str__(); } - public @ExposedMethod(doc = BuiltinDocs.str___str___doc) + @ExposedMethod(doc = BuiltinDocs.str___str___doc) final PyString str___str__() { if (getClass() == PyString.class) { return this; @@ -673,6 +684,14 @@ return new PyString(str); } + /** + * Create an instance of the same type as this object, from the Java String given as argument. + * This is to be overridden in a subclass to return its own type. + * + * @param string UTF-16 string encoding the characters (as Java). + * @param isBasic is ignored in PyString (effectively true). + * @return + */ protected PyString createInstance(String str, boolean isBasic) { // ignore isBasic, doesn't apply to PyString, just PyUnicode return new PyString(str); @@ -2353,59 +2372,28 @@ * @param endObj end of slice. * @return count of occurrences */ - protected final int _count_old(String sub, PyObject startObj, PyObject endObj) { -// xxx + protected final int _count(String sub, PyObject startObj, PyObject endObj) { + // Interpret the slice indices as concrete values int[] indices = translateIndices(startObj, endObj); int subLen = sub.length(); if (subLen == 0) { - // Special case counting the occurrences of an empty string - if (indices[2] > getString().length()) { + // Special case counting the occurrences of an empty string. + int start = indices[2], end = indices[3], n = __len__(); + if (end < 0 || end < start || start > n) { + // Slice is reversed or does not overlap the string. return 0; } else { - return indices[1] - indices[0] + 1; + // Count of '' is one more than number of characters in overlap. + return Math.min(end, n) - Math.max(start, 0) + 1; } } else { + // Skip down this string finding occurrences of sub - int start = indices[0], end = indices[1], count = 0; - while (true) { - int index = getString().indexOf(sub, start); - if (index < 0) { - break; // not found - } else { - // Found at index. Next search begins at end of this instance, at: - start = index + subLen; - if (start <= end) { - count += 1; // ... and the instance found fits within this string. - } else { - break; // ... but the instance found overlaps the end, so is not valid. - } - } - } - return count; - } - } - - protected final int _count(String sub, PyObject startObj, PyObject endObj) { - - // Interpret the slice indices as concrete values - int[] indices = translateIndices(startObj, endObj); - int subLen = sub.length(); - - if (subLen == 0) { - // Special case counting the occurrences of an empty string - if (indices[2] > getString().length()) { - return 0; - } else { - return indices[1] - indices[0] + 1; - } - - } else { - - // Skip down this string finding occurrences of sub - int start = indices[0], limit = indices[1] - subLen, count = 0; + int start = indices[0], end = indices[1]; + int limit = end - subLen, count = 0; while (start <= limit) { int index = getString().indexOf(sub, start); @@ -2496,17 +2484,36 @@ * {@link PyUnicode#unicode_find(PyObject, PyObject, PyObject)}. * * @param sub substring to find. - * @param start start of slice. - * @param end end of slice. + * @param startObj start of slice. + * @param endObj end of slice. * @return index of sub in this object or -1 if not found. */ - protected final int _find(String sub, PyObject start, PyObject end) { - int[] indices = translateIndices(start, end); - int index = getString().indexOf(sub, indices[0]); - if (index < indices[2] || index > indices[1]) { - return -1; + protected final int _find(String sub, PyObject startObj, PyObject endObj) { + // Interpret the slice indices as concrete values + int[] indices = translateIndices(startObj, endObj); + int subLen = sub.length(); + + if (subLen == 0) { + // Special case: an empty string may be found anywhere, ... + int start = indices[2], end = indices[3]; + if (end < 0 || end < start || start > __len__()) { + // ... except ln a reverse slice or beyond the end of the string, + return -1; + } else { + // ... and will be reported at the start of the overlap. + return indices[0]; + } + + } else { + // General case: search for first match then check against slice. + int start = indices[0], end = indices[1]; + int found = getString().indexOf(sub, start); + if (found >= 0 && found + subLen <= end) { + return found; + } else { + return -1; + } } - return index; } /** @@ -2582,17 +2589,36 @@ * {@link PyUnicode#unicode_rfind(PyObject, PyObject, PyObject)}. * * @param sub substring to find. - * @param start start of slice. - * @param end end of slice. + * @param startObj start of slice. + * @param endObj end of slice. * @return index of sub in this object or -1 if not found. */ - protected final int _rfind(String sub, PyObject start, PyObject end) { - int[] indices = translateIndices(start, end); - int index = getString().lastIndexOf(sub, indices[1] - sub.length()); - if (index < indices[2]) { - return -1; + protected final int _rfind(String sub, PyObject startObj, PyObject endObj) { + // Interpret the slice indices as concrete values + int[] indices = translateIndices(startObj, endObj); + int subLen = sub.length(); + + if (subLen == 0) { + // Special case: an empty string may be found anywhere, ... + int start = indices[2], end = indices[3]; + if (end < 0 || end < start || start > __len__()) { + // ... except ln a reverse slice or beyond the end of the string, + return -1; + } else { + // ... and will be reported at the end of the overlap. + return indices[1]; + } + + } else { + // General case: search for first match then check against slice. + int start = indices[0], end = indices[1]; + int found = getString().lastIndexOf(sub, end - subLen); + if (found >= start) { + return found; + } else { + return -1; + } } - return index; } public double atof() { @@ -3284,51 +3310,80 @@ } /** - * Turns the possibly negative Python slice start and end into valid indices into this string. + * Many of the string methods deal with slices specified using Python slice semantics: + * endpoints, which are PyObjects, may be null or None + * (meaning default to one end or the other) or may be negative (meaning "from the end"). + * Meanwhile, the implementation methods need integer indices, both within the array, and + * 0<=start<=end<=N the length of the array. + *

    + * This method first translates the Python slice startObj and endObj + * according to the slice semantics for null and negative values, and stores these in elements 2 + * and 3 of the result. Then, since the end points of the range may lie outside this sequence's + * bounds (in either direction) it reduces them to the nearest points satisfying + * 0<=start<=end<=N, and stores these in elements [0] and [1] of the + * result. * - * @return a 3 element array of indices into this string describing a substring from [0] to [1]. - * [0] <= [1], [0] >= 0 and [1] <= string.length(). The third element contains the - * unadjusted start value (or nearest int). + * @param startObj Python start of slice + * @param endObj Python end of slice + * @return a 4 element array of two range-safe indices, and two original indices. */ - protected int[] translateIndices(PyObject start, PyObject end) { - int iStart, iStartUnadjusted, iEnd; - int n = getString().length(); - - // Make sure the slice end decodes to something in range - if (end == null || end == Py.None) { - iEnd = n; + protected int[] translateIndices(PyObject startObj, PyObject endObj) { + int start, end; + int n = __len__(); + int[] result = new int[4]; + + // Decode the start using slice semantics + if (startObj == null || startObj == Py.None) { + start = 0; + // result[2] = 0 already } else { - // Convert to int but limit to Integer.MIN_VALUE <= iEnd <= Integer.MAX_VALUE - iEnd = end.asIndex(null); - if (iEnd > n) { - iEnd = n; - } else if (iEnd < 0) { - iEnd = n + iEnd; - if (iEnd < 0) { - iEnd = 0; + // Convert to int but limit to Integer.MIN_VALUE <= start <= Integer.MAX_VALUE + start = startObj.asIndex(null); + if (start < 0) { + // Negative value means "from the end" + start = n + start; + } + result[2] = start; + } + + // Decode the end using slice semantics + if (endObj == null || endObj == Py.None) { + result[1] = result[3] = end = n; + } else { + // Convert to int but limit to Integer.MIN_VALUE <= end <= Integer.MAX_VALUE + end = endObj.asIndex(null); + if (end < 0) { + // Negative value means "from the end" + result[3] = end = end + n; + // Ensure end is safe for String.substring(start,end). + if (end < 0) { + end = 0; + // result[1] = 0 already + } else { + result[1] = end; + } + } else { + result[3] = end; + // Ensure end is safe for String.substring(start,end). + if (end > n) { + result[1] = end = n; + } else { + result[1] = end; } } } - // Make sure the slice start decodes to something in range - if (start == null || start == Py.None) { - iStartUnadjusted = iStart = 0; + // Ensure start is safe for String.substring(start,end). + if (start < 0) { + start = 0; + // result[0] = 0 already + } else if (start > end) { + result[0] = start = end; } else { - // Convert to int but limit to Integer.MIN_VALUE <= iStart <= Integer.MAX_VALUE - iStartUnadjusted = iStart = start.asIndex(null); - if (iStart > iEnd) { - iStart = iEnd; - } else if (iStart < 0) { - iStart = n + iStart; - if (iStart > iEnd) { - iStart = iEnd; - } else if (iStart < 0) { - iStart = 0; - } - } + result[0] = start; } - return new int[] {iStart, iEnd, iStartUnadjusted}; + return result; } /** @@ -3847,7 +3902,8 @@ * @param keywords naming the keyword arguments. * @return the object designated or null. */ - private PyObject getFieldObject(String fieldName, boolean bytes, PyObject[] args, String[] keywords) { + private PyObject getFieldObject(String fieldName, boolean bytes, PyObject[] args, + String[] keywords) { FieldNameIterator iterator = new FieldNameIterator(fieldName, bytes); PyObject head = iterator.pyHead(); PyObject obj = null; diff --git a/src/org/python/core/PyUnicode.java b/src/org/python/core/PyUnicode.java --- a/src/org/python/core/PyUnicode.java +++ b/src/org/python/core/PyUnicode.java @@ -22,31 +22,44 @@ @ExposedType(name = "unicode", base = PyBaseString.class, doc = BuiltinDocs.unicode_doc) public class PyUnicode extends PyString implements Iterable { - private enum Plane { + /** + * Nearly every significant method comes in two versions: one applicable when the string + * contains only basic plane characters, and one that is correct when supplementary characters + * are also present. Set this constant true to treat all strings as containing + * supplementary characters, so that these versions will be exercised in tests. + */ + private static final boolean DEBUG_NON_BMP_METHODS = false; - UNKNOWN, BASIC, ASTRAL - } - - private volatile Plane plane = Plane.UNKNOWN; - private volatile int codePointCount = -1; public static final PyType TYPE = PyType.fromClass(PyUnicode.class); // for PyJavaClass.init() public PyUnicode() { - this(TYPE, ""); + this(TYPE, "", true); } + /** + * Construct a PyUnicode interpreting the Java String argument as UTF-16. + * + * @param string UTF-16 string encoding the characters (as Java). + */ public PyUnicode(String string) { - this(TYPE, string); + this(TYPE, string, false); } + /** + * Construct a PyUnicode interpreting the Java String argument as UTF-16. If it is known that + * the string contains no supplementary characters, argument isBasic may be set true by the + * caller. If it is false, the PyUnicode will scan the string to find out. + * + * @param string UTF-16 string encoding the characters (as Java). + * @param isBasic true if it is known that only BMP characters are present. + */ public PyUnicode(String string, boolean isBasic) { - this(TYPE, string); - plane = isBasic ? Plane.BASIC : Plane.UNKNOWN; + this(TYPE, string, isBasic); } public PyUnicode(PyType subtype, String string) { - super(subtype, string); + this(subtype, string, false); } public PyUnicode(PyString pystring) { @@ -54,12 +67,13 @@ } public PyUnicode(PyType subtype, PyString pystring) { - this(subtype, pystring instanceof PyUnicode ? pystring.string : pystring.decode() - .toString()); + this(subtype, // + pystring instanceof PyUnicode ? pystring.string : pystring.decode().toString(), // + pystring.isBasicPlane()); } public PyUnicode(char c) { - this(TYPE, String.valueOf(c)); + this(TYPE, String.valueOf(c), true); } public PyUnicode(int codepoint) { @@ -90,6 +104,20 @@ this(ucs4.iterator()); } + /** + * Fundamental all-features constructor on which the others depend. If it is known that the + * string contains no supplementary characters, argument isBasic may be set true by the caller. + * If it is false, the PyUnicode will scan the string to find out. + * + * @param subtype actual type to create. + * @param string UTF-16 string encoding the characters (as Java). + * @param isBasic true if it is known that only BMP characters are present. + */ + private PyUnicode(PyType subtype, String string, boolean isBasic) { + super(subtype, string); + translator = isBasic ? BASIC : this.chooseIndexTranslator(); + } + @Override public int[] toCodePoints() { int n = getCodePointCount(); @@ -101,6 +129,115 @@ return codePoints; } + // ------------------------------------------------------------------------------------------ + // Index translation for Unicode beyond the BMP + // ------------------------------------------------------------------------------------------ + + /** + * Index translation between code point index (as seen by Python) and UTF-16 index (as used in + * the Java String. + */ + private interface IndexTranslator { + + /** Number of supplementary characters (hence point code length may be found). */ + public int suppCount(); + + /** Translate a UTF-16 code unit index to its equivalent code point index. */ + public int codePointIndex(int utf16Index); + + /** Translate a code point index to its equivalent UTF-16 code unit index. */ + public int utf16Index(int codePointIndex); + } + + /** + * The instance of index translation in use in this string. It will be set to either + * {@link #BASIC} or and instance of {@link #Supplementary}. + */ + private final IndexTranslator translator; + + /** + * A singleton provides the translation service (which is a pass-through) for all BMP strings. + */ + static final IndexTranslator BASIC = new IndexTranslator() { + + @Override + public int suppCount() { + return 0; + } + + @Override + public int codePointIndex(int u) { + return u; + } + + @Override + public int utf16Index(int i) { + return i; + } + }; + + /** + * A class of index translation that uses the features provided by the Java String. + */ + private class Supplementary implements IndexTranslator { + + /** The number of supplementary character in this string. */ + private final int supp; + + Supplementary(int supp) { + this.supp = supp; + } + + @Override + public int codePointIndex(int u) { + return string.codePointCount(0, u); + } + + @Override + public int utf16Index(int i) { + return string.offsetByCodePoints(0, i); + } + + @Override + public int suppCount() { + return supp; + } + } + + /** + * Choose an {@link IndexTranslator} implementation for efficient working, according to the + * contents of the {@link PyString#string}. + * + * @return chosen IndexTranslator + */ + private IndexTranslator chooseIndexTranslator() { + int n = string.length(); + int s = n - string.codePointCount(0, n); + if (DEBUG_NON_BMP_METHODS) { + return new Supplementary(s); + } else { + return s == 0 ? BASIC : new Supplementary(s); + } + } + + /** + * {@inheritDoc} + *

    + * In the PyUnicode version, the arguments are code point indices, such as are + * received from the Python caller, while the first two elements of the returned array have been + * translated to UTF-16 indices in the implementation string. + */ + @Override + protected int[] translateIndices(PyObject start, PyObject end) { + int[] indices = super.translateIndices(start, end); + indices[0] = translator.utf16Index(indices[0]); + indices[1] = translator.utf16Index(indices[1]); + // indices[2] and [3] remain Unicode indices (and may be out of bounds) relative to len() + return indices; + } + + // ------------------------------------------------------------------------------------------ + // modified to know something about codepoints; we just need to return the // corresponding substring; darn UTF16! // TODO: we could avoid doing this unnecessary copy @@ -122,29 +259,22 @@ return uni; } + /** + * {@inheritDoc} + * + * @return true if the string consists only of BMP characters + */ + @Override public boolean isBasicPlane() { - if (plane == Plane.BASIC) { - return true; - } else if (plane == Plane.UNKNOWN) { - plane = (getString().length() == getCodePointCount()) ? Plane.BASIC : Plane.ASTRAL; + if (DEBUG_NON_BMP_METHODS) { + return false; + } else { + return translator.suppCount() == 0; } - return plane == Plane.BASIC; } -// RETAIN THE BELOW CODE, it facilitates testing astral support more completely - -// public boolean isBasicPlane() { -// return false; -// } - -// END RETAIN - public int getCodePointCount() { - if (codePointCount >= 0) { - return codePointCount; - } - codePointCount = getString().codePointCount(0, getString().length()); - return codePointCount; + return string.length() - translator.suppCount(); } @ExposedNew @@ -193,12 +323,13 @@ return new PyUnicode(str); } - // Unicode ops consisting of basic strings can only produce basic strings; - // this may not be the case for astral ones - they also might be basic, in - // case of deletes. So optimize by providing a tainting mechanism. + /** + * @param string UTF-16 string encoding the characters (as Java). + * @param isBasic true if it is known that only BMP characters are present. + */ @Override - protected PyString createInstance(String str, boolean isBasic) { - return new PyUnicode(str, isBasic); + protected PyString createInstance(String string, boolean isBasic) { + return new PyUnicode(string, isBasic); } @Override @@ -443,10 +574,12 @@ private PyUnicode coerceToUnicode(PyObject o) { if (o instanceof PyUnicode) { return (PyUnicode)o; + } else if (o instanceof PyString) { + return new PyUnicode(((PyString)o).getString(), true); } else if (o instanceof BufferProtocol) { - // PyString or PyByteArray, PyMemoryView, Py2kBuffer ... + // PyByteArray, PyMemoryView, Py2kBuffer ... try (PyBuffer buf = ((BufferProtocol)o).getBuffer(PyBUF.FULL_RO)) { - return new PyUnicode(buf.toString()); + return new PyUnicode(buf.toString(), true); } } else { // o is some type not allowed: @@ -998,7 +1131,7 @@ @Override protected PyString fromSubstring(int begin, int end) { assert (isBasicPlane()); // can only be used on a codepath from str_ equivalents - return new PyUnicode(getString().substring(begin, end)); + return new PyUnicode(getString().substring(begin, end), true); } @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_index_doc) @@ -1021,7 +1154,7 @@ if (isBasicPlane()) { return _count(sub.getString(), start, end); } - int[] indices = translateIndices(start, end); + int[] indices = super.translateIndices(start, end); // do not convert to utf-16 indices. int count = 0; for (Iterator mainIter = newSubsequenceIterator(indices[0], indices[1], 1); mainIter .hasNext();) { @@ -1043,12 +1176,14 @@ @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_find_doc) final int unicode_find(PyObject subObj, PyObject start, PyObject end) { - return _find(coerceToUnicode(subObj).getString(), start, end); + int found = _find(coerceToUnicode(subObj).getString(), start, end); + return found < 0 ? -1 : translator.codePointIndex(found); } @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_rfind_doc) final int unicode_rfind(PyObject subObj, PyObject start, PyObject end) { - return _rfind(coerceToUnicode(subObj).getString(), start, end); + int found = _rfind(coerceToUnicode(subObj).getString(), start, end); + return found < 0 ? -1 : translator.codePointIndex(found); } private static String padding(int n, int pad) { -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:26 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:26 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Forbid_lone_surrogates_in_P?= =?utf-8?q?yUnicode=2E_Consequent_refactoring=2E?= Message-ID: <20140916225526.116311.92950@mail.hg.python.org> http://hg.python.org/jython/rev/4187e256ae1e changeset: 7386:4187e256ae1e user: Jeff Allen date: Mon Sep 15 22:33:07 2014 +0100 summary: Forbid lone surrogates in PyUnicode. Consequent refactoring. Surrogate code units are not (easily) compatible with a PyUnicode implementation that uses a UTF-16 interpretation of String. This change produces test failures in test_unicodedata, but they should go away when merged with work on unichr. files: Lib/test/test_unicode_jy.py | 37 +++++ src/org/python/core/PyUnicode.java | 118 ++++++++++------ 2 files changed, 112 insertions(+), 43 deletions(-) diff --git a/Lib/test/test_unicode_jy.py b/Lib/test/test_unicode_jy.py --- a/Lib/test/test_unicode_jy.py +++ b/Lib/test/test_unicode_jy.py @@ -11,6 +11,7 @@ import unittest from StringIO import StringIO from test import test_support +from java.lang import StringBuilder class UnicodeTestCase(unittest.TestCase): @@ -360,6 +361,42 @@ m.insert(t) check_rfind_str(m, t) + def test_surrogate_validation(self): + + def insert_sb(text, c1, c2): + # Insert code points c1, c2 in the text, as a Java StringBuilder + sb = StringBuilder() + # c1 at the quarter point + p1 = len(mat) // 4 + for c in mat.text[:p1]: + sb.appendCodePoint(ord(c)) + sb.appendCodePoint(c1) + # c2 at the three-quarter point + p2 = 3 * p1 + for c in mat.text[p1:p2]: + sb.appendCodePoint(ord(c)) + sb.appendCodePoint(c2) + # Rest of text + for c in mat.text[p2:]: + sb.appendCodePoint(ord(c)) + return sb + + # Test that lone surrogates are rejected + for surr in [0xdc81, 0xdc00, 0xdfff, 0xd800, 0xdbff]: + for mat in self.material: + + # Java StringBuilder with two private-use characters: + sb = insert_sb(mat.text, 0xe000, 0xf000) + # Check this is acceptable + #print repr(unicode(sb)) + self.assertEqual(len(unicode(sb)), len(mat)+2) + + # Java StringBuilder with private-use and lone surrogate: + sb = insert_sb(mat.text, 0xe000, surr) + # Check this is detected + #print repr(unicode(sb)) + self.assertRaises(ValueError, unicode, sb) + class UnicodeFormatTestCase(unittest.TestCase): diff --git a/src/org/python/core/PyUnicode.java b/src/org/python/core/PyUnicode.java --- a/src/org/python/core/PyUnicode.java +++ b/src/org/python/core/PyUnicode.java @@ -336,11 +336,12 @@ int p; // Index of the current UTF-16 code unit. /* - * We scan to the first supplementary character in a simple loop. If we hit the end before - * we find one, no count array will be necessary and we'll use BASIC. + * We scan to the first surrogate code unit, in a simple loop. If we hit the end before we + * find one, no count array will be necessary and we'll use BASIC. If we find a surrogate it + * may be half a supplementary character, or a lone surrogate: we'll find out later. */ for (p = 0; p < n; p++) { - if (Character.isHighSurrogate(string.charAt(p))) { + if (Character.isSurrogate(string.charAt(p))) { break; } } @@ -371,20 +372,15 @@ /* * To get the generation of count[] going efficiently, we need to advance the next whole * block. The next loop will complete processing of the block containing the first - * supplementary character. Note that in all these loops, if we exit on p==n, the count - * for the last partial; block is known from p-q and we take care of that right at the - * end of this method. + * supplementary character. Note that in all these loops, if we exit because p reaches a + * limit, the count for the last partial block is known from p-q and we take care of + * that right at the end of this method. The limit of these loops is n-1, so if we spot + * a lead surrogate, the we may access the low-surrogate confident that p+1p we find a lead surrogate without a trailing one + * following, or a trailing surrogate directly. It should not be called on the final code unit, + * when p==string.length()-1, since it may check the next code unit as well. + * + * @param string of UTF-16 code units + * @param p index into that string + * @return 2 if a surrogate pair stands at p, 1 if not + * @throws PyException(ValueError) if a lone surrogate stands at p. + */ + private static int calcAdvance(String string, int p) throws PyException { + + // Catch supplementary characters and lone surrogate code units. + char c = string.charAt(p); + + if (c >= Character.MIN_SURROGATE) { + if (c < Character.MIN_LOW_SURROGATE) { + // This is a lead surrogate. + if (Character.isLowSurrogate(string.charAt(p + 1))) { + // Required trailing surrogate follows, so step over both. + return 2; + } else { + // Required trailing surrogate missing. + throw unpairedSurrogate(p, c); + } + + } else if (c <= Character.MAX_SURROGATE) { + // This is a lone trailing surrogate + throw unpairedSurrogate(p, c); + + } // else this is a private use or special character in 0xE000 to 0xFFFF. + + } + return 1; + } + + /** * Return a ready-to-throw exception indicating an unpaired surrogate. * - * @param n the UTF-16 length of the array being scanned - * @param p pointer within that array + * @param p index within that sequence of the problematic code unit + * @param c the code unit * @return an exception */ - private static PyException unpairedLeadSurrogate(int n, int p) { - String msg; - if (p + 1 >= n) { - msg = "unpaired lead-surrogate at end of string/array"; - } else { - String fmt = "unpaired lead-surrogate at code unit %d"; - msg = String.format(fmt, p); - } + private static PyException unpairedSurrogate(int p, int c) { + String fmt = "unpaired surrogate %#4x at code unit %d"; + String msg = String.format(fmt, c, p); return Py.ValueError(msg); } -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:25 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:25 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Relocate_ProxyDeserializati?= =?utf-8?q?on_to_a_default_package_directory=2E?= Message-ID: <20140916225524.118936.29729@mail.hg.python.org> http://hg.python.org/jython/rev/cc7f13d7915f changeset: 7381:cc7f13d7915f user: Jeff Allen date: Sat Sep 06 17:36:50 2014 +0100 summary: Relocate ProxyDeserialization to a default package directory. Quiets the IDE. Possibly should have package declaration instead. files: tests/java/javatests/ProxyDeserialization.java | 0 1 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/java/javatests/ProxyDeserialization.java b/tests/java/ProxyDeserialization.java rename from tests/java/javatests/ProxyDeserialization.java rename to tests/java/ProxyDeserialization.java -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:25 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:25 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Speed_up_unicode_index_and_?= =?utf-8?q?slice_operations_above_BMP=2E?= Message-ID: <20140916225525.53736.85754@mail.hg.python.org> http://hg.python.org/jython/rev/058aea53a4ec changeset: 7385:058aea53a4ec user: Jeff Allen date: Fri Sep 12 07:15:01 2014 +0100 summary: Speed up unicode index and slice operations above BMP. Simple uses of the index in pyget and for te start point of the subsequence iterator. files: src/org/python/core/PyUnicode.java | 26 ++--------------- 1 files changed, 3 insertions(+), 23 deletions(-) diff --git a/src/org/python/core/PyUnicode.java b/src/org/python/core/PyUnicode.java --- a/src/org/python/core/PyUnicode.java +++ b/src/org/python/core/PyUnicode.java @@ -694,37 +694,19 @@ @Override protected PyObject pyget(int i) { - if (isBasicPlane()) { - return Py.makeCharacter(getString().charAt(i), true); - } - - int k = 0; - while (i > 0) { - int W1 = getString().charAt(k); - if (W1 >= 0xD800 && W1 < 0xDC00) { - k += 2; - } else { - k += 1; - } - i--; - } - int codepoint = getString().codePointAt(k); + int codepoint = getString().codePointAt(translator.utf16Index(i)); return Py.makeCharacter(codepoint, true); } private class SubsequenceIteratorImpl implements Iterator { - private int current, k, start, stop, step; + private int current, k, stop, step; SubsequenceIteratorImpl(int start, int stop, int step) { - k = 0; current = start; - this.start = start; + k = translator.utf16Index(current); this.stop = stop; this.step = step; - for (int i = 0; i < start; i++) { - nextCodePoint(); - } } SubsequenceIteratorImpl() { @@ -1631,13 +1613,11 @@ @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_startswith_doc) final boolean unicode_startswith(PyObject prefix, PyObject start, PyObject end) { - // FIXME: slice indexing logic incorrect when this is ASTRAL return str_startswith(prefix, start, end); } @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_endswith_doc) final boolean unicode_endswith(PyObject suffix, PyObject start, PyObject end) { - // FIXME: slice indexing logic incorrect when this is ASTRAL return str_endswith(suffix, start, end); } -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 00:55:25 2014 From: jython-checkins at python.org (jeff.allen) Date: Tue, 16 Sep 2014 22:55:25 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Add_index_to_PyUnicode_faci?= =?utf-8?q?litating_O=281=29_access_to_strings_beyond_the_BMP=2E?= Message-ID: <20140916225525.29122.57772@mail.hg.python.org> http://hg.python.org/jython/rev/b96c8402f7ba changeset: 7384:b96c8402f7ba user: Jeff Allen date: Mon Sep 08 23:29:35 2014 +0100 summary: Add index to PyUnicode facilitating O(1) access to strings beyond the BMP. files: src/org/python/core/PyUnicode.java | 303 +++++++++++++++- 1 files changed, 283 insertions(+), 20 deletions(-) diff --git a/src/org/python/core/PyUnicode.java b/src/org/python/core/PyUnicode.java --- a/src/org/python/core/PyUnicode.java +++ b/src/org/python/core/PyUnicode.java @@ -177,46 +177,313 @@ }; /** - * A class of index translation that uses the features provided by the Java String. + * A class of index translation that uses the cumulative count so far of supplementary + * characters, tabulated in blocks of a standard size. The count is then used as an offset + * between the code point index and the corresponding point in the UTF-16 representation. */ - private class Supplementary implements IndexTranslator { + private final class Supplementary implements IndexTranslator { - /** The number of supplementary character in this string. */ - private final int supp; + /** Tabulates cumulative count so far of supplementary characters, by blocks of size M. */ + final int[] count; - Supplementary(int supp) { - this.supp = supp; + /** Configure the block size M, as this power of 2. */ + static final int LOG2M = 4; + /** The block size used for indexing (power of 2). */ + static final int M = 1 << LOG2M; + /** A mask used to separate the block number and offset in the block. */ + static final int MASK = M - 1; + + /** + * The constructor works on a count array prepared by + * {@link PyUnicode#getSupplementaryCounts(String)}. + */ + Supplementary(int[] count) { + this.count = count; } @Override public int codePointIndex(int u) { - return string.codePointCount(0, u); + /* + * Let the desired result be j such that utf16Index(j) = u. As we have only a forward + * index of the string, we have to conduct a search. In principle, we bound j by a pair + * of values (j1,j2) such that j1<=j> LOG2M) + 1; + // The count of supplementary characters before the start of block k2 is: + int c2 = count[k2 - 1]; + /* + * Since the count array is non-decreasing, and j < k2*M, we have u-j <= count[k2-1]. + * That is, j >= k1*M, where: + */ + int k1 = Math.max(0, u - c2) >> LOG2M; + // The count of supplementary characters before the start of block k1 is: + int c1 = (k1 == 0) ? 0 : count[k1 - 1]; + + /* + * Now, j (to be found) is in an unknown block k, where k1<=k u) { + // k*M+c > u therefore j is not in block k but to its left. + k2 = k; + c2 = c; + } else { + // k*M+c <= u therefore j must be in block k, or to its right. + k1 = k; + c1 = c; + } + } + } + + /* + * At this point, j is known to be in block k1 (and k2=k1+1). c1 is the number of + * supplementary characters to the left of code point index k1*M and c2 is the number of + * supplementary characters to the left of code point index (k1+1)*M. We have to search + * this block sequentially. The current position in the UTF-16 is: + */ + int p = (k1 << LOG2M) + c1; + while (p < u) { + if (Character.isHighSurrogate(string.charAt(p++))) { + // c1 tracks the number of supplementary characters to the left of p + c1 += 1; + if (c1 == c2) { + // We have found all supplementary characters in the block. + break; + } + // Skip the trailing surrogate. + p++; + } + } + // c1 is the number of supplementary characters to the left of u, so the result j is: + return u - c1; } @Override public int utf16Index(int i) { - return string.offsetByCodePoints(0, i); + // The code point index i lies in the k-th block where: + int k = i >> LOG2M; + // The offset for the code point index k*M is exactly + int d = (k == 0) ? 0 : count[k - 1]; + // The offset for the code point index (k+1)*M is exactly + int e = count[k]; + if (d == e) { + /* + * The offset for the code point index (k+1)*M is the same, and since this is a + * non-decreasing function of k, it is also the value for i. + */ + return i + d; + } else { + /* + * The offset for the code point index (k+1)*M is different (higher). We must scan + * along until we have found all the supplementary characters that precede i, + * starting the scan at code point index k*M. + */ + for (int q = i & ~MASK; q < i; q++) { + if (Character.isHighSurrogate(string.charAt(q + d))) { + d += 1; + if (d == e) { + /* + * We have found all the supplementary characters in this block, so we + * must have found all those to the left of i. + */ + break; + } + } + } + + // d counts all the supplementary characters to the left of i. + return i + d; + } } @Override public int suppCount() { - return supp; + // The last element of the count array is the total number of supplementary characters. + return count[count.length - 1]; } } /** + * Generate the table that is used by the class {@link Supplementary} to accelerate access to + * the the implementation string. The method returns null if the string passed + * contains no surrogate pairs, in which case we'll use {@link #BASIC} as the translator. This + * method is sensitive to {@link #DEBUG_NON_BMP_METHODS} which if true will prevent it returning + * null, hance we will always use a {@link Supplementary} {@link #translator}. + * + * @param string to index + * @return the index (counts) or null if basic plane + */ + private static int[] getSupplementaryCounts(final String string) { + + final int n = string.length(); + int p; // Index of the current UTF-16 code unit. + + /* + * We scan to the first supplementary character in a simple loop. If we hit the end before + * we find one, no count array will be necessary and we'll use BASIC. + */ + for (p = 0; p < n; p++) { + if (Character.isHighSurrogate(string.charAt(p))) { + break; + } + } + + if (p == n && !DEBUG_NON_BMP_METHODS) { + // There are no supplementary characters so the 1:1 translator is fine. + return null; + + } else { + /* + * We have to do this properly, using a scheme in which code point indexes are + * efficiently translatable to UTF-16 indexes through a table called here count[]. In + * this array, count[k] contains the total number of supplementary characters up to the + * end of the k.th block, that is, to the left of code point (k+1)M. We have to fill + * this array by scanning the string. + */ + int q = p; // The current code point index (q = p+s). + int k = q >> Supplementary.LOG2M; // The block number k = q/M. + + /* + * When addressing with a code point index q<=L (the length in code points) we will + * index the count array with k = q/M. We have q<=L<=n, therefore q/M <= n/M, the + * maximum valid k is 1 + n/M. A q>=L should raise IndexOutOfBoundsException, but it + * doesn't matter whether that's from indexing this array, or the string later. + */ + int[] count = new int[1 + (n >> Supplementary.LOG2M)]; + + /* + * To get the generation of count[] going efficiently, we need to advance the next whole + * block. The next loop will complete processing of the block containing the first + * supplementary character. Note that in all these loops, if we exit on p==n, the count + * for the last partial; block is known from p-q and we take care of that right at the + * end of this method. + */ + while (p < n) { + + if (Character.isHighSurrogate(string.charAt(p++))) { + // Integrity checks (also advances p past the trailing surrogate) + if (p == n || !Character.isLowSurrogate(string.charAt(p++))) { + // End of string follows or trailing surrogate does not : oops. + throw unpairedLeadSurrogate(n, p - 1); + } + } + + // Advance the code point index + q += 1; + + // Was that the last in a block? + if ((q & Supplementary.MASK) == 0) { + count[k++] = p - q; + break; + } + } + + /* + * If the string is long enough, we can work in whole blocks of M, and there are fewer + * things to track. We can't know the number of blocks in advance, but we know there is + * at least one whole block to go when p+2*M= n) { + msg = "unpaired lead-surrogate at end of string/array"; + } else { + String fmt = "unpaired lead-surrogate at code unit %d"; + msg = String.format(fmt, p); + } + return Py.ValueError(msg); + } + + /** * Choose an {@link IndexTranslator} implementation for efficient working, according to the * contents of the {@link PyString#string}. * * @return chosen IndexTranslator */ private IndexTranslator chooseIndexTranslator() { - int n = string.length(); - int s = n - string.codePointCount(0, n); + int[] count = getSupplementaryCounts(string); if (DEBUG_NON_BMP_METHODS) { - return new Supplementary(s); + return new Supplementary(count); } else { - return s == 0 ? BASIC : new Supplementary(s); + return count == null ? BASIC : new Supplementary(count); } } @@ -239,8 +506,8 @@ // ------------------------------------------------------------------------------------------ /** - * {@inheritDoc} - * The indices are code point indices, not UTF-16 (char) indices. For example: + * {@inheritDoc} The indices are code point indices, not UTF-16 (char) indices. For + * example: * *

          * PyUnicode u = new PyUnicode("..\ud800\udc02\ud800\udc03...");
    @@ -271,11 +538,7 @@
          */
         @Override
         public boolean isBasicPlane() {
    -        if (DEBUG_NON_BMP_METHODS) {
    -            return false;
    -        } else {
    -            return translator.suppCount() == 0;
    -        }
    +        return translator == BASIC;
         }
     
         public int getCodePointCount() {
    
    -- 
    Repository URL: http://hg.python.org/jython
    
    From jython-checkins at python.org  Wed Sep 17 00:55:25 2014
    From: jython-checkins at python.org (jeff.allen)
    Date: Tue, 16 Sep 2014 22:55:25 +0000
    Subject: [Jython-checkins] =?utf-8?q?jython=3A_Add_strided_slice_operation?=
     =?utf-8?q?_to_the_benchmmark_for_unicode_operations=2E?=
    Message-ID: <20140916225525.29801.15851@mail.hg.python.org>
    
    http://hg.python.org/jython/rev/a5d1fd17e143
    changeset:   7382:a5d1fd17e143
    user:        Jeff Allen 
    date:        Sun Sep 07 22:56:03 2014 +0100
    summary:
      Add strided slice operation to the benchmmark for unicode operations.
    
    files:
      tests/python/unicode_index_times.py |  53 ++++++++++++++--
      1 files changed, 45 insertions(+), 8 deletions(-)
    
    
    diff --git a/tests/python/unicode_index_times.py b/tests/python/unicode_index_times.py
    --- a/tests/python/unicode_index_times.py
    +++ b/tests/python/unicode_index_times.py
    @@ -179,11 +179,47 @@
                     starts = n - m + 1
                     for i in range(starts):
                         dummy = t[i:i+m]
    +                    #print(i, i+m, step, dummy)
                     opcount += starts
                     m *= 5
     
             return opcount
     
    +    def repeat_slice_step(self, mincount):
    +        ''' Extract a slice at each feasible position and length,
    +            and using different sizes for the step,
    +            repeating enough times to do mincount operations, and
    +            return the actual number of operations.
    +        '''
    +        n = self.size
    +        t = self.text
    +        opcount = 0
    +        dummy = None
    +        steps = [3, -1, 10]
    +
    +        while opcount < mincount:
    +            for step in steps:
    +                if step > 0:
    +                    m = 1
    +                    while m <= n:
    +                        starts = n - m + 1
    +                        for i in range(starts):
    +                            dummy = t[i:i+m:step]
    +                            #print(i, i+m, step, dummy)
    +                        opcount += starts
    +                        m *= 5
    +                else:
    +                    m = 1
    +                    while m <= n:
    +                        starts = n - m + 1
    +                        for i in range(starts):
    +                            dummy = t[i+m:i:step]
    +                            #print(i+m, i, step, dummy)
    +                        opcount += starts
    +                        m *= 5
    +                    
    +        return opcount
    +
         def repeat_find_char(self, mincount):
             ''' Do an incremental find of each code point, repeating
                 enough times to do mincount finds, and return the actual
    @@ -313,8 +349,8 @@
             ("long bmp", UnicodeActions(LONG, (lambda ran, i : False))),
             ("long 1%", UnicodeActions(LONG, evenly(0.01))),
             ("long 10%", UnicodeActions(LONG, evenly(0.1))),
    -        ("long 10% low", UnicodeActions(LONG, evenly_before(LONG/4, 0.4))),
    -        ("long 10% high", UnicodeActions(LONG, evenly_from(LONG-(LONG/4), 0.4))),
    +        ("long 10% L", UnicodeActions(LONG, evenly_before(LONG/4, 0.4))),
    +        ("long 10% H", UnicodeActions(LONG, evenly_from(LONG-(LONG/4), 0.4))),
             ("long 50%", UnicodeActions(LONG, evenly(0.5))),
             ("huge bmp", UnicodeActions(HUGE, (lambda ran, i : False))),
             ("huge 10%", UnicodeActions(HUGE, evenly(0.1))),
    @@ -323,16 +359,17 @@
         ops = [
             ("[i]", "repeat_getitem"),
             ("[i:i+n]", "repeat_slice"),
    +        ("[i:i+n:k]", "repeat_slice_step"),
             ("find(c)", "repeat_find_char"),
    -        ("find(str)", "repeat_find_str"),
    +        ("find(s)", "repeat_find_str"),
             ("rfind(c)", "repeat_rfind_char"),
    -        ("rfind(str)", "repeat_rfind_str"),
    +        ("rfind(s)", "repeat_rfind_str"),
         ]
     
     
    -    print("{:15s}{:>6s}".format("time (us)", "len"), end='')
    +    print("{:12s}{:>6s}".format("time (us)", "len"), end='')
         for title, _ in ops:
    -        print("{:>12s}".format(title), end='')
    +        print("{:>10s}".format(title), end='')
         print()
     
         mintime = dict()
    @@ -355,10 +392,10 @@
     
         # Cycle through the cases again to print them.
         for name, material in setups:
    -        print("{:15s}{:6d}".format(name, material.size), end='')
    +        print("{:12s}{:6d}".format(name, material.size), end='')
             for _, opname in ops:
                 t = mintime[(name, opname)]
    -            print("{:12.3f}".format(t), end='')
    +            print("{:10.2f}".format(t), end='')
             print()
     
         print("y =", trashcan)
    
    -- 
    Repository URL: http://hg.python.org/jython
    
    From jython-checkins at python.org  Wed Sep 17 00:55:29 2014
    From: jython-checkins at python.org (jeff.allen)
    Date: Tue, 16 Sep 2014 22:55:29 +0000
    Subject: [Jython-checkins] =?utf-8?q?jython_=28merge_default_-=3E_default?=
     =?utf-8?q?=29=3A_Merge_recent_work_to_trunk_=28mostly_PyUnicode=29=2E?=
    Message-ID: <20140916225526.35920.13124@mail.hg.python.org>
    
    http://hg.python.org/jython/rev/776cae0189ed
    changeset:   7387:776cae0189ed
    parent:      7375:4ed83fcdb13e
    parent:      7386:4187e256ae1e
    user:        Jeff Allen 
    date:        Tue Sep 16 23:55:09 2014 +0100
    summary:
      Merge recent work to trunk (mostly PyUnicode).
    
    files:
      Lib/test/test_bytes_jy.py                          |   44 +-
      Lib/test/test_unicode_jy.py                        |  249 ++++
      src/org/python/core/PyArray.java                   |   83 +-
      src/org/python/core/PyBUF.java                     |   10 +
      src/org/python/core/PyBuffer.java                  |   53 +-
      src/org/python/core/PyByteArray.java               |   30 +-
      src/org/python/core/PyString.java                  |  253 ++-
      src/org/python/core/PyUnicode.java                 |  563 ++++++++-
      src/org/python/core/buffer/BaseBuffer.java         |   86 +-
      src/org/python/core/buffer/SimpleBuffer.java       |    9 +
      src/org/python/core/buffer/SimpleStringBuffer.java |   11 +-
      src/org/python/modules/_io/PyFileIO.java           |    6 +-
      src/org/python/modules/posix/PosixModule.java      |    9 +-
      tests/java/javatests/ProxyDeserialization.java     |    0 
      tests/python/unicode_index_times.py                |  405 +++++++
      15 files changed, 1591 insertions(+), 220 deletions(-)
    
    
    diff --git a/Lib/test/test_bytes_jy.py b/Lib/test/test_bytes_jy.py
    --- a/Lib/test/test_bytes_jy.py
    +++ b/Lib/test/test_bytes_jy.py
    @@ -12,11 +12,51 @@
             class Sub(bytearray): pass
             s = Sub("abc123")
             self.assertEqual(len(s), 6)
    - 
    +
    +
    +class SimpleOperationsTest(unittest.TestCase):
    +    # Things the CPython library did not test throughly enough
    +
    +    def test_irepeat(self) :
    +
    +        def check_irepeat(a, n) :
    +            # Check in-place multiplication (repeats)
    +            b = bytearray(a)
    +            b *= n
    +            self.assertEquals(b, bytearray(a*n))
    +
    +        def irepeat_export(a, n) :
    +            # In-place multiplication with export mostly raises BufferError
    +            b = bytearray(a)
    +            with memoryview(b) as m:
    +                b *= n
    +            # If it doesn't raise, it gets the right answer
    +            self.assertEquals(b, bytearray(a*n))
    +
    +        for a in [b'', b'a', b'hello'] :
    +            check_irepeat(a, 7)
    +            check_irepeat(a, 1)
    +            check_irepeat(a, 0)
    +            check_irepeat(a, -1) # -ve treated as 0
    +
    +        # Resizing with exports should raise an exception
    +        self.assertRaises(BufferError, irepeat_export, b'a', 5)
    +        self.assertRaises(BufferError, irepeat_export, b'hello', 3)
    +        self.assertRaises(BufferError, irepeat_export, b'hello', 0)
    +        self.assertRaises(BufferError, irepeat_export, b'hello', -1)
    +
    +        # These don't raise an exception (CPython 2.7.6, 3.4.1)
    +        irepeat_export(b'a', 1)
    +        irepeat_export(b'hello', 1)
    +        for n in range(-1, 3) :
    +            irepeat_export(b'', n)
    +
     
     def test_main():
         test.test_support.run_unittest(
    -        ByteArraySubclassTest)
    +            ByteArraySubclassTest,
    +            SimpleOperationsTest,
    +        )
     
     
     if __name__ == "__main__":
    diff --git a/Lib/test/test_unicode_jy.py b/Lib/test/test_unicode_jy.py
    --- a/Lib/test/test_unicode_jy.py
    +++ b/Lib/test/test_unicode_jy.py
    @@ -3,12 +3,15 @@
     
     Made for Jython.
     """
    +import itertools
    +import random
     import re
     import string
     import sys
     import unittest
     from StringIO import StringIO
     from test import test_support
    +from java.lang import StringBuilder
     
     class UnicodeTestCase(unittest.TestCase):
     
    @@ -155,6 +158,251 @@
                 u'f')
     
     
    +class UnicodeMaterial(object):
    +    ''' Object holding a list of single characters and a unicode string
    +        that is their concatenation. The sequence is created from a
    +        background sequence of basic plane characters and random
    +        replacement with supplementary plane characters (those with
    +        point code>0xffff).
    +    '''
    +
    +    base = tuple(u'abcdefghijklmnopqrstuvwxyz')
    +    supp = tuple(map(unichr, range(0x10000, 0x1000c)))
    +    used = sorted(set(base+supp))
    +
    +    def __init__(self, size=20, pred=None, ran=None):
    +        ''' Create size chars choosing an SP char at i where
    +            pred(ran, i)==True where ran is an instance of
    +            random.Random supplied in the constructor or created
    +            locally (if ran==None).
    +        '''
    +
    +        # Generators for the BMP and SP characters
    +        base = itertools.cycle(UnicodeMaterial.base)
    +        supp = itertools.cycle(UnicodeMaterial.supp)
    +
    +        # Each instance gets a random generator
    +        if ran is None:
    +            ran = random.Random()
    +        self.random = ran
    +
    +        if pred is None:
    +            pred = lambda ran, j : ran.random() < DEFAULT_RATE
    +
    +        # Generate the list
    +        r = list()
    +        for i in range(size):
    +            if pred(self.random, i):
    +                c = supp.next()
    +            else:
    +                c = base.next()
    +            r.append(c)
    +
    +        # The list and its concatenation are our material
    +        self.ref = r
    +        self.size = len(r)
    +        self.text = u''.join(r)
    +        self.target = u''
    +
    +    def __len__(self):
    +        return self.size
    +
    +    def insert(self, target, p=None):
    +        ''' Insert target string at position p (or middle), truncating if
    +            that would make the material any longer
    +        '''
    +        if p is None:
    +            p = max(0, (self.size-len(target)) // 2)
    +
    +        n = 0
    +        for t in target:
    +            if p+n >= self.size:
    +                break;
    +            self.ref[p+n] = t
    +            n += 1
    +
    +        self.target = target[:n]
    +        self.text = u''.join(self.ref)
    +
    +
    +class UnicodeIndexMixTest(unittest.TestCase):
    +    # Test indexing where there may be more than one code unit per code point.
    +    # See Jython Issue #2100.
    +
    +    # Functions defining particular distributions of SP codes
    +    #
    +    def evenly(self, rate=0.2):
    +        'Evenly distributed at given rate'
    +        def f(ran, i):
    +            return ran.random() < rate
    +        return f
    +
    +    def evenly_before(self, k, rate=0.2):
    +        'Evenly distributed on i=k at given rate'
    +        def f(ran, i):
    +            return i >= k and ran.random() < rate
    +        return f
    +
    +    def at(self, places):
    +        'Only at specified places'
    +        def f(ran, i):
    +            return i in places
    +        return f
    +
    +    def setUp(self):
    +        ran = random.Random(1234)  # ensure repeatable
    +        mat = list()
    +        mat.append(UnicodeMaterial(10, self.at([2]), ran))
    +        mat.append(UnicodeMaterial(10, self.at([2, 5]), ran))
    +        mat.append(UnicodeMaterial(50, self.evenly(), ran))
    +        mat.append(UnicodeMaterial(200, self.evenly_before(70), ran))
    +        mat.append(UnicodeMaterial(200, self.evenly_from(130), ran))
    +        mat.append(UnicodeMaterial(1000, self.evenly(), ran))
    +
    +        self.material = mat
    +
    +
    +    def test_getitem(self):
    +        # Test map from to code point index to internal representation
    +        # Fails in Jython 2.7b3
    +
    +        def check_getitem(m):
    +            # Check indexing the string returns the expected point code
    +            for i in xrange(m.size):
    +                self.assertEqual(m.text[i], m.ref[i])
    +
    +        for m in self.material:
    +            check_getitem(m)
    +
    +    def test_slice(self):
    +        # Test indexing gets the slice ends correct.
    +        # Passes in Jython 2.7b3, but may be touched by #2100 changes.
    +
    +        def check_slice(m):
    +            # Check a range of slices against slices of the reference.
    +            n = 1
    +            while n <= m.size:
    +                for i in range(m.size - n):
    +                    exp = u''.join(m.ref[i:i+n])
    +                    self.assertEqual(m.text[i:i+n], exp)
    +                n *= 3
    +
    +        for m in self.material:
    +            check_slice(m)
    +
    +    def test_find(self):
    +        # Test map from internal find result to code point index
    +        # Fails in Jython 2.7b3
    +
    +        def check_find(ref):
    +            # Check find returns indexes for single point codes
    +            for c in set(m.used):
    +                start = 0
    +                u = m.text
    +                while start < m.size:
    +                    i = u.find(c, start)
    +                    if i < 0: break
    +                    self.assertEqual(u[i], c)
    +                    self.assertGreaterEqual(i, start)
    +                    start = i + 1
    +
    +        def check_find_str(m, t):
    +            # Check find returns correct index for string target
    +            i = m.text.find(t)
    +            self.assertEqual(list(t), m.ref[i:i+len(t)])
    +
    +        targets = [
    +            u"this",
    +            u"ab\U00010041de", 
    +            u"\U00010041\U00010042\U00010042xx",
    +            u"xx\U00010041\U00010042\U00010043yy",
    +        ]
    +
    +        for m in self.material:
    +            check_find(m)
    +            for t in targets:
    +                # Insert in middle then try to find it
    +                m.insert(t)
    +                check_find_str(m, t)
    +
    +    def test_rfind(self):
    +        # Test map from internal rfind result to code point index
    +        # Fails in Jython 2.7b3
    +
    +        def check_rfind(ref):
    +            # Check rfind returns indexes for single point codes
    +            for c in set(m.used):
    +                end = m.size
    +                u = m.text
    +                while True:
    +                    i = u.rfind(c, 0, end)
    +                    if i < 0: break
    +                    self.assertLess(i, end)
    +                    self.assertEqual(u[i], c)
    +                    end = i
    +
    +        def check_rfind_str(m, t):
    +            # Check rfind returns correct index for string target
    +            i = m.text.rfind(t)
    +            self.assertEqual(list(t), m.ref[i:i+len(t)])
    +
    +        targets = [
    +            u"this",
    +            u"ab\U00010041de", 
    +            u"\U00010041\U00010042\U00010042xx",
    +            u"xx\U00010041\U00010042\U00010043yy",
    +        ]
    +
    +        for m in self.material:
    +            check_rfind(m)
    +            for t in targets:
    +                # Insert in middle then try to find it
    +                m.insert(t)
    +                check_rfind_str(m, t)
    +
    +    def test_surrogate_validation(self):
    +
    +        def insert_sb(text, c1, c2):
    +            # Insert code points c1, c2 in the text, as a Java StringBuilder
    +            sb = StringBuilder()
    +            # c1 at the quarter point
    +            p1 = len(mat) // 4
    +            for c in mat.text[:p1]:
    +                sb.appendCodePoint(ord(c))
    +            sb.appendCodePoint(c1)
    +            # c2 at the three-quarter point
    +            p2 = 3 * p1
    +            for c in mat.text[p1:p2]:
    +                sb.appendCodePoint(ord(c))
    +            sb.appendCodePoint(c2)
    +            # Rest of text
    +            for c in mat.text[p2:]:
    +                sb.appendCodePoint(ord(c))
    +            return sb
    +
    +        # Test that lone surrogates are rejected
    +        for surr in [0xdc81, 0xdc00, 0xdfff, 0xd800, 0xdbff]:
    +            for mat in self.material:
    +
    +                # Java StringBuilder with two private-use characters:
    +                sb = insert_sb(mat.text, 0xe000, 0xf000)
    +                # Check this is acceptable
    +                #print repr(unicode(sb))
    +                self.assertEqual(len(unicode(sb)), len(mat)+2)
    +
    +                # Java StringBuilder with private-use and lone surrogate:
    +                sb = insert_sb(mat.text, 0xe000, surr)
    +                # Check this is detected
    +                #print repr(unicode(sb))
    +                self.assertRaises(ValueError, unicode, sb)
    +
    +
     class UnicodeFormatTestCase(unittest.TestCase):
     
         def test_unicode_mapping(self):
    @@ -601,6 +849,7 @@
     def test_main():
         test_support.run_unittest(
                     UnicodeTestCase,
    +                UnicodeIndexMixTest,
                     UnicodeFormatTestCase,
                     UnicodeStdIOTestCase,
                     UnicodeFormatStrTest,
    diff --git a/src/org/python/core/PyArray.java b/src/org/python/core/PyArray.java
    --- a/src/org/python/core/PyArray.java
    +++ b/src/org/python/core/PyArray.java
    @@ -1,7 +1,6 @@
     // Copyright (c) Corporation for National Research Initiatives
     package org.python.core;
     
    -import java.io.ByteArrayInputStream;
     import java.io.ByteArrayOutputStream;
     import java.io.DataInputStream;
     import java.io.DataOutputStream;
    @@ -11,6 +10,7 @@
     import java.io.OutputStream;
     import java.lang.ref.WeakReference;
     import java.lang.reflect.Array;
    +import java.nio.ByteBuffer;
     
     import org.python.core.buffer.BaseBuffer;
     import org.python.core.buffer.SimpleStringBuffer;
    @@ -1130,19 +1130,17 @@
                     frombytesInternal(StringUtil.toBytes(s));
     
                 } else {
    -                // Access the bytes
    +                // Access the bytes through the abstract API of the BufferProtocol
                     try (PyBuffer pybuf = ((BufferProtocol)input).getBuffer(PyBUF.STRIDED_RO)) {
    -                    // Provide argument as stream of bytes for fromstream method
                         if (pybuf.getNdim() == 1) {
                             if (pybuf.getStrides()[0] == 1) {
    -                            // Data are contiguous in a byte[]
    -                            PyBuffer.Pointer b = pybuf.getBuf();
    -                            frombytesInternal(b.storage, b.offset, pybuf.getLen());
    +                            // Data are contiguous in the buffer
    +                            frombytesInternal(pybuf.getNIOByteBuffer());
                             } else {
                                 // As frombytesInternal only knows contiguous bytes, make a copy.
                                 byte[] copy = new byte[pybuf.getLen()];
                                 pybuf.copyTo(copy, 0);
    -                            frombytesInternal(copy);
    +                            frombytesInternal(ByteBuffer.wrap(copy));
                             }
                         } else {
                             // Currently don't support n-dimensional sources
    @@ -1158,39 +1156,30 @@
         }
     
         /**
    -     * Common code supporting Java and Python versions of .fromstring()
    -     *
    -     * @param input string of bytes encoding the array data
    -     */
    -    private final void fromstringInternal(String input) {
    -        frombytesInternal(StringUtil.toBytes(input));
    -    }
    -
    -    /**
          * Common code supporting Java and Python versions of .fromstring() or
          * .frombytes() (Python 3.2+ name).
          *
          * @param bytes array containing the new array data in machine encoding
          */
         private final void frombytesInternal(byte[] bytes) {
    -        frombytesInternal(bytes, 0, bytes.length);
    +        frombytesInternal(ByteBuffer.wrap(bytes));
         }
     
         /**
    -     * Common code supporting Java and Python versions of .fromstring() or
    -     * .frombytes() (Python 3.2+ name).
    +     * Copy into this array, the remaining bytes of a ByteBuffer (from the current position to the
    +     * limit). This is common code supporting Java and Python versions of .fromstring()
    +     * or .frombytes() (Python 3.2+ name).
          *
    -     * @param bytes array containing the new array data in machine encoding
    -     * @param offset of the first byte to read
    -     * @param count of bytes to read
    +     * @param bytes buffer containing the new array data in machine encoding
          */
    -    private final void frombytesInternal(byte[] bytes, int offset, int count) {
    +    private final void frombytesInternal(ByteBuffer bytes) {
     
             // Access the bytes
             int origsize = delegate.getSize();
     
             // Check validity wrt array itemsize
             int itemsize = getStorageSize();
    +        int count = bytes.remaining();
             if ((count % itemsize) != 0) {
                 throw Py.ValueError("string length not a multiple of item size");
             }
    @@ -1201,8 +1190,8 @@
             try {
     
                 // Provide argument as stream of bytes for fromstream method
    -            ByteArrayInputStream bis = new ByteArrayInputStream(bytes, offset, count);
    -            fromStream(bis);
    +            InputStream is = new ByteBufferBackedInputStream(bytes);
    +            fromStream(is);
     
             } catch (EOFException e) {
                 // stubbed catch for fromStream throws
    @@ -2117,4 +2106,48 @@
             }
         }
     
    +    /**
    +     * Wrap a ByteBuffer in an InputStream. Reference: 
    +     * Stackoverflow question 4332264.
    +     */
    +    private class ByteBufferBackedInputStream extends InputStream {
    +
    +        ByteBuffer buf;
    +
    +        public ByteBufferBackedInputStream(ByteBuffer buf) {
    +            this.buf = buf;
    +        }
    +
    +        /**
    +         * Return the number of bytes remaining in the underlying buffer.
    +         */
    +        @Override
    +        public int available() throws IOException {
    +            return buf.remaining();
    +        }
    +
    +
    +        @Override
    +        public int read() {
    +            return buf.hasRemaining() ? buf.get() & 0xff : -1;
    +        }
    +
    +        @Override
    +        public int read(byte[] bytes, int off, int len) {
    +            int n = buf.remaining();
    +            if (n >= len) {
    +                // There are enough bytes remaining to satisfy the request.
    +                buf.get(bytes, off, len);
    +                return len;
    +            } else if (n > 0) {
    +                // There are some bytes remaining: truncate request.
    +                buf.get(bytes, off, n);
    +                return n;
    +            } else {
    +                // Signal that there are no bytes left
    +                return -1;
    +            }
    +        }
    +    }
     }
    diff --git a/src/org/python/core/PyBUF.java b/src/org/python/core/PyBUF.java
    --- a/src/org/python/core/PyBUF.java
    +++ b/src/org/python/core/PyBUF.java
    @@ -213,6 +213,16 @@
          */
         static final int FULL_RO = INDIRECT | FORMAT;
     
    +    /* Constants for additional feature(s), not standard for CPython */
    +
    +    /**
    +     * A constant used by the consumer in its call to {@link BufferProtocol#getBuffer(int)} to
    +     * specify that it expects to access the buffer contents directly as an array (rather than
    +     * through the purely abstract part of the API). getBuffer will raise an exception
    +     * if the exporter cannot expose its storage as Java array.
    +     */
    +    static final int AS_ARRAY = 0x10000000;
    +
         /* Constants for readability, not standard for CPython */
     
         /**
    diff --git a/src/org/python/core/PyBuffer.java b/src/org/python/core/PyBuffer.java
    --- a/src/org/python/core/PyBuffer.java
    +++ b/src/org/python/core/PyBuffer.java
    @@ -1,5 +1,7 @@
     package org.python.core;
     
    +import java.nio.ByteBuffer;
    +
     /**
      * The Jython buffer API for access to a byte array within an exporting object. This interface is
      * the counterpart of the CPython Py_buffer struct. Several concrete types implement
    @@ -237,10 +239,49 @@
          */
         public PyBuffer getBufferSlice(int flags, int start, int length, int stride);
     
    +    // java.nio access to actual storage
    +    //
    +
    +    /**
    +     * Obtain a {@link java.nio.ByteBuffer} giving access to the bytes that hold the data being
    +     * exported to the consumer. For a one-dimensional contiguous buffer, assuming the following
    +     * client code where obj has type BufferProtocol:
    +     *
    +     * 
    +     * PyBuffer a = obj.getBuffer(PyBUF.SIMPLE);
    +     * int itemsize = a.getItemsize();
    +     * ByteBuffer bb = a.getNIOBuffer();
    +     * 
    + * + * the item with index bb.pos()+k is in the buffer bb at positions + * bb.pos()+k*itemsize to bb.pos()+(k+1)*itemsize - 1 inclusive. And + * if itemsize==1, the item is simply the byte at position bb.pos()+k. + * The buffer limit is set to the first byte beyond the valid data. A block read or write will + * therefore access the contents sequentially. + *

    + * If the buffer is multidimensional or non-contiguous (strided), the buffer position is still + * the (first byte of) the item at index [0] or [0,...,0], and the + * limit is one item beyond the valid data. However, it is necessary to navigate bb + * using the shape, strides and maybe suboffsets provided + * by the API. + * + * @return a ByteBuffer equivalent to the exported data contents. + */ + ByteBuffer getNIOByteBuffer(); + // Direct access to actual storage // /** + * Determine whether the exporter is able to offer direct access to the exported storage as a + * Java byte array (through the API that involves class {@link Pointer}), or only supports the + * abstract API. See also {@link PyBUF#AS_ARRAY}. + * + * @return true if array access is supported, false if it is not. + */ + boolean hasArray(); + + /** * A class that references a byte[] array and a particular offset within it, as the * return type for methods that give direct access to byte-oriented data exported by a Python * object. In some contexts the consumer will be entitled to make changes to the contents of @@ -270,11 +311,13 @@ * Return a structure describing the slice of a byte array that holds the data being exported to * the consumer. For a one-dimensional contiguous buffer, assuming the following client code * where obj has type BufferProtocol: + * *

    -     * PyBuffer a = obj.getBuffer();
    +     * PyBuffer a = obj.getBuffer(PyBUF.SIMPLE);
          * int itemsize = a.getItemsize();
          * PyBuffer.Pointer b = a.getBuf();
          * 
    + * * the item with index k is in the array b.storage at index * [b.offset + k*itemsize] to [b.offset + (k+1)*itemsize - 1] * inclusive. And if itemsize==1, the item is simply the byte @@ -293,12 +336,14 @@ * Return a structure describing the position in a byte array of a single item from the data * being exported to the consumer. For a one-dimensional contiguous buffer, assuming the * following client code where obj has type BufferProtocol: + * *
          * int k = ... ;
    -     * PyBuffer a = obj.getBuffer();
    +     * PyBuffer a = obj.getBuffer(PyBUF.FULL);
          * int itemsize = a.getItemsize();
          * PyBuffer.Pointer b = a.getPointer(k);
          * 
    + * * the item with index k is in the array b.storage at index * [b.offset] to [b.offset + itemsize - 1] inclusive. And if * itemsize==1, the item is simply the byte b.storage[b.offset] @@ -317,13 +362,15 @@ * being exported to the consumer, in the case that array may be multi-dimensional. For a * 3-dimensional contiguous buffer, assuming the following client code where obj * has type BufferProtocol: + * *
          * int i, j, k;
          * // ... calculation that assigns i, j, k
    -     * PyBuffer a = obj.getBuffer();
    +     * PyBuffer a = obj.getBuffer(PyBUF.FULL);
          * int itemsize = a.getItemsize();
          * PyBuffer.Pointer b = a.getPointer(i,j,k);
          * 
    + * * the item with index [i,j,k] is in the array b.storage at index * [b.offset] to [b.offset + itemsize - 1] inclusive. And if * itemsize==1, the item is simply the byte b.storage[b.offset] diff --git a/src/org/python/core/PyByteArray.java b/src/org/python/core/PyByteArray.java --- a/src/org/python/core/PyByteArray.java +++ b/src/org/python/core/PyByteArray.java @@ -352,7 +352,33 @@ * @param count the number of times to repeat this. */ protected synchronized void irepeat(int count) { - this.setStorage(repeatImpl(count)); + // There are several special cases + if (size == 0 || count == 1) { + // No resize, so no check (consistent with CPython) + // Value is unchanged. + + } else if (count <= 0) { + // Treat as if count == 0. + resizeCheck(); + this.setStorage(emptyStorage); + + } else { + // Open up space (remembering the original size) + int orginalSize = size; + storageExtend(orginalSize * (count - 1)); + if (orginalSize == 1) { + // Do it efficiently for single bytes + byte b = storage[offset]; + for (int i = 1, p = offset + 1; i < count; i++) { + storage[p++] = b; + } + } else { + // General case + for (int i = 1, p = offset + orginalSize; i < count; i++, p += orginalSize) { + System.arraycopy(storage, offset, storage, p, orginalSize); + } + } + } } /** @@ -924,7 +950,7 @@ return bytearray___imul__(n); } - @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.bytearray___mul___doc) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.bytearray___imul___doc) final PyObject bytearray___imul__(PyObject n) { if (!n.isIndex()) { return null; diff --git a/src/org/python/core/PyString.java b/src/org/python/core/PyString.java --- a/src/org/python/core/PyString.java +++ b/src/org/python/core/PyString.java @@ -72,6 +72,17 @@ return str; } + /** + * Determine whether the string consists entirely of basic-plane characters. For a + * {@link PyString}, of course, it is always true, but this is useful in cases + * where either a PyString or a {@link PyUnicode} is acceptable. + * + * @return true + */ + public boolean isBasicPlane() { + return true; + } + @ExposedNew static PyObject str_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { @@ -144,6 +155,13 @@ return pybuf; } + /** + * Return a substring of this object as a Java String. + * + * @param start the beginning index, inclusive. + * @param end the ending index, exclusive. + * @return the specified substring. + */ public String substring(int start, int end) { return getString().substring(start, end); } @@ -153,7 +171,7 @@ return str___str__(); } - public @ExposedMethod(doc = BuiltinDocs.str___str___doc) + @ExposedMethod(doc = BuiltinDocs.str___str___doc) final PyString str___str__() { if (getClass() == PyString.class) { return this; @@ -673,6 +691,14 @@ return new PyString(str); } + /** + * Create an instance of the same type as this object, from the Java String given as argument. + * This is to be overridden in a subclass to return its own type. + * + * @param string UTF-16 string encoding the characters (as Java). + * @param isBasic is ignored in PyString (effectively true). + * @return + */ protected PyString createInstance(String str, boolean isBasic) { // ignore isBasic, doesn't apply to PyString, just PyUnicode return new PyString(str); @@ -2353,59 +2379,28 @@ * @param endObj end of slice. * @return count of occurrences */ - protected final int _count_old(String sub, PyObject startObj, PyObject endObj) { -// xxx + protected final int _count(String sub, PyObject startObj, PyObject endObj) { + // Interpret the slice indices as concrete values int[] indices = translateIndices(startObj, endObj); int subLen = sub.length(); if (subLen == 0) { - // Special case counting the occurrences of an empty string - if (indices[2] > getString().length()) { + // Special case counting the occurrences of an empty string. + int start = indices[2], end = indices[3], n = __len__(); + if (end < 0 || end < start || start > n) { + // Slice is reversed or does not overlap the string. return 0; } else { - return indices[1] - indices[0] + 1; + // Count of '' is one more than number of characters in overlap. + return Math.min(end, n) - Math.max(start, 0) + 1; } } else { + // Skip down this string finding occurrences of sub - int start = indices[0], end = indices[1], count = 0; - while (true) { - int index = getString().indexOf(sub, start); - if (index < 0) { - break; // not found - } else { - // Found at index. Next search begins at end of this instance, at: - start = index + subLen; - if (start <= end) { - count += 1; // ... and the instance found fits within this string. - } else { - break; // ... but the instance found overlaps the end, so is not valid. - } - } - } - return count; - } - } - - protected final int _count(String sub, PyObject startObj, PyObject endObj) { - - // Interpret the slice indices as concrete values - int[] indices = translateIndices(startObj, endObj); - int subLen = sub.length(); - - if (subLen == 0) { - // Special case counting the occurrences of an empty string - if (indices[2] > getString().length()) { - return 0; - } else { - return indices[1] - indices[0] + 1; - } - - } else { - - // Skip down this string finding occurrences of sub - int start = indices[0], limit = indices[1] - subLen, count = 0; + int start = indices[0], end = indices[1]; + int limit = end - subLen, count = 0; while (start <= limit) { int index = getString().indexOf(sub, start); @@ -2496,17 +2491,36 @@ * {@link PyUnicode#unicode_find(PyObject, PyObject, PyObject)}. * * @param sub substring to find. - * @param start start of slice. - * @param end end of slice. + * @param startObj start of slice. + * @param endObj end of slice. * @return index of sub in this object or -1 if not found. */ - protected final int _find(String sub, PyObject start, PyObject end) { - int[] indices = translateIndices(start, end); - int index = getString().indexOf(sub, indices[0]); - if (index < indices[2] || index > indices[1]) { - return -1; + protected final int _find(String sub, PyObject startObj, PyObject endObj) { + // Interpret the slice indices as concrete values + int[] indices = translateIndices(startObj, endObj); + int subLen = sub.length(); + + if (subLen == 0) { + // Special case: an empty string may be found anywhere, ... + int start = indices[2], end = indices[3]; + if (end < 0 || end < start || start > __len__()) { + // ... except ln a reverse slice or beyond the end of the string, + return -1; + } else { + // ... and will be reported at the start of the overlap. + return indices[0]; + } + + } else { + // General case: search for first match then check against slice. + int start = indices[0], end = indices[1]; + int found = getString().indexOf(sub, start); + if (found >= 0 && found + subLen <= end) { + return found; + } else { + return -1; + } } - return index; } /** @@ -2582,17 +2596,36 @@ * {@link PyUnicode#unicode_rfind(PyObject, PyObject, PyObject)}. * * @param sub substring to find. - * @param start start of slice. - * @param end end of slice. + * @param startObj start of slice. + * @param endObj end of slice. * @return index of sub in this object or -1 if not found. */ - protected final int _rfind(String sub, PyObject start, PyObject end) { - int[] indices = translateIndices(start, end); - int index = getString().lastIndexOf(sub, indices[1] - sub.length()); - if (index < indices[2]) { - return -1; + protected final int _rfind(String sub, PyObject startObj, PyObject endObj) { + // Interpret the slice indices as concrete values + int[] indices = translateIndices(startObj, endObj); + int subLen = sub.length(); + + if (subLen == 0) { + // Special case: an empty string may be found anywhere, ... + int start = indices[2], end = indices[3]; + if (end < 0 || end < start || start > __len__()) { + // ... except ln a reverse slice or beyond the end of the string, + return -1; + } else { + // ... and will be reported at the end of the overlap. + return indices[1]; + } + + } else { + // General case: search for first match then check against slice. + int start = indices[0], end = indices[1]; + int found = getString().lastIndexOf(sub, end - subLen); + if (found >= start) { + return found; + } else { + return -1; + } } - return index; } public double atof() { @@ -3284,51 +3317,80 @@ } /** - * Turns the possibly negative Python slice start and end into valid indices into this string. + * Many of the string methods deal with slices specified using Python slice semantics: + * endpoints, which are PyObjects, may be null or None + * (meaning default to one end or the other) or may be negative (meaning "from the end"). + * Meanwhile, the implementation methods need integer indices, both within the array, and + * 0<=start<=end<=N the length of the array. + *

    + * This method first translates the Python slice startObj and endObj + * according to the slice semantics for null and negative values, and stores these in elements 2 + * and 3 of the result. Then, since the end points of the range may lie outside this sequence's + * bounds (in either direction) it reduces them to the nearest points satisfying + * 0<=start<=end<=N, and stores these in elements [0] and [1] of the + * result. * - * @return a 3 element array of indices into this string describing a substring from [0] to [1]. - * [0] <= [1], [0] >= 0 and [1] <= string.length(). The third element contains the - * unadjusted start value (or nearest int). + * @param startObj Python start of slice + * @param endObj Python end of slice + * @return a 4 element array of two range-safe indices, and two original indices. */ - protected int[] translateIndices(PyObject start, PyObject end) { - int iStart, iStartUnadjusted, iEnd; - int n = getString().length(); - - // Make sure the slice end decodes to something in range - if (end == null || end == Py.None) { - iEnd = n; + protected int[] translateIndices(PyObject startObj, PyObject endObj) { + int start, end; + int n = __len__(); + int[] result = new int[4]; + + // Decode the start using slice semantics + if (startObj == null || startObj == Py.None) { + start = 0; + // result[2] = 0 already } else { - // Convert to int but limit to Integer.MIN_VALUE <= iEnd <= Integer.MAX_VALUE - iEnd = end.asIndex(null); - if (iEnd > n) { - iEnd = n; - } else if (iEnd < 0) { - iEnd = n + iEnd; - if (iEnd < 0) { - iEnd = 0; + // Convert to int but limit to Integer.MIN_VALUE <= start <= Integer.MAX_VALUE + start = startObj.asIndex(null); + if (start < 0) { + // Negative value means "from the end" + start = n + start; + } + result[2] = start; + } + + // Decode the end using slice semantics + if (endObj == null || endObj == Py.None) { + result[1] = result[3] = end = n; + } else { + // Convert to int but limit to Integer.MIN_VALUE <= end <= Integer.MAX_VALUE + end = endObj.asIndex(null); + if (end < 0) { + // Negative value means "from the end" + result[3] = end = end + n; + // Ensure end is safe for String.substring(start,end). + if (end < 0) { + end = 0; + // result[1] = 0 already + } else { + result[1] = end; + } + } else { + result[3] = end; + // Ensure end is safe for String.substring(start,end). + if (end > n) { + result[1] = end = n; + } else { + result[1] = end; } } } - // Make sure the slice start decodes to something in range - if (start == null || start == Py.None) { - iStartUnadjusted = iStart = 0; + // Ensure start is safe for String.substring(start,end). + if (start < 0) { + start = 0; + // result[0] = 0 already + } else if (start > end) { + result[0] = start = end; } else { - // Convert to int but limit to Integer.MIN_VALUE <= iStart <= Integer.MAX_VALUE - iStartUnadjusted = iStart = start.asIndex(null); - if (iStart > iEnd) { - iStart = iEnd; - } else if (iStart < 0) { - iStart = n + iStart; - if (iStart > iEnd) { - iStart = iEnd; - } else if (iStart < 0) { - iStart = 0; - } - } + result[0] = start; } - return new int[] {iStart, iEnd, iStartUnadjusted}; + return result; } /** @@ -3847,7 +3909,8 @@ * @param keywords naming the keyword arguments. * @return the object designated or null. */ - private PyObject getFieldObject(String fieldName, boolean bytes, PyObject[] args, String[] keywords) { + private PyObject getFieldObject(String fieldName, boolean bytes, PyObject[] args, + String[] keywords) { FieldNameIterator iterator = new FieldNameIterator(fieldName, bytes); PyObject head = iterator.pyHead(); PyObject obj = null; diff --git a/src/org/python/core/PyUnicode.java b/src/org/python/core/PyUnicode.java --- a/src/org/python/core/PyUnicode.java +++ b/src/org/python/core/PyUnicode.java @@ -22,31 +22,44 @@ @ExposedType(name = "unicode", base = PyBaseString.class, doc = BuiltinDocs.unicode_doc) public class PyUnicode extends PyString implements Iterable { - private enum Plane { + /** + * Nearly every significant method comes in two versions: one applicable when the string + * contains only basic plane characters, and one that is correct when supplementary characters + * are also present. Set this constant true to treat all strings as containing + * supplementary characters, so that these versions will be exercised in tests. + */ + private static final boolean DEBUG_NON_BMP_METHODS = false; - UNKNOWN, BASIC, ASTRAL - } - - private volatile Plane plane = Plane.UNKNOWN; - private volatile int codePointCount = -1; public static final PyType TYPE = PyType.fromClass(PyUnicode.class); // for PyJavaClass.init() public PyUnicode() { - this(TYPE, ""); + this(TYPE, "", true); } + /** + * Construct a PyUnicode interpreting the Java String argument as UTF-16. + * + * @param string UTF-16 string encoding the characters (as Java). + */ public PyUnicode(String string) { - this(TYPE, string); + this(TYPE, string, false); } + /** + * Construct a PyUnicode interpreting the Java String argument as UTF-16. If it is known that + * the string contains no supplementary characters, argument isBasic may be set true by the + * caller. If it is false, the PyUnicode will scan the string to find out. + * + * @param string UTF-16 string encoding the characters (as Java). + * @param isBasic true if it is known that only BMP characters are present. + */ public PyUnicode(String string, boolean isBasic) { - this(TYPE, string); - plane = isBasic ? Plane.BASIC : Plane.UNKNOWN; + this(TYPE, string, isBasic); } public PyUnicode(PyType subtype, String string) { - super(subtype, string); + this(subtype, string, false); } public PyUnicode(PyString pystring) { @@ -54,12 +67,13 @@ } public PyUnicode(PyType subtype, PyString pystring) { - this(subtype, pystring instanceof PyUnicode ? pystring.string : pystring.decode() - .toString()); + this(subtype, // + pystring instanceof PyUnicode ? pystring.string : pystring.decode().toString(), // + pystring.isBasicPlane()); } public PyUnicode(char c) { - this(TYPE, String.valueOf(c)); + this(TYPE, String.valueOf(c), true); } public PyUnicode(int codepoint) { @@ -90,6 +104,20 @@ this(ucs4.iterator()); } + /** + * Fundamental all-features constructor on which the others depend. If it is known that the + * string contains no supplementary characters, argument isBasic may be set true by the caller. + * If it is false, the PyUnicode will scan the string to find out. + * + * @param subtype actual type to create. + * @param string UTF-16 string encoding the characters (as Java). + * @param isBasic true if it is known that only BMP characters are present. + */ + private PyUnicode(PyType subtype, String string, boolean isBasic) { + super(subtype, string); + translator = isBasic ? BASIC : this.chooseIndexTranslator(); + } + @Override public int[] toCodePoints() { int n = getCodePointCount(); @@ -101,15 +129,428 @@ return codePoints; } - // modified to know something about codepoints; we just need to return the - // corresponding substring; darn UTF16! - // TODO: we could avoid doing this unnecessary copy + // ------------------------------------------------------------------------------------------ + // Index translation for Unicode beyond the BMP + // ------------------------------------------------------------------------------------------ + + /** + * Index translation between code point index (as seen by Python) and UTF-16 index (as used in + * the Java String. + */ + private interface IndexTranslator { + + /** Number of supplementary characters (hence point code length may be found). */ + public int suppCount(); + + /** Translate a UTF-16 code unit index to its equivalent code point index. */ + public int codePointIndex(int utf16Index); + + /** Translate a code point index to its equivalent UTF-16 code unit index. */ + public int utf16Index(int codePointIndex); + } + + /** + * The instance of index translation in use in this string. It will be set to either + * {@link #BASIC} or and instance of {@link #Supplementary}. + */ + private final IndexTranslator translator; + + /** + * A singleton provides the translation service (which is a pass-through) for all BMP strings. + */ + static final IndexTranslator BASIC = new IndexTranslator() { + + @Override + public int suppCount() { + return 0; + } + + @Override + public int codePointIndex(int u) { + return u; + } + + @Override + public int utf16Index(int i) { + return i; + } + }; + + /** + * A class of index translation that uses the cumulative count so far of supplementary + * characters, tabulated in blocks of a standard size. The count is then used as an offset + * between the code point index and the corresponding point in the UTF-16 representation. + */ + private final class Supplementary implements IndexTranslator { + + /** Tabulates cumulative count so far of supplementary characters, by blocks of size M. */ + final int[] count; + + /** Configure the block size M, as this power of 2. */ + static final int LOG2M = 4; + /** The block size used for indexing (power of 2). */ + static final int M = 1 << LOG2M; + /** A mask used to separate the block number and offset in the block. */ + static final int MASK = M - 1; + + /** + * The constructor works on a count array prepared by + * {@link PyUnicode#getSupplementaryCounts(String)}. + */ + Supplementary(int[] count) { + this.count = count; + } + + @Override + public int codePointIndex(int u) { + /* + * Let the desired result be j such that utf16Index(j) = u. As we have only a forward + * index of the string, we have to conduct a search. In principle, we bound j by a pair + * of values (j1,j2) such that j1<=j> LOG2M) + 1; + // The count of supplementary characters before the start of block k2 is: + int c2 = count[k2 - 1]; + /* + * Since the count array is non-decreasing, and j < k2*M, we have u-j <= count[k2-1]. + * That is, j >= k1*M, where: + */ + int k1 = Math.max(0, u - c2) >> LOG2M; + // The count of supplementary characters before the start of block k1 is: + int c1 = (k1 == 0) ? 0 : count[k1 - 1]; + + /* + * Now, j (to be found) is in an unknown block k, where k1<=k u) { + // k*M+c > u therefore j is not in block k but to its left. + k2 = k; + c2 = c; + } else { + // k*M+c <= u therefore j must be in block k, or to its right. + k1 = k; + c1 = c; + } + } + } + + /* + * At this point, j is known to be in block k1 (and k2=k1+1). c1 is the number of + * supplementary characters to the left of code point index k1*M and c2 is the number of + * supplementary characters to the left of code point index (k1+1)*M. We have to search + * this block sequentially. The current position in the UTF-16 is: + */ + int p = (k1 << LOG2M) + c1; + while (p < u) { + if (Character.isHighSurrogate(string.charAt(p++))) { + // c1 tracks the number of supplementary characters to the left of p + c1 += 1; + if (c1 == c2) { + // We have found all supplementary characters in the block. + break; + } + // Skip the trailing surrogate. + p++; + } + } + // c1 is the number of supplementary characters to the left of u, so the result j is: + return u - c1; + } + + @Override + public int utf16Index(int i) { + // The code point index i lies in the k-th block where: + int k = i >> LOG2M; + // The offset for the code point index k*M is exactly + int d = (k == 0) ? 0 : count[k - 1]; + // The offset for the code point index (k+1)*M is exactly + int e = count[k]; + if (d == e) { + /* + * The offset for the code point index (k+1)*M is the same, and since this is a + * non-decreasing function of k, it is also the value for i. + */ + return i + d; + } else { + /* + * The offset for the code point index (k+1)*M is different (higher). We must scan + * along until we have found all the supplementary characters that precede i, + * starting the scan at code point index k*M. + */ + for (int q = i & ~MASK; q < i; q++) { + if (Character.isHighSurrogate(string.charAt(q + d))) { + d += 1; + if (d == e) { + /* + * We have found all the supplementary characters in this block, so we + * must have found all those to the left of i. + */ + break; + } + } + } + + // d counts all the supplementary characters to the left of i. + return i + d; + } + } + + @Override + public int suppCount() { + // The last element of the count array is the total number of supplementary characters. + return count[count.length - 1]; + } + } + + /** + * Generate the table that is used by the class {@link Supplementary} to accelerate access to + * the the implementation string. The method returns null if the string passed + * contains no surrogate pairs, in which case we'll use {@link #BASIC} as the translator. This + * method is sensitive to {@link #DEBUG_NON_BMP_METHODS} which if true will prevent it returning + * null, hance we will always use a {@link Supplementary} {@link #translator}. + * + * @param string to index + * @return the index (counts) or null if basic plane + */ + private static int[] getSupplementaryCounts(final String string) { + + final int n = string.length(); + int p; // Index of the current UTF-16 code unit. + + /* + * We scan to the first surrogate code unit, in a simple loop. If we hit the end before we + * find one, no count array will be necessary and we'll use BASIC. If we find a surrogate it + * may be half a supplementary character, or a lone surrogate: we'll find out later. + */ + for (p = 0; p < n; p++) { + if (Character.isSurrogate(string.charAt(p))) { + break; + } + } + + if (p == n && !DEBUG_NON_BMP_METHODS) { + // There are no supplementary characters so the 1:1 translator is fine. + return null; + + } else { + /* + * We have to do this properly, using a scheme in which code point indexes are + * efficiently translatable to UTF-16 indexes through a table called here count[]. In + * this array, count[k] contains the total number of supplementary characters up to the + * end of the k.th block, that is, to the left of code point (k+1)M. We have to fill + * this array by scanning the string. + */ + int q = p; // The current code point index (q = p+s). + int k = q >> Supplementary.LOG2M; // The block number k = q/M. + + /* + * When addressing with a code point index q<=L (the length in code points) we will + * index the count array with k = q/M. We have q<=L<=n, therefore q/M <= n/M, the + * maximum valid k is 1 + n/M. A q>=L should raise IndexOutOfBoundsException, but it + * doesn't matter whether that's from indexing this array, or the string later. + */ + int[] count = new int[1 + (n >> Supplementary.LOG2M)]; + + /* + * To get the generation of count[] going efficiently, we need to advance the next whole + * block. The next loop will complete processing of the block containing the first + * supplementary character. Note that in all these loops, if we exit because p reaches a + * limit, the count for the last partial block is known from p-q and we take care of + * that right at the end of this method. The limit of these loops is n-1, so if we spot + * a lead surrogate, the we may access the low-surrogate confident that p+1p we find a lead surrogate without a trailing one + * following, or a trailing surrogate directly. It should not be called on the final code unit, + * when p==string.length()-1, since it may check the next code unit as well. + * + * @param string of UTF-16 code units + * @param p index into that string + * @return 2 if a surrogate pair stands at p, 1 if not + * @throws PyException(ValueError) if a lone surrogate stands at p. + */ + private static int calcAdvance(String string, int p) throws PyException { + + // Catch supplementary characters and lone surrogate code units. + char c = string.charAt(p); + + if (c >= Character.MIN_SURROGATE) { + if (c < Character.MIN_LOW_SURROGATE) { + // This is a lead surrogate. + if (Character.isLowSurrogate(string.charAt(p + 1))) { + // Required trailing surrogate follows, so step over both. + return 2; + } else { + // Required trailing surrogate missing. + throw unpairedSurrogate(p, c); + } + + } else if (c <= Character.MAX_SURROGATE) { + // This is a lone trailing surrogate + throw unpairedSurrogate(p, c); + + } // else this is a private use or special character in 0xE000 to 0xFFFF. + + } + return 1; + } + + /** + * Return a ready-to-throw exception indicating an unpaired surrogate. + * + * @param p index within that sequence of the problematic code unit + * @param c the code unit + * @return an exception + */ + private static PyException unpairedSurrogate(int p, int c) { + String fmt = "unpaired surrogate %#4x at code unit %d"; + String msg = String.format(fmt, c, p); + return Py.ValueError(msg); + } + + /** + * Choose an {@link IndexTranslator} implementation for efficient working, according to the + * contents of the {@link PyString#string}. + * + * @return chosen IndexTranslator + */ + private IndexTranslator chooseIndexTranslator() { + int[] count = getSupplementaryCounts(string); + if (DEBUG_NON_BMP_METHODS) { + return new Supplementary(count); + } else { + return count == null ? BASIC : new Supplementary(count); + } + } + + /** + * {@inheritDoc} + *

    + * In the PyUnicode version, the arguments are code point indices, such as are + * received from the Python caller, while the first two elements of the returned array have been + * translated to UTF-16 indices in the implementation string. + */ + @Override + protected int[] translateIndices(PyObject start, PyObject end) { + int[] indices = super.translateIndices(start, end); + indices[0] = translator.utf16Index(indices[0]); + indices[1] = translator.utf16Index(indices[1]); + // indices[2] and [3] remain Unicode indices (and may be out of bounds) relative to len() + return indices; + } + + // ------------------------------------------------------------------------------------------ + + /** + * {@inheritDoc} The indices are code point indices, not UTF-16 (char) indices. For + * example: + * + *

    +     * PyUnicode u = new PyUnicode("..\ud800\udc02\ud800\udc03...");
    +     * // (Python) u = u'..\U00010002\U00010003...'
    +     *
    +     * String s = u.substring(2, 4);  // = "\ud800\udc02\ud800\udc03" (Java)
    +     * 
    + */ @Override public String substring(int start, int end) { - if (isBasicPlane()) { - return super.substring(start, end); - } - return new PyUnicode(newSubsequenceIterator(start, end, 1)).getString(); + return super.substring(translator.utf16Index(start), translator.utf16Index(end)); } /** @@ -122,29 +563,18 @@ return uni; } + /** + * {@inheritDoc} + * + * @return true if the string consists only of BMP characters + */ + @Override public boolean isBasicPlane() { - if (plane == Plane.BASIC) { - return true; - } else if (plane == Plane.UNKNOWN) { - plane = (getString().length() == getCodePointCount()) ? Plane.BASIC : Plane.ASTRAL; - } - return plane == Plane.BASIC; + return translator == BASIC; } -// RETAIN THE BELOW CODE, it facilitates testing astral support more completely - -// public boolean isBasicPlane() { -// return false; -// } - -// END RETAIN - public int getCodePointCount() { - if (codePointCount >= 0) { - return codePointCount; - } - codePointCount = getString().codePointCount(0, getString().length()); - return codePointCount; + return string.length() - translator.suppCount(); } @ExposedNew @@ -193,12 +623,13 @@ return new PyUnicode(str); } - // Unicode ops consisting of basic strings can only produce basic strings; - // this may not be the case for astral ones - they also might be basic, in - // case of deletes. So optimize by providing a tainting mechanism. + /** + * @param string UTF-16 string encoding the characters (as Java). + * @param isBasic true if it is known that only BMP characters are present. + */ @Override - protected PyString createInstance(String str, boolean isBasic) { - return new PyUnicode(str, isBasic); + protected PyString createInstance(String string, boolean isBasic) { + return new PyUnicode(string, isBasic); } @Override @@ -295,37 +726,19 @@ @Override protected PyObject pyget(int i) { - if (isBasicPlane()) { - return Py.makeCharacter(getString().charAt(i), true); - } - - int k = 0; - while (i > 0) { - int W1 = getString().charAt(k); - if (W1 >= 0xD800 && W1 < 0xDC00) { - k += 2; - } else { - k += 1; - } - i--; - } - int codepoint = getString().codePointAt(k); + int codepoint = getString().codePointAt(translator.utf16Index(i)); return Py.makeCharacter(codepoint, true); } private class SubsequenceIteratorImpl implements Iterator { - private int current, k, start, stop, step; + private int current, k, stop, step; SubsequenceIteratorImpl(int start, int stop, int step) { - k = 0; current = start; - this.start = start; + k = translator.utf16Index(current); this.stop = stop; this.step = step; - for (int i = 0; i < start; i++) { - nextCodePoint(); - } } SubsequenceIteratorImpl() { @@ -443,10 +856,12 @@ private PyUnicode coerceToUnicode(PyObject o) { if (o instanceof PyUnicode) { return (PyUnicode)o; + } else if (o instanceof PyString) { + return new PyUnicode(((PyString)o).getString(), true); } else if (o instanceof BufferProtocol) { - // PyString or PyByteArray, PyMemoryView, Py2kBuffer ... + // PyByteArray, PyMemoryView, Py2kBuffer ... try (PyBuffer buf = ((BufferProtocol)o).getBuffer(PyBUF.FULL_RO)) { - return new PyUnicode(buf.toString()); + return new PyUnicode(buf.toString(), true); } } else { // o is some type not allowed: @@ -998,7 +1413,7 @@ @Override protected PyString fromSubstring(int begin, int end) { assert (isBasicPlane()); // can only be used on a codepath from str_ equivalents - return new PyUnicode(getString().substring(begin, end)); + return new PyUnicode(getString().substring(begin, end), true); } @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_index_doc) @@ -1021,7 +1436,7 @@ if (isBasicPlane()) { return _count(sub.getString(), start, end); } - int[] indices = translateIndices(start, end); + int[] indices = super.translateIndices(start, end); // do not convert to utf-16 indices. int count = 0; for (Iterator mainIter = newSubsequenceIterator(indices[0], indices[1], 1); mainIter .hasNext();) { @@ -1043,12 +1458,14 @@ @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_find_doc) final int unicode_find(PyObject subObj, PyObject start, PyObject end) { - return _find(coerceToUnicode(subObj).getString(), start, end); + int found = _find(coerceToUnicode(subObj).getString(), start, end); + return found < 0 ? -1 : translator.codePointIndex(found); } @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_rfind_doc) final int unicode_rfind(PyObject subObj, PyObject start, PyObject end) { - return _rfind(coerceToUnicode(subObj).getString(), start, end); + int found = _rfind(coerceToUnicode(subObj).getString(), start, end); + return found < 0 ? -1 : translator.codePointIndex(found); } private static String padding(int n, int pad) { @@ -1228,13 +1645,11 @@ @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_startswith_doc) final boolean unicode_startswith(PyObject prefix, PyObject start, PyObject end) { - // FIXME: slice indexing logic incorrect when this is ASTRAL return str_startswith(prefix, start, end); } @ExposedMethod(defaults = {"null", "null"}, doc = BuiltinDocs.unicode_endswith_doc) final boolean unicode_endswith(PyObject suffix, PyObject start, PyObject end) { - // FIXME: slice indexing logic incorrect when this is ASTRAL return str_endswith(suffix, start, end); } diff --git a/src/org/python/core/buffer/BaseBuffer.java b/src/org/python/core/buffer/BaseBuffer.java --- a/src/org/python/core/buffer/BaseBuffer.java +++ b/src/org/python/core/buffer/BaseBuffer.java @@ -1,5 +1,7 @@ package org.python.core.buffer; +import java.nio.ByteBuffer; + import org.python.core.BufferProtocol; import org.python.core.Py; import org.python.core.PyBUF; @@ -126,17 +128,17 @@ * Construct an instance of BaseBuffer in support of a sub-class, specifying the 'feature * flags', or at least a starting set to be adjusted later. These are the features of the buffer * exported, not the flags that form the consumer's request. The buffer will be read-only unless - * {@link PyBUF#WRITABLE} is set in the feature flags. {@link PyBUF#FORMAT} is implicitly added - * to the feature flags. The navigation arrays are all null, awaiting action by the sub-class - * constructor. To complete initialisation, the sub-class normally must assign: the buffer ( - * {@link #storage}, {@link #index0}), and the navigation arrays ({@link #shape}, - * {@link #strides}), and call {@link #checkRequestFlags(int)} passing the consumer's request - * flags. + * {@link PyBUF#WRITABLE} is set in the feature flags. {@link PyBUF#FORMAT} and + * {@link PyBUF#AS_ARRAY} are implicitly added to the feature flags. The navigation arrays are + * all null, awaiting action by the sub-class constructor. To complete initialisation, the + * sub-class normally must assign: the buffer ( {@link #storage}, {@link #index0}), and the + * navigation arrays ({@link #shape}, {@link #strides}), and call + * {@link #checkRequestFlags(int)} passing the consumer's request flags. * * @param featureFlags bit pattern that specifies the actual features allowed/required */ protected BaseBuffer(int featureFlags) { - setFeatureFlags(featureFlags | FORMAT); + setFeatureFlags(featureFlags | FORMAT | AS_ARRAY); } /** @@ -213,6 +215,12 @@ } @Override + public boolean hasArray() { + // AS_ARRAY is a non-navigational flag, so is inverted in gFeatureFlags + return (gFeatureFlags & AS_ARRAY) != 0; + } + + @Override public int getNdim() { return shape.length; } @@ -297,7 +305,7 @@ * accessors. The default implementation here is suited to N-dimensional arrays. * * @param indices of the item from the consumer - * @return index relative to item x[0,...,0] in actual storage + * @return corresponding absolute index in storage */ protected int calcIndex(int... indices) throws IndexOutOfBoundsException { final int N = checkDimension(indices); @@ -313,6 +321,57 @@ } /** + * Calculate the absolute byte index in the storage array of the last item of the exported data + * (if we are not using indirection). This is the greatest value attained by + * {@link #calcIndex(int...)}. The first byte not used will be one itemsize more + * than the returned value. + * + * @return greatest absolute index in storage + */ + protected int calcGreatestIndex() throws IndexOutOfBoundsException { + final int N = shape.length; + // If all the strides are positive, the maximal value is found from: + // index = index0 + sum(k=0,N-1) (shape[k]-1)*strides[k] + // but in general, for any k where strides[k]<=0, the term should be zero. + int index = index0; + if (N > 0) { + int[] strides = getStrides(); + for (int k = 0; k < N; k++) { + int stride = strides[k]; + if (stride > 0) { + index += (shape[k] - 1) * stride; + } + } + } + return index; + } + + /** + * Calculate the absolute byte index in the storage array of the first item of the exported data + * (if we are not using indirection). This is the least value attained by + * {@link #calcIndex(int...)}. + * + * @return least absolute index in storage + */ + protected int calcLeastIndex() throws IndexOutOfBoundsException { + final int N = shape.length; + // If all the strides are positive, the maximal value is just index0, + // but in general, we must allow strides[k]<=0 for some k: + // index = index0 + sum(k=0,N-1) (strides[k]<0) ? (shape[k]-1)*strides[k] : 0 + int index = index0; + if (N > 0) { + int[] strides = getStrides(); + for (int k = 0; k < N; k++) { + int stride = strides[k]; + if (stride < 0) { + index += (shape[k] - 1) * stride; + } + } + } + return index; + } + + /** * {@inheritDoc} *

    * The default implementation in BaseBuffer deals with the general one-dimensional @@ -540,6 +599,15 @@ // @Override public PyBuffer getBufferSlice(int flags, int start, int length, int stride) {} @Override + public ByteBuffer getNIOByteBuffer() { + // Determine the limit of the buffer just beyond the last item. + int length = calcGreatestIndex() + getItemsize() - index0; + ByteBuffer b = ByteBuffer.wrap(storage, index0, length); + // Return as read-only if it is. + return isReadonly() ? b.asReadOnlyBuffer() : b; + } + + @Override public Pointer getBuf() { return new Pointer(storage, index0); } @@ -664,6 +732,8 @@ return bufferRequires("shape array"); } else if ((syndrome & WRITABLE) != 0) { return bufferIsNot("writable"); + } else if ((syndrome & AS_ARRAY) != 0) { + return bufferIsNot("accessible as a Java array"); } else if ((syndrome & C_CONTIGUOUS) != 0) { return bufferIsNot("C-contiguous"); } else if ((syndrome & F_CONTIGUOUS) != 0) { diff --git a/src/org/python/core/buffer/SimpleBuffer.java b/src/org/python/core/buffer/SimpleBuffer.java --- a/src/org/python/core/buffer/SimpleBuffer.java +++ b/src/org/python/core/buffer/SimpleBuffer.java @@ -1,5 +1,7 @@ package org.python.core.buffer; +import java.nio.ByteBuffer; + import org.python.core.PyBuffer; import org.python.core.PyException; import org.python.core.util.StringUtil; @@ -229,6 +231,13 @@ } @Override + public ByteBuffer getNIOByteBuffer() { + // Simplify for one-dimensional contiguous bytes + ByteBuffer b = ByteBuffer.wrap(storage, index0, shape[0]); + return isReadonly() ? b.asReadOnlyBuffer() : b; + } + + @Override public Pointer getPointer(int index) throws IndexOutOfBoundsException { return new Pointer(storage, index0 + index); } diff --git a/src/org/python/core/buffer/SimpleStringBuffer.java b/src/org/python/core/buffer/SimpleStringBuffer.java --- a/src/org/python/core/buffer/SimpleStringBuffer.java +++ b/src/org/python/core/buffer/SimpleStringBuffer.java @@ -1,5 +1,7 @@ package org.python.core.buffer; +import java.nio.ByteBuffer; + import org.python.core.PyBuffer; import org.python.core.util.StringUtil; @@ -112,12 +114,19 @@ return getBufferSlice(flags, start, length); } else { // Force creation of the actual byte array from the String. - getBuf(); + ensureHaveBytes(); // Now we are effectively a SimpleBuffer, return the strided view. return super.getBufferSlice(flags, start, length, stride); } } + @Override + public ByteBuffer getNIOByteBuffer() { + // Force creation of the actual byte array from the String. + ensureHaveBytes(); + return super.getNIOByteBuffer().asReadOnlyBuffer(); + } + /** * This method creates an actual byte array from the underlying String if none yet exists. */ diff --git a/src/org/python/modules/_io/PyFileIO.java b/src/org/python/modules/_io/PyFileIO.java --- a/src/org/python/modules/_io/PyFileIO.java +++ b/src/org/python/modules/_io/PyFileIO.java @@ -251,8 +251,7 @@ PyBuffer pybuf = writablePyBuffer(buf); try { - PyBuffer.Pointer bp = pybuf.getBuf(); - ByteBuffer byteBuffer = ByteBuffer.wrap(bp.storage, bp.offset, pybuf.getLen()); + ByteBuffer byteBuffer = pybuf.getNIOByteBuffer(); synchronized (ioDelegate) { count = ioDelegate.readinto(byteBuffer); } @@ -293,8 +292,7 @@ try { // Access the data as a java.nio.ByteBuffer [pos:limit] within possibly larger array - PyBuffer.Pointer bp = pybuf.getBuf(); - ByteBuffer byteBuffer = ByteBuffer.wrap(bp.storage, bp.offset, pybuf.getLen()); + ByteBuffer byteBuffer = pybuf.getNIOByteBuffer(); synchronized (ioDelegate) { count = ioDelegate.write(byteBuffer); } diff --git a/src/org/python/modules/posix/PosixModule.java b/src/org/python/modules/posix/PosixModule.java --- a/src/org/python/modules/posix/PosixModule.java +++ b/src/org/python/modules/posix/PosixModule.java @@ -29,7 +29,6 @@ import org.python.core.Py; import org.python.core.PyBUF; import org.python.core.PyBuffer; -import org.python.core.PyBuffer.Pointer; import org.python.core.PyBuiltinFunctionNarrow; import org.python.core.PyDictionary; import org.python.core.PyException; @@ -826,10 +825,8 @@ public static int write(PyObject fd, BufferProtocol bytes) { // Get a buffer view: we can cope with N-dimensional data, but not strided data. try (PyBuffer buf = bytes.getBuffer(PyBUF.ND)) { - // Get the array and offset of the first real byte. - Pointer p = buf.getBuf(); - // Make a ByteBuffer of that array, setting the position and limit to the real data. - ByteBuffer bb = ByteBuffer.wrap(p.storage, p.offset, buf.getLen()); + // Get a ByteBuffer of that data, setting the position and limit to the real data. + ByteBuffer bb = buf.getNIOByteBuffer(); try { // Write the data (returning the count of bytes). return FileDescriptors.get(fd).write(bb); @@ -902,7 +899,7 @@ } /** - * Return a path as a String from a PyObject + * Return a path as a String from a PyObject * * @param path a PyObject, raising a TypeError if an invalid path type * @return a String path diff --git a/tests/java/javatests/ProxyDeserialization.java b/tests/java/ProxyDeserialization.java rename from tests/java/javatests/ProxyDeserialization.java rename to tests/java/ProxyDeserialization.java diff --git a/tests/python/unicode_index_times.py b/tests/python/unicode_index_times.py new file mode 100644 --- /dev/null +++ b/tests/python/unicode_index_times.py @@ -0,0 +1,405 @@ +# -*- coding: utf-8 -*- +# unicode speed tests for access operations and find +# This is part of an effort to supply the Jython implementation of +# unicode with efficient, correct translations between the visible index +# of a character and and the index in the implementation array of the +# UTF-16 code unit(s) that represent it. See also test.test_unicode_jy, +# and Jython issue #2100. The presence of characters with Unicode +# code points > 0xffff (supplementary characters), that it takes two +# code units to represent, makes this non-trivial. +# +# The program defines a variety of test strings of differing lengths +# and distribution of supplementary characters, then times some basic +# operations involving index translation: of retrieval, slicing and +# find, to provide an average time per operation. It runs several trials +# of each test case (a combination of an operation and the test material) +# and reports the shortest trial, using the same strategy as the timeit +# module). +# +# It was difficult to get repeatable times from the test under Jython, +# because the JIT compiler (?) is non-deterministic. It proved +# impossible using a strategy that would run the same test case multiple +# times in succession. The approach eventually taken was to run the all +# the test cases once, then repeat this sequence several times, and +# report the minimum time of each case in these widely separated trials. +# This strategy provides stable results with the default JIT behaviour. +# +# Two interesting options are to run with the # JIT compiler disabled: +# $ jython -J-Xint tests/python/unicode_index_times.py +# +# or with it continuously enabled: +# $ jython -J-Xcomp tests/python/unicode_index_times.py +# +from __future__ import print_function +import itertools +import random +import sys +import time + +if sys.platform == "win32" or sys.platform.startswith("java"): + # On Windows and Jython, the best timer is time.clock() + timer = time.clock +else: + # On most other platforms the best timer is time.time() + timer = time.time + +if sys.version_info[0] > 2: + unichr = chr +else: + def next(it) : return it.next() + +# Proportion of characters that are supplementary (if not explicit) +DEFAULT_RATE = 0.2 # 20% + +# We will test performance with these sizes +SHORT = 10 +MEDIUM = 100 +LONG = 1000 +HUGE = 10000 + + +class UnicodeMaterial(object): + ''' Object holding a list of single characters and a unicode string + that is their concatenation. The sequence is created from a + background sequence of basic plane characters and random + replacement with supplementary plane characters (those with + point code>0xffff). + ''' + + base = tuple(u'abcdefghijklmnopqrstuvwxyz') + if sys.maxunicode < 0x10000: + print("Narrow build: all characters from BMP", file=sys.stderr) + supp = tuple(map(unichr, range(0x20, 0x2c))) + else: + # Wide build: we have real supplementary characters + supp = tuple(map(unichr, range(0x10000, 0x1000c))) + used = sorted(set(base+supp)) + + def __init__(self, size=20, pred=None, ran=None): + ''' Create size chars choosing an SP char at i where + pred(ran, i)==True where ran is an instance of + random.Random supplied in the constructor or created + locally (if ran==None). + ''' + + # Generators for the BMP and SP characters + base = itertools.cycle(UnicodeMaterial.base) + supp = itertools.cycle(UnicodeMaterial.supp) + + # Each instance gets a random generator + if ran is None: + ran = random.Random() + self.random = ran + + if pred is None: + pred = lambda ran, j : ran.random() < DEFAULT_RATE + + # Generate the list + r = list() + for i in range(size): + if pred(self.random, i): + c = next(supp) + else: + c = next(base) + r.append(c) + + # The list and its concatenation are our material + self.ref = r + self.size = len(r) + self.text = u''.join(r) + self.target = u'' + + def __len__(self): + return self.size + + def insert(self, target, p=None): + ''' Insert target string at position p (or middle), truncating if + that would make the material any longer + ''' + if p is None: + p = max(0, (self.size-len(target)) // 2) + + n = 0 + for t in target: + if p+n >= self.size: + break; + self.ref[p+n] = t + n += 1 + + self.target = target[:n] + self.text = u''.join(self.ref) + + +class UnicodeActions(UnicodeMaterial): + ''' Provides test material with loops for timing.''' + + def __init__(self, size=20, pred=None, ran=None): + super(UnicodeActions, self).__init__(size, pred, ran) + if self.size <= 0: + raise ValueError("The timings don't work for zero length") + self.used = UnicodeMaterial.used + self.trash = None + # String to find (note 'abcde' in base: nice for false alarms) + self.insert(u"abide") + + + def repeat_getitem(self, mincount): + ''' Access each code point in sequence repeatedly so that at + least mincount operations have been peformed, and return the + actual number of operations. + ''' + n = self.size + t = self.text + opcount = 0 + dummy = None + while opcount < mincount: + # Access each point code + i = 0 + while i < n: + # Avoid optimising away the call + dummy = t[i] + i += 1 + opcount += n + self.trash = dummy + return opcount + + def repeat_slice(self, mincount): + ''' Extract a slice at each feasible position and length, + repeating enough times to do mincount operations, and + return the actual number of operations. + ''' + n = self.size + t = self.text + opcount = 0 + dummy = None + + while opcount < mincount: + m = 1 + while m <= n: + starts = n - m + 1 + for i in range(starts): + dummy = t[i:i+m] + #print(i, i+m, step, dummy) + opcount += starts + m *= 5 + + return opcount + + def repeat_slice_step(self, mincount): + ''' Extract a slice at each feasible position and length, + and using different sizes for the step, + repeating enough times to do mincount operations, and + return the actual number of operations. + ''' + n = self.size + t = self.text + opcount = 0 + dummy = None + steps = [3, -1, 10] + + while opcount < mincount: + for step in steps: + if step > 0: + m = 1 + while m <= n: + starts = n - m + 1 + for i in range(starts): + dummy = t[i:i+m:step] + #print(i, i+m, step, dummy) + opcount += starts + m *= 5 + else: + m = 1 + while m <= n: + starts = n - m + 1 + for i in range(starts): + dummy = t[i+m:i:step] + #print(i+m, i, step, dummy) + opcount += starts + m *= 5 + + return opcount + + def repeat_find_char(self, mincount): + ''' Do an incremental find of each code point, repeating + enough times to do mincount finds, and return the actual + number of operations. + ''' + opcount = 0 + n = self.size + findop = self.text.find + dummy = 0 + + while opcount < mincount: + # The text is searched for every code c. + for c in self.used: + # ... and every occurrence is found. + start = 0 + while start < n: + i = findop(c, start) + if i < 0: break + # Avoid optimising away the call + dummy += i + start = i + 1 + + # Every character in the text was a hit exactly once. + # And every character was also a miss, except for + # the character that ends the text. So we did: + opcount += n + len(self.used) - 1 + + self.trash = dummy + return opcount + + def repeat_find_str(self, mincount): + ''' Find the target string within the material, repeating + enough times to do mincount finds, and return the actual + number of operations. + ''' + opcount = 0 + s = self.target + findop = self.text.find + dummy = 0 + + while opcount < mincount: + dummy += findop(s) + opcount += 1 + + self.trash = dummy + return opcount + + def repeat_rfind_char(self, mincount): + ''' Do an incremental rfind of each code point, repeating + enough times to do mincount finds, and return the actual + number of operations. + ''' + opcount = 0 + n = self.size + findop = self.text.rfind + + while opcount < mincount: + # The text is searched for every code c. + for c in self.used: + # ... and every occurrence is found. + end = n + while end >= 0: + end = findop(c, 0, end) + + # Every character in the text was a hit exactly once. + # And every character was also a miss. So we did: + opcount += n + len(self.used) + + return opcount + + def repeat_rfind_str(self, mincount): + ''' Find the target string within the material, repeating + enough times to do mincount finds, and return the actual + number of operations. + ''' + opcount = 0 + s = self.target + findop = self.text.rfind + dummy = 0 + + while opcount < mincount: + dummy += findop(s) + opcount += 1 + + self.trash = dummy + return opcount + + +def time_per_op(op, mincount): + ''' Repeat the given operation at least mincount times and + return the time per operation in microseconds. + ''' + t = timer() + opcount = op(mincount) + return (timer() - t) * 1e6 / opcount + +# Functions defining particular distributions of SP codes +# +def evenly(rate=DEFAULT_RATE): + 'Evenly distributed at given rate' + def f(ran, i): + return ran.random() < rate + return f + +def evenly_before(k, rate=DEFAULT_RATE): + 'Evenly distributed on i=k at given rate' + def f(ran, i): + return i >= k and ran.random() < rate + return f + +def time_all(): + + setups = [ + #("empty", UnicodeActions(0)), + ("single bmp", UnicodeActions(1, (lambda ran, i : False))), + ("single", UnicodeActions(1, (lambda ran, i : True))), + ("short bmp", UnicodeActions(SHORT, (lambda ran, i : False))), + ("short 50%", UnicodeActions(SHORT, evenly(0.5))), + ("medium bmp", UnicodeActions(MEDIUM, (lambda ran, i : False))), + ("medium 10%", UnicodeActions(MEDIUM, evenly(0.1))), + ("long bmp", UnicodeActions(LONG, (lambda ran, i : False))), + ("long 1%", UnicodeActions(LONG, evenly(0.01))), + ("long 10%", UnicodeActions(LONG, evenly(0.1))), + ("long 10% L", UnicodeActions(LONG, evenly_before(LONG/4, 0.4))), + ("long 10% H", UnicodeActions(LONG, evenly_from(LONG-(LONG/4), 0.4))), + ("long 50%", UnicodeActions(LONG, evenly(0.5))), + ("huge bmp", UnicodeActions(HUGE, (lambda ran, i : False))), + ("huge 10%", UnicodeActions(HUGE, evenly(0.1))), + ] + + ops = [ + ("[i]", "repeat_getitem"), + ("[i:i+n]", "repeat_slice"), + ("[i:i+n:k]", "repeat_slice_step"), + ("find(c)", "repeat_find_char"), + ("find(s)", "repeat_find_str"), + ("rfind(c)", "repeat_rfind_char"), + ("rfind(s)", "repeat_rfind_str"), + ] + + + print("{:12s}{:>6s}".format("time (us)", "len"), end='') + for title, _ in ops: + print("{:>10s}".format(title), end='') + print() + + mintime = dict() + def save_mintime(k, t): + mintime[k] = min(t, mintime.get(k, 1e9)) + + trashcan = [] + + # Cycle through the cases repeatedly. + for k in range(5): + for name, material in setups: + for _, opname in ops: + # For each case, keep the minimum time + op = material.__getattribute__(opname) + t = time_per_op(op, 1000) + save_mintime((name, opname), t) + + if k == 0: + trashcan.append(material.trash) + + # Cycle through the cases again to print them. + for name, material in setups: + print("{:12s}{:6d}".format(name, material.size), end='') + for _, opname in ops: + t = mintime[(name, opname)] + print("{:10.2f}".format(t), end='') + print() + + print("y =", trashcan) + +if __name__ == "__main__": + + time_all() -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Wed Sep 17 21:32:05 2014 From: jython-checkins at python.org (jim.baker) Date: Wed, 17 Sep 2014 19:32:05 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fix_bug_in_supporting_meta_?= =?utf-8?q?path_importers_for_six=2E?= Message-ID: <20140917193154.69465.81868@mail.hg.python.org> http://hg.python.org/jython/rev/3bfd14f0b231 changeset: 7388:3bfd14f0b231 user: Werner Mendizabal date: Wed Sep 17 13:31:32 2014 -0600 summary: Fix bug in supporting meta path importers for six. files: src/org/python/core/PyModule.java | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/org/python/core/PyModule.java b/src/org/python/core/PyModule.java --- a/src/org/python/core/PyModule.java +++ b/src/org/python/core/PyModule.java @@ -86,11 +86,13 @@ return null; } PyObject path = __dict__.__finditem__("__path__"); + if (path == null) { + path = new PyList(); + } PyObject pyName = __dict__.__finditem__("__name__"); - if (path == null || pyName == null) { + if (pyName == null) { return null; } - PyObject attr = null; String fullName = (pyName.__str__().toString() + '.' + name).intern(); if (path == Py.None) { -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Tue Sep 23 00:13:16 2014 From: jython-checkins at python.org (jim.baker) Date: Mon, 22 Sep 2014 22:13:16 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fix_logic_on_when_to_shutdo?= =?utf-8?q?wn_Netty_child_workers=2E?= Message-ID: <20140922221314.112519.16854@mail.hg.python.org> https://hg.python.org/jython/rev/a33353c0ac25 changeset: 7389:a33353c0ac25 user: Jim Baker date: Mon Sep 22 16:13:01 2014 -0600 summary: Fix logic on when to shutdown Netty child workers. Do not shutdown Netty child worker group thread pool for listening server socket unless the server socket is also closed. Note that it is perfectly possible for an accepted child socket to have a lifetime past that of the listening socket (especially perhaps in tests), but the socket code was not also checking if the server socket itself was still open. This meant that subsequent incoming child connections would failed with a RejectedExecutionException error. Other socket fixes include no longer uses the root handler for socket debug logging, and allows for any object that is an Iterable for select lists. files: Lib/_socket.py | 18 +++++++++++------- Lib/test/test_socket.py | 10 ++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Lib/_socket.py b/Lib/_socket.py --- a/Lib/_socket.py +++ b/Lib/_socket.py @@ -9,7 +9,7 @@ import sys import time import _google_ipaddr_r234 -from collections import namedtuple, Sequence +from collections import namedtuple, Iterable from contextlib import contextmanager from functools import partial, wraps from itertools import chain @@ -54,7 +54,10 @@ def _debug(): FORMAT = '%(asctime)-15s %(threadName)s %(levelname)s %(funcName)s %(message)s %(sock)s' - logging.basicConfig(format=FORMAT, level=logging.DEBUG) + debug_sh = logging.StreamHandler() + debug_sh.setFormatter(logging.Formatter(FORMAT)) + log.addHandler(debug_sh) + log.setLevel(level=logging.DEBUG) # _debug() # UNCOMMENT to get logging of socket activity @@ -575,6 +578,8 @@ def initChannel(self, child_channel): child = ChildSocket(self.parent_socket) + log.debug("Initializing child %s", extra={"sock": self.parent_socket}) + child.proto = IPPROTO_TCP child._init_client_mode(child_channel) @@ -1366,8 +1371,6 @@ self._ensure_post_connect() return super(ChildSocket, self).setblocking(mode) - # FIXME FIXME FIXME other ops. - def close(self): self._ensure_post_connect() super(ChildSocket, self).close() @@ -1376,8 +1379,9 @@ if self.accepted: with self.parent_socket.open_lock: self.parent_socket.accepted_children -= 1 - if self.parent_socket.accepted_children == 0: - log.debug("Shutting down child group for parent socket=%s", self.parent_socket, extra={"sock": self}) + if self.parent_socket.open_count == 0 and self.parent_socket.accepted_children == 0: + log.debug("Shutting down child group for parent socket=%s accepted_children=%s", + self.parent_socket, self.parent_socket.accepted_children, extra={"sock": self}) self.parent_socket.child_group.shutdownGracefully(0, 100, TimeUnit.MILLISECONDS) def shutdown(self, how): @@ -1402,7 +1406,7 @@ def select(rlist, wlist, xlist, timeout=None): for lst in (rlist, wlist, xlist): - if not isinstance(lst, Sequence): + if not isinstance(lst, Iterable): raise TypeError("arguments 1-3 must be sequences") if not(timeout is None or isinstance(timeout, Number)): raise TypeError("timeout must be a float or None") diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -4,6 +4,7 @@ from test import test_support import errno +import gc import jarray import Queue import platform @@ -128,7 +129,16 @@ self.client_ready.wait() def _assert_no_pending_threads(self, group, msg): + # Ensure __del__ finalizers are called on sockets. Two things to note: + # 1. It takes two collections for finalization to run. + # 2. gc.collect() is only advisory to the JVM, never mandatory. Still + # it usually seems to happen under light load. + gc.collect() + time.sleep(0.1) + gc.collect() + # Wait up to one second for there not to be pending threads + for i in xrange(10): pending_threads = _check_threadpool_for_pending_threads(group) if len(pending_threads) == 0: -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Tue Sep 23 05:41:30 2014 From: jython-checkins at python.org (jim.baker) Date: Tue, 23 Sep 2014 03:41:30 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Rework_function_attributes_?= =?utf-8?q?support=2E?= Message-ID: <20140923034129.44104.57815@mail.hg.python.org> https://hg.python.org/jython/rev/d5df69a9fac0 changeset: 7390:d5df69a9fac0 user: Jim Baker date: Mon Sep 22 21:41:13 2014 -0600 summary: Rework function attributes support. Preferentially use (and now support) __closure__ instead of func_closure and __defaults__ instead of func_defaults. Ensure consistent support, especially being writable and deletable, for function attributes compared to CPython and unskip relevant portions in test suite. Fixes http://bugs.jython.org/issue2183 files: Lib/test/test_funcattrs.py | 10 +- src/org/python/core/ContextGuard.java | 6 +- src/org/python/core/PyClassMethod.java | 2 + src/org/python/core/PyFunction.java | 148 ++++++++--- src/org/python/core/PyMethod.java | 7 + src/org/python/core/PyStaticMethod.java | 2 + 6 files changed, 124 insertions(+), 51 deletions(-) diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -54,19 +54,18 @@ return 3 self.assertNotEqual(self.b, duplicate) - @unittest.skipIf(test_support.is_jython, "FIXME: not working in Jython") def test_copying_func_code(self): def test(): pass self.assertEqual(test(), None) test.func_code = self.b.func_code self.assertEqual(test(), 3) # self.b always returns 3, arbitrarily - @unittest.skipIf(test_support.is_jython, "FIXME: not working in Jython") def test_func_globals(self): self.assertIs(self.b.func_globals, globals()) + self.assertIs(self.b.__globals__, globals()) self.cannot_set_attr(self.b, 'func_globals', 2, TypeError) + self.cannot_set_attr(self.b, '__globals__', 2, TypeError) - @unittest.skipIf(test_support.is_jython, "FIXME: not working in Jython") def test_func_closure(self): a = 12 def f(): print a @@ -87,7 +86,6 @@ self.fail("shouldn't be able to read an empty cell") a = 12 - @unittest.skipIf(test_support.is_jython, "FIXME: not working in Jython") def test_func_name(self): self.assertEqual(self.b.__name__, 'b') self.assertEqual(self.b.func_name, 'b') @@ -110,7 +108,6 @@ self.cannot_set_attr(self.f.a, "__name__", 'a', AttributeError) self.cannot_set_attr(self.fi.a, "__name__", 'a', AttributeError) - @unittest.skipIf(test_support.is_jython, "FIXME: not working in Jython") def test_func_code(self): num_one, num_two = 7, 8 def a(): pass @@ -153,8 +150,10 @@ return a+b self.assertEqual(first_func.func_defaults, None) self.assertEqual(second_func.func_defaults, (1, 2)) + self.assertEqual(second_func.func_defaults, second_func.__defaults__) first_func.func_defaults = (1, 2) self.assertEqual(first_func.func_defaults, (1, 2)) + self.assertEqual(first_func.func_defaults, first_func.__defaults__) self.assertEqual(first_func(), 3) self.assertEqual(first_func(3), 5) self.assertEqual(first_func(3, 5), 8) @@ -338,7 +337,6 @@ class StaticMethodAttrsTest(unittest.TestCase): - @unittest.skipIf(test_support.is_jython, "FIXME: not working in Jython") def test_func_attribute(self): def f(): pass diff --git a/src/org/python/core/ContextGuard.java b/src/org/python/core/ContextGuard.java --- a/src/org/python/core/ContextGuard.java +++ b/src/org/python/core/ContextGuard.java @@ -61,11 +61,11 @@ PyBaseCode pyCode = (PyBaseCode) code; if (pyCode.co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyFunction(function.__globals__, - function.func_defaults, + function.__defaults__, new ContextCode(pyCode), function.__doc__, - (function.func_closure == null) ? null : - ((PyTuple)function.func_closure).getArray()); + (function.__closure__ == null) ? null : + ((PyTuple)function.__closure__).getArray()); } } } diff --git a/src/org/python/core/PyClassMethod.java b/src/org/python/core/PyClassMethod.java --- a/src/org/python/core/PyClassMethod.java +++ b/src/org/python/core/PyClassMethod.java @@ -1,5 +1,6 @@ package org.python.core; +import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; @@ -12,6 +13,7 @@ public static final PyType TYPE = PyType.fromClass(PyClassMethod.class); + @ExposedGet(name = "__func__") protected PyObject callable; public PyClassMethod(PyObject callable) { diff --git a/src/org/python/core/PyFunction.java b/src/org/python/core/PyFunction.java --- a/src/org/python/core/PyFunction.java +++ b/src/org/python/core/PyFunction.java @@ -22,7 +22,6 @@ /** The writable name, also available via func_name. */ @ExposedGet - @ExposedSet public String __name__; /** The writable doc string, also available via func_doc. */ @@ -38,9 +37,9 @@ * Default argument values for associated kwargs. Exposed as a * tuple to Python. Writable. */ - public PyObject[] func_defaults; + public PyObject[] __defaults__; - /** The actual funtion's code, writable. */ + /** The actual function's code, writable. */ @ExposedGet public PyCode __code__; @@ -52,7 +51,7 @@ /** A read only closure tuple for nested scopes. */ @ExposedGet - public PyObject func_closure; + public PyObject __closure__; /** Writable object describing what module this function belongs to. */ @ExposedGet @@ -66,11 +65,11 @@ __name__ = code.co_name; __doc__ = doc != null ? doc : Py.None; // XXX: workaround the compiler passing Py.EmptyObjects - // instead of null for defaults, whereas we want func_defaults + // instead of null for defaults, whereas we want __defaults__ // to be None (null) in that situation - func_defaults = (defaults != null && defaults.length == 0) ? null : defaults; + __defaults__ = (defaults != null && defaults.length == 0) ? null : defaults; __code__ = code; - func_closure = closure_cells != null ? new PyTuple(closure_cells) : null; + __closure__ = closure_cells != null ? new PyTuple(closure_cells) : null; PyObject moduleName = globals.__finditem__("__name__"); __module__ = moduleName != null ? moduleName : Py.None; } @@ -147,16 +146,32 @@ return function; } + @ExposedSet(name = "__name__") + public void setName(String func_name) { + __name__ = func_name; + } + + @ExposedDelete(name = "__name__") + public void delName() { + throw Py.TypeError("__name__ must be set to a string object"); + } + @Deprecated @ExposedGet(name = "func_name") - public PyString getFuncName() { - return new PyString(__name__); + public String getFuncName() { + return __name__; } @Deprecated @ExposedSet(name = "func_name") - public void setFuncName(PyString func_name) { - __name__ = func_name.asString(); + public void setFuncName(String func_name) { + setName(func_name); + } + + @Deprecated + @ExposedDelete(name = "func_name") + public void delFuncName() { + delName(); } @Deprecated @@ -182,25 +197,43 @@ __doc__ = Py.None; } - @ExposedGet(name = "func_defaults") - public PyObject getFuncDefaults() { - if (func_defaults == null) { + @ExposedGet(name = "__defaults__") + public PyObject getDefaults() { + if (__defaults__ == null) { return Py.None; } - return new PyTuple(func_defaults); + return new PyTuple(__defaults__); } - @ExposedSet(name = "func_defaults") - public void setFuncDefaults(PyObject func_defaults) { + @ExposedSet(name = "__defaults__") + public void setDefaults(PyObject func_defaults) { if (func_defaults != Py.None && !(func_defaults instanceof PyTuple)) { throw Py.TypeError("func_defaults must be set to a tuple object"); } - this.func_defaults = func_defaults == Py.None ? null : ((PyTuple)func_defaults).getArray(); + this.__defaults__ = func_defaults == Py.None ? null : ((PyTuple)func_defaults).getArray(); } + @ExposedDelete(name = "__defaults__") + public void delDefaults() { + __defaults__ = null; + } + + @Deprecated + @ExposedGet(name = "func_defaults") + public PyObject getFuncDefaults() { + return getDefaults(); + } + + @Deprecated + @ExposedSet(name = "func_defaults") + public void setFuncDefaults(PyObject func_defaults) { + setDefaults(func_defaults); + } + + @Deprecated @ExposedDelete(name = "func_defaults") - public void delFuncDefaults() { - func_defaults = null; + public void delFuncDefaults( ) { + delDefaults(); } @Deprecated @@ -212,7 +245,7 @@ @Deprecated @ExposedSet(name = "func_code") public void setFuncCode(PyCode code) { - setFuncCode(code); + setCode(code); } @ExposedSet(name = "__code__") @@ -222,7 +255,7 @@ } PyBaseCode tcode = (PyBaseCode)code; int nfree = tcode.co_freevars == null ? 0 : tcode.co_freevars.length; - int nclosure = func_closure != null ? func_closure.__len__() : 0; + int nclosure = __closure__ != null ? __closure__.__len__() : 0; if (nclosure != nfree) { throw Py.ValueError(String.format("%s() requires a code object with %d free vars," + " not %d", __name__, nclosure, nfree)); @@ -259,45 +292,78 @@ throw Py.TypeError("function's dictionary may not be deleted"); } + @Deprecated @ExposedGet(name = "func_dict") public PyObject getFuncDict() { return getDict(); } + @Deprecated @ExposedSet(name = "func_dict") public void setFuncDict(PyObject value) { setDict(value); } + @Deprecated @ExposedDelete(name = "func_dict") public void delFuncDict() { delDict(); } + @ExposedSet(name = "__globals__") + public void setGlobals(PyObject value) { + throw Py.TypeError("readonly attribute"); + } + + @ExposedDelete(name = "__globals__") + public void delGlobals() { + throw Py.TypeError("readonly attribute"); + } + + @Deprecated @ExposedGet(name = "func_globals") public PyObject getFuncGlobals() { return __globals__; } - @ExposedSet(name = "__globals__") - public void setGlobals(PyObject value) { - // __setattr__ would set __dict__['func_globals'] = value - // without this method + @Deprecated + @ExposedSet(name = "func_globals") + public void setFuncGlobals(PyObject value) { + setGlobals(value); + } + + @Deprecated + @ExposedDelete(name = "func_globals") + public void delFuncGlobals() { + delGlobals(); + } + + @ExposedSet(name = "__closure__") + public void setClosure(PyObject value) { throw Py.TypeError("readonly attribute"); } - - @ExposedSet(name = "func_globals") - public void setFuncGlobals(PyObject value) { - // __setattr__ would set __dict__['func_globals'] = value - // without this method + @ExposedDelete(name = "__closure__") + public void delClosure() { throw Py.TypeError("readonly attribute"); } + @Deprecated + @ExposedGet(name = "func_closure") + public PyObject getFuncClosure() { + return __closure__; + } + + @Deprecated @ExposedSet(name = "func_closure") public void setFuncClosure(PyObject value) { - // same idea as setFuncGlobals - throw Py.TypeError("readonly attribute"); + setClosure(value); + } + + @Deprecated + @ExposedDelete(name = "func_closure") + public void delFuncClosure() { + delClosure(); } private void ensureDict() { @@ -334,7 +400,7 @@ @Override public PyObject __call__(ThreadState state) { - return __code__.call(state, __globals__, func_defaults, func_closure); + return __code__.call(state, __globals__, __defaults__, __closure__); } @Override @@ -344,7 +410,7 @@ @Override public PyObject __call__(ThreadState state, PyObject arg0) { - return __code__.call(state, arg0, __globals__, func_defaults, func_closure); + return __code__.call(state, arg0, __globals__, __defaults__, __closure__); } @Override @@ -354,7 +420,7 @@ @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1) { - return __code__.call(state, arg0, arg1, __globals__, func_defaults, func_closure); + return __code__.call(state, arg0, arg1, __globals__, __defaults__, __closure__); } @Override @@ -365,7 +431,7 @@ @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2) { - return __code__.call(state, arg0, arg1, arg2, __globals__, func_defaults, func_closure); + return __code__.call(state, arg0, arg1, arg2, __globals__, __defaults__, __closure__); } @Override @@ -377,8 +443,7 @@ @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) { - return __code__.call(state, arg0, arg1, arg2, arg3, __globals__, func_defaults, - func_closure); + return __code__.call(state, arg0, arg1, arg2, arg3, __globals__, __defaults__, __closure__); } @Override @@ -403,7 +468,7 @@ @ExposedMethod(doc = BuiltinDocs.function___call___doc) final PyObject function___call__(ThreadState state, PyObject[] args, String[] keywords) { - return __code__.call(state, args, keywords, __globals__, func_defaults, func_closure); + return __code__.call(state, args, keywords, __globals__, __defaults__, __closure__); } @Override @@ -414,8 +479,7 @@ @Override public PyObject __call__(ThreadState state, PyObject arg1, PyObject[] args, String[] keywords) { - return __code__.call(state, arg1, args, keywords, __globals__, func_defaults, - func_closure); + return __code__.call(state, arg1, args, keywords, __globals__, __defaults__, __closure__); } @Override diff --git a/src/org/python/core/PyMethod.java b/src/org/python/core/PyMethod.java --- a/src/org/python/core/PyMethod.java +++ b/src/org/python/core/PyMethod.java @@ -4,6 +4,7 @@ import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; +import org.python.expose.ExposedSet; import org.python.expose.ExposedType; import org.python.expose.MethodType; @@ -302,6 +303,12 @@ return __func__.__getattr__("__doc__"); } + // FIXME this should work, but it has a dependency on our descriptor mechanism! +// @ExposedSet(name = "__doc__") +// public void setDoc() { +// throw Py.AttributeError("attribute '__doc__' of 'instancemethod' objects is not writable"); +// } + @Override public String toString() { String className = "?"; diff --git a/src/org/python/core/PyStaticMethod.java b/src/org/python/core/PyStaticMethod.java --- a/src/org/python/core/PyStaticMethod.java +++ b/src/org/python/core/PyStaticMethod.java @@ -1,5 +1,6 @@ package org.python.core; +import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; @@ -12,6 +13,7 @@ public static final PyType TYPE = PyType.fromClass(PyStaticMethod.class); + @ExposedGet(name = "__func__") protected PyObject callable; public PyStaticMethod(PyObject callable) { -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Wed Sep 24 02:00:24 2014 From: jython-checkins at python.org (jim.baker) Date: Wed, 24 Sep 2014 00:00:24 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Allow_bound_methods_as_arg_?= =?utf-8?q?for_single_method_interface_param=2E?= Message-ID: <20140924000018.69841.78721@mail.hg.python.org> https://hg.python.org/jython/rev/0e4c6e7d2273 changeset: 7391:0e4c6e7d2273 user: Jim Baker date: Tue Sep 23 18:00:10 2014 -0600 summary: Allow bound methods as arg for single method interface param. Java widely uses single method interfaces (such as Callable or Runnable) as parameters for methods, such as setting up a callback. Jython since 2.5 has supported passing Python functions as such arguments, which avoids having to define a class extending the single method interface. This change allows bound methods to be used in a similar fashion, by using PyMethod#__tojava__. Note that any callable object should have this behavior, since there is no possibility of ambiguity; however, this change did not add such support for __call__ since it seems to be a bit more complex in how it interacts with class derivation. But a test, currently skipped, as been added for such future support. Partial fix of http://bugs.jython.org/issue2115 files: Lib/_socket.py | 11 +-- Lib/test/test_java_integration.py | 63 ++++++++++++++++++- src/org/python/core/PyMethod.java | 59 +++++++++++++++++- 3 files changed, 122 insertions(+), 11 deletions(-) diff --git a/Lib/_socket.py b/Lib/_socket.py --- a/Lib/_socket.py +++ b/Lib/_socket.py @@ -742,14 +742,7 @@ # is managed by this method. # # All sockets can be selected on, regardless of blocking/nonblocking state. - - def workaround_jython_bug_for_bound_methods(_): - # FIXME check for errors, notify the corresponding socket accordingly - # FIXME wrapper function is needed because of http://bugs.jython.org/issue2115 - self._notify_selectors() - - future.addListener(workaround_jython_bug_for_bound_methods) - + future.addListener(self._notify_selectors) if self.timeout is None: log.debug("Syncing on future %s for %s", future, reason, extra={"sock": self}) return future.sync() @@ -1194,7 +1187,7 @@ else: return _socktuple(self.bind_addr) # Netty 4 currently races between bind to ephemeral port and the availability - # of the local address for the channel. Workaround for now is to poll. + # of the local address for the channel. Poll to work around this issue. while True: local_addr = self.channel.localAddress() if local_addr: diff --git a/Lib/test/test_java_integration.py b/Lib/test/test_java_integration.py --- a/Lib/test/test_java_integration.py +++ b/Lib/test/test_java_integration.py @@ -22,6 +22,7 @@ FileNotFoundException, FileOutputStream, FileWriter, ObjectInputStream, ObjectOutputStream, OutputStreamWriter, UnsupportedEncodingException) from java.util import ArrayList, Date, HashMap, Hashtable, StringTokenizer, Vector +from java.util.concurrent import Executors from java.awt import Dimension, Color, Component, Container from java.awt.event import ComponentEvent @@ -833,6 +834,65 @@ self.assertEqual(target.attribute, value) +class WrappedUp(object): + def __init__(self): + self.data = list() + def doit(self): + self.data.append(42) + + +class CallableObject(object): + def __init__(self): + self.data = list() + def __call__(self): + self.data.append(42) + + +class SingleMethodInterfaceTest(unittest.TestCase): + + def setUp(self): + self.executor = Executors.newSingleThreadExecutor() + + def tearDown(self): + self.executor.shutdown() + + def test_function(self): + x = list() + def f(): + x.append(42) + future = self.executor.submit(f) + future.get() + self.assertEqual(x, [42]) + + @unittest.skip("FIXME: not working") + def test_callable_object(self): + callable_obj = CallableObject() + future = self.executor.submit(callable_obj) + future.get() + self.assertEqual(callable_obj.data, [42]) + + def test_bound_method(self): + obj = WrappedUp() + future = self.executor.submit(obj.doit) + future.get() + self.assertEqual(obj.data, [42]) + + def test_unbound_method(self): + with self.assertRaises(TypeError) as exc: + future = self.executor.submit(WrappedUp.doit) # not a bound method + self.assertIsInstance( + exc.exception, TypeError, + "submit(): 1st arg can't be coerced to java.util.concurrent.Callable, java.lang.Runnable") + + def test_some_noncallable_object(self): + obj = WrappedUp() + with self.assertRaises(TypeError) as exc: + future = self.executor.submit(obj) + self.assertIsInstance( + exc.exception, TypeError, + "submit(): 1st arg can't be coerced to java.util.concurrent.Callable, java.lang.Runnable") + + def test_main(): test_support.run_unittest( BeanPropertyTest, @@ -852,7 +912,8 @@ SerializationTest, SysIntegrationTest, TreePathTest, - UnicodeTest) + UnicodeTest, + SingleMethodInterfaceTest) if __name__ == "__main__": test_main() diff --git a/src/org/python/core/PyMethod.java b/src/org/python/core/PyMethod.java --- a/src/org/python/core/PyMethod.java +++ b/src/org/python/core/PyMethod.java @@ -8,11 +8,15 @@ import org.python.expose.ExposedType; import org.python.expose.MethodType; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + /** * A Python method. */ @ExposedType(name = "instancemethod", isBaseType = false, doc = BuiltinDocs.instancemethod_doc) -public class PyMethod extends PyObject { +public class PyMethod extends PyObject implements InvocationHandler { public static final PyType TYPE = PyType.fromClass(PyMethod.class); @@ -356,4 +360,57 @@ } return funcName.toString(); } + + @Override + public Object __tojava__(Class c) { + // Automatically coerce to single method interfaces + if (__self__ == null) { + return super.__tojava__(c); // not a bound method, so no special handling + } + if (c.isInstance(this) && c != InvocationHandler.class) { + // for base types, conversion is simple - so don't wrap! + // InvocationHandler is special, since it's a single method interface + // that we implement, but if we coerce to it we want the arguments + return c.cast( this ); + } else if (c.isInterface()) { + if (c.getDeclaredMethods().length == 1 && c.getInterfaces().length == 0) { + // Proper single method interface + return proxy(c); + } else { + // Try coerce to interface with multiple overloaded versions of + // the same method (name) + String name = null; + for (Method method : c.getMethods()) { + if (method.getDeclaringClass() != Object.class) { + if (name == null || name.equals(method.getName())) { + name = method.getName(); + } else { + name = null; + break; + } + } + } + if (name != null) { // single unique method name + return proxy(c); + } + } + } + return super.__tojava__(c); + } + + private Object proxy( Class c ) { + return Proxy.newProxyInstance(c.getClassLoader(), new Class[]{c}, this); + } + + public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable { + // Handle invocation when invoked through Proxy (as coerced to single method interface) + if (method.getDeclaringClass() == Object.class) { + return method.invoke( this, args ); + } else if (args == null || args.length == 0) { + return __call__().__tojava__(method.getReturnType()); + } else { + return __call__(Py.javas2pys(args)).__tojava__(method.getReturnType()); + } + } + } -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Wed Sep 24 02:31:38 2014 From: jython-checkins at python.org (jim.baker) Date: Wed, 24 Sep 2014 00:31:38 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Restore_select=2Ecpython=5F?= =?utf-8?q?compatible=5Fselect?= Message-ID: <20140924003134.42209.57498@mail.hg.python.org> https://hg.python.org/jython/rev/e2ce0753284e changeset: 7392:e2ce0753284e user: Jim Baker date: Tue Sep 23 18:31:28 2014 -0600 summary: Restore select.cpython_compatible_select Jython 2.5 has select.cpython_compatible_select that -- as its name suggest -- is compatible with how select.select behaves in CPython with respect to blocking sockets. Now that select.select has this desired compatible behavior, without any special workarounds, this function is obsolete. However, there is code for Jython that expects it, so now have it be an alias. files: Lib/select.py | 7 +++++++ Lib/test/test_select.py | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletions(-) diff --git a/Lib/select.py b/Lib/select.py --- a/Lib/select.py +++ b/Lib/select.py @@ -10,3 +10,10 @@ error, poll, select) + +# backwards compatibility with Jython 2.5 +cpython_compatible_select = select + +__all__ = [ + "POLLIN", "POLLOUT", "POLLPRI", "POLLERR", "POLLHUP", "POLLNVAL", + "error", "poll", "select", "cpython_compatible_select"] diff --git a/Lib/test/test_select.py b/Lib/test/test_select.py --- a/Lib/test/test_select.py +++ b/Lib/test/test_select.py @@ -168,10 +168,18 @@ except Exception, x: self.fail("Selecting on socket.fileno() should not have raised exception: %s" % str(x)) +class TestJythonSelect(unittest.TestCase): + # Normally we would have a test_select_jy for such testing, but + # the reality is that this test module is really that test :) + + def test_cpython_compatible_select_exists(self): + self.assertIs(select.cpython_compatible_select, select.select) + def test_main(): - tests = [TestSelectInvalidParameters, TestSelectClientSocket, TestPollClientSocket, ThreadedPollClientSocket] + tests = [TestSelectInvalidParameters, TestSelectClientSocket, TestPollClientSocket, ThreadedPollClientSocket, + TestJythonSelect] suites = [unittest.makeSuite(klass, 'test') for klass in tests] test_support._run_suite(unittest.TestSuite(suites)) -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Wed Sep 24 05:13:57 2014 From: jython-checkins at python.org (jim.baker) Date: Wed, 24 Sep 2014 03:13:57 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Remove_Jython-specific_test?= =?utf-8?q?=5Fsax_given_that_we_no_longer_support_Java_1=2E4_=3A=29?= Message-ID: <20140924031355.28790.83145@mail.hg.python.org> https://hg.python.org/jython/rev/0fdc65448925 changeset: 7393:0fdc65448925 user: Jim Baker date: Tue Sep 23 21:13:51 2014 -0600 summary: Remove Jython-specific test_sax given that we no longer support Java 1.4 :) files: Lib/test/test_sax.py | 754 ------------------------------- 1 files changed, 0 insertions(+), 754 deletions(-) diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py deleted file mode 100644 --- a/Lib/test/test_sax.py +++ /dev/null @@ -1,754 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# regression test for SAX 2.0 -# $Id: test_sax.py,v 1.13 2004/03/20 07:46:04 fdrake Exp $ - -import urllib -from xml.sax import handler, make_parser, ContentHandler, \ - SAXException, SAXReaderNotAvailable, SAXParseException -try: - make_parser() -except SAXReaderNotAvailable: - # don't try to test this module if we cannot create a parser - raise ImportError("no XML parsers available") -from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \ - XMLFilterBase, Location -from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl -from cStringIO import StringIO -from test.test_support import is_jython, verbose, TestFailed, findfile - -# ===== Utilities - -tests = 0 -failures = [] - -def confirm(outcome, name): - global tests - - tests = tests + 1 - if outcome: - if verbose: - print "Passed", name - else: - print "Failed", name - failures.append(name) - -def test_make_parser2(): - try: - # Creating parsers several times in a row should succeed. - # Testing this because there have been failures of this kind - # before. - from xml.sax import make_parser - p = make_parser() - from xml.sax import make_parser - p = make_parser() - from xml.sax import make_parser - p = make_parser() - from xml.sax import make_parser - p = make_parser() - from xml.sax import make_parser - p = make_parser() - from xml.sax import make_parser - p = make_parser() - except: - return 0 - else: - return p - - -# =========================================================================== -# -# saxutils tests -# -# =========================================================================== - -# ===== escape - -def test_escape_basic(): - return escape("Donald Duck & Co") == "Donald Duck & Co" - -def test_escape_all(): - return escape("") == "<Donald Duck & Co>" - -def test_escape_extra(): - return escape("Hei p? deg", {"?" : "å"}) == "Hei på deg" - -# ===== unescape - -def test_unescape_basic(): - return unescape("Donald Duck & Co") == "Donald Duck & Co" - -def test_unescape_all(): - return unescape("<Donald Duck & Co>") == "" - -def test_unescape_extra(): - return unescape("Hei p? deg", {"?" : "å"}) == "Hei på deg" - -def test_unescape_amp_extra(): - return unescape("&foo;", {"&foo;": "splat"}) == "&foo;" - -# ===== quoteattr - -def test_quoteattr_basic(): - return quoteattr("Donald Duck & Co") == '"Donald Duck & Co"' - -def test_single_quoteattr(): - return (quoteattr('Includes "double" quotes') - == '\'Includes "double" quotes\'') - -def test_double_quoteattr(): - return (quoteattr("Includes 'single' quotes") - == "\"Includes 'single' quotes\"") - -def test_single_double_quoteattr(): - return (quoteattr("Includes 'single' and \"double\" quotes") - == "\"Includes 'single' and "double" quotes\"") - -# ===== make_parser - -def test_make_parser(): - try: - # Creating a parser should succeed - it should fall back - # to the expatreader - p = make_parser(['xml.parsers.no_such_parser']) - except: - return 0 - else: - return p - - -# ===== XMLGenerator - -start = '\n' - -def test_xmlgen_basic(): - result = StringIO() - gen = XMLGenerator(result) - gen.startDocument() - gen.startElement("doc", {}) - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start + "" - -def test_xmlgen_content(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startElement("doc", {}) - gen.characters("huhei") - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start + "huhei" - -def test_xmlgen_escaped_content(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startElement("doc", {}) - gen.characters(unicode("\xa0\\u3042", "unicode-escape")) - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start + "\xa0あ" - -def test_xmlgen_escaped_attr(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startElement("doc", {"x": unicode("\\u3042", "unicode-escape")}) - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start + '' - -def test_xmlgen_pi(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.processingInstruction("test", "data") - gen.startElement("doc", {}) - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start + "" - -def test_xmlgen_content_escape(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startElement("doc", {}) - gen.characters("<huhei&" - -def test_xmlgen_attr_escape(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startElement("doc", {"a": '"'}) - gen.startElement("e", {"a": "'"}) - gen.endElement("e") - gen.startElement("e", {"a": "'\""}) - gen.endElement("e") - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start \ - + "" - -def test_xmlgen_attr_escape_manydouble(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startElement("doc", {"a": '"\'"'}) - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start + "" - -def test_xmlgen_attr_escape_manysingle(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startElement("doc", {"a": "'\"'"}) - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start + '' - -def test_xmlgen_ignorable(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startElement("doc", {}) - gen.ignorableWhitespace(" ") - gen.endElement("doc") - gen.endDocument() - - return result.getvalue() == start + " " - -ns_uri = "http://www.python.org/xml-ns/saxtest/" - -def test_xmlgen_ns(): - result = StringIO() - gen = XMLGenerator(result) - - gen.startDocument() - gen.startPrefixMapping("ns1", ns_uri) - gen.startElementNS((ns_uri, "doc"), "ns1:doc", {}) - # add an unqualified name - gen.startElementNS((None, "udoc"), None, {}) - gen.endElementNS((None, "udoc"), None) - gen.endElementNS((ns_uri, "doc"), "ns1:doc") - gen.endPrefixMapping("ns1") - gen.endDocument() - - return result.getvalue() == start + \ - ('' % - ns_uri) - -# ===== XMLFilterBase - -def test_filter_basic(): - result = StringIO() - gen = XMLGenerator(result) - filter = XMLFilterBase() - filter.setContentHandler(gen) - - filter.startDocument() - filter.startElement("doc", {}) - filter.characters("content") - filter.ignorableWhitespace(" ") - filter.endElement("doc") - filter.endDocument() - - return result.getvalue() == start + "content " - -# =========================================================================== -# -# expatreader tests -# -# =========================================================================== - -# ===== XMLReader support - -def test_expat_file(): - parser = make_parser() - result = StringIO() - xmlgen = XMLGenerator(result) - - parser.setContentHandler(xmlgen) - parser.parse(open(findfile("test.xml"))) - - return result.getvalue() == xml_test_out - -# ===== DTDHandler support - -class TestDTDHandler: - - def __init__(self): - self._notations = [] - self._entities = [] - - def notationDecl(self, name, publicId, systemId): - self._notations.append((name, publicId, systemId)) - - def unparsedEntityDecl(self, name, publicId, systemId, ndata): - self._entities.append((name, publicId, systemId, ndata)) - -def test_expat_dtdhandler(): - parser = make_parser() - handler = TestDTDHandler() - parser.setDTDHandler(handler) - - parser.parse(StringIO(''' - -]> -''')) - if len(handler._entities) != 1 or len(handler._entities[0]) != 4: - return 0 - name, pubId, sysId, ndata = handler._entities[0] - if name != 'img' or not pubId is None or not sysId.endswith('expat.gif') or ndata != 'GIF': - return 0 - return handler._notations == [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)] - -# ===== EntityResolver support - -class TestEntityResolver: - - def resolveEntity(self, publicId, systemId): - inpsrc = InputSource() - inpsrc.setByteStream(StringIO("")) - return inpsrc - -def test_expat_entityresolver(): - parser = make_parser() - parser.setEntityResolver(TestEntityResolver()) - result = StringIO() - parser.setContentHandler(XMLGenerator(result)) - - parser.parse(StringIO(''' -]> -&test;''')) - return result.getvalue() == start + "" - -# ===== Attributes support - -class AttrGatherer(ContentHandler): - - def startElement(self, name, attrs): - self._attrs = attrs - - def startElementNS(self, name, qname, attrs): - self._attrs = attrs - -def test_expat_attrs_empty(): - parser = make_parser() - gather = AttrGatherer() - parser.setContentHandler(gather) - - parser.parse(StringIO("")) - - return verify_empty_attrs(gather._attrs) - -def test_expat_attrs_wattr(): - parser = make_parser() - gather = AttrGatherer() - parser.setContentHandler(gather) - - parser.parse(StringIO("")) - - return verify_attrs_wattr(gather._attrs) - -def test_expat_nsattrs_empty(): - parser = make_parser() - parser.setFeature(handler.feature_namespaces, 1) - gather = AttrGatherer() - parser.setContentHandler(gather) - - parser.parse(StringIO("")) - - return verify_empty_nsattrs(gather._attrs) - -def test_expat_nsattrs_wattr(): - parser = make_parser() - parser.setFeature(handler.feature_namespaces, 1) - gather = AttrGatherer() - parser.setContentHandler(gather) - - a_name = "id" ; a_val = "val" - parser.parse(StringIO("" % (ns_uri, a_name, a_val) )) - - attrs = gather._attrs - - return attrs.getLength() == 1 and \ - attrs.getNames() == [(ns_uri, a_name)] and \ - attrs.getQNames() == ["ns:%s" % a_name] and \ - len(attrs) == 1 and \ - attrs.has_key((ns_uri, a_name)) and \ - attrs.keys() == [(ns_uri, a_name)] and \ - attrs.get((ns_uri, a_name)) == a_val and \ - attrs.get((ns_uri, a_name), 25) == a_val and \ - attrs.items() == [((ns_uri, a_name), a_val)] and \ - attrs.values() == [a_val] and \ - attrs.getValue((ns_uri, a_name)) == a_val and \ - attrs[(ns_uri, a_name)] == a_val - -def test_expat_nsattrs_no_namespace(): - parser = make_parser() - parser.setFeature(handler.feature_namespaces, 1) - gather = AttrGatherer() - parser.setContentHandler(gather) - - a_name = "id" ; a_val = "val" - parser.parse(StringIO("" % (a_name, a_val) )) - - attrs = gather._attrs - - return attrs.getLength() == 1 and \ - attrs.getNames() == [(None, a_name)] and \ - attrs.getQNames() == [a_name] and \ - len(attrs) == 1 and \ - attrs.has_key((None, a_name)) and \ - attrs.keys() == [(None, a_name)] and \ - attrs.get((None, a_name)) == a_val and \ - attrs.get((None, a_name), 25) == a_val and \ - attrs.items() == [((None, a_name), a_val)] and \ - attrs.values() == [a_val] and \ - attrs.getValue((None, a_name)) == a_val and \ - attrs[(None, a_name)] == a_val - -# ===== InputSource support - -xml_test_out = open(findfile("test.xml.out")).read() - -def test_expat_inpsource_filename(): - parser = make_parser() - result = StringIO() - xmlgen = XMLGenerator(result) - - parser.setContentHandler(xmlgen) - parser.parse(findfile("test.xml")) - - return result.getvalue() == xml_test_out - -def test_expat_inpsource_sysid(): - parser = make_parser() - result = StringIO() - xmlgen = XMLGenerator(result) - - parser.setContentHandler(xmlgen) - parser.parse(InputSource(findfile("test.xml"))) - - return result.getvalue() == xml_test_out - -def test_expat_inpsource_stream(): - parser = make_parser() - result = StringIO() - xmlgen = XMLGenerator(result) - - parser.setContentHandler(xmlgen) - inpsrc = InputSource() - inpsrc.setByteStream(open(findfile("test.xml"))) - parser.parse(inpsrc) - - return result.getvalue() == xml_test_out - -# ===== Locator support - -class LocatorTest(XMLGenerator): - def __init__(self, out=None, encoding="iso-8859-1"): - XMLGenerator.__init__(self, out, encoding) - self.location = None - - def setDocumentLocator(self, locator): - XMLGenerator.setDocumentLocator(self, locator) - self.location = Location(self._locator) - -def test_expat_locator_noinfo(): - result = StringIO() - xmlgen = LocatorTest(result) - parser = make_parser() - parser.setContentHandler(xmlgen) - - parser.parse(StringIO("")) - - return xmlgen.location.getSystemId() is None and \ - xmlgen.location.getPublicId() is None and \ - xmlgen.location.getLineNumber() == 1 - -def test_expat_locator_withinfo(): - result = StringIO() - xmlgen = LocatorTest(result) - parser = make_parser() - parser.setContentHandler(xmlgen) - testfile = findfile("test.xml") - parser.parse(testfile) - if is_jython: - # In Jython, the system id is a URL with forward slashes, and - # under Windows findfile returns a path with backslashes, so - # replace the backslashes with forward - testfile = testfile.replace('\\', '/') - - # urllib.quote isn't the exact encoder (e.g. ':' isn't escaped) - expected = urllib.quote(testfile).replace('%3A', ':') - return xmlgen.location.getSystemId().endswith(expected) and \ - xmlgen.location.getPublicId() is None - - -# =========================================================================== -# -# error reporting -# -# =========================================================================== - -def test_expat_incomplete(): - parser = make_parser() - parser.setContentHandler(ContentHandler()) # do nothing - try: - parser.parse(StringIO("")) - except SAXParseException: - return 1 # ok, error found - else: - return 0 - -def test_sax_location_str(): - # pass various values from a locator to the SAXParseException to - # make sure that the __str__() doesn't fall apart when None is - # passed instead of an integer line and column number - # - # use "normal" values for the locator: - str(Location(DummyLocator(1, 1))) - # use None for the line number: - str(Location(DummyLocator(None, 1))) - # use None for the column number: - str(Location(DummyLocator(1, None))) - # use None for both: - str(Location(DummyLocator(None, None))) - return 1 - -def test_sax_parse_exception_str(): - # pass various values from a locator to the SAXParseException to - # make sure that the __str__() doesn't fall apart when None is - # passed instead of an integer line and column number - # - # use "normal" values for the locator: - str(SAXParseException("message", None, - DummyLocator(1, 1))) - # use None for the line number: - str(SAXParseException("message", None, - DummyLocator(None, 1))) - # use None for the column number: - str(SAXParseException("message", None, - DummyLocator(1, None))) - # use None for both: - str(SAXParseException("message", None, - DummyLocator(None, None))) - return 1 - -class DummyLocator: - def __init__(self, lineno, colno): - self._lineno = lineno - self._colno = colno - - def getPublicId(self): - return "pubid" - - def getSystemId(self): - return "sysid" - - def getLineNumber(self): - return self._lineno - - def getColumnNumber(self): - return self._colno - -# =========================================================================== -# -# xmlreader tests -# -# =========================================================================== - -# ===== AttributesImpl - -def verify_empty_attrs(attrs): - try: - attrs.getValue("attr") - gvk = 0 - except KeyError: - gvk = 1 - - try: - attrs.getValueByQName("attr") - gvqk = 0 - except KeyError: - gvqk = 1 - - try: - attrs.getNameByQName("attr") - gnqk = 0 - except KeyError: - gnqk = 1 - - try: - attrs.getQNameByName("attr") - gqnk = 0 - except KeyError: - gqnk = 1 - - try: - attrs["attr"] - gik = 0 - except KeyError: - gik = 1 - - return attrs.getLength() == 0 and \ - attrs.getNames() == [] and \ - attrs.getQNames() == [] and \ - len(attrs) == 0 and \ - not attrs.has_key("attr") and \ - attrs.keys() == [] and \ - attrs.get("attrs") is None and \ - attrs.get("attrs", 25) == 25 and \ - attrs.items() == [] and \ - attrs.values() == [] and \ - gvk and gvqk and gnqk and gik and gqnk - -def verify_attrs_wattr(attrs): - return attrs.getLength() == 1 and \ - attrs.getNames() == ["attr"] and \ - attrs.getQNames() == ["attr"] and \ - len(attrs) == 1 and \ - attrs.has_key("attr") and \ - attrs.keys() == ["attr"] and \ - attrs.get("attr") == "val" and \ - attrs.get("attr", 25) == "val" and \ - attrs.items() == [("attr", "val")] and \ - attrs.values() == ["val"] and \ - attrs.getValue("attr") == "val" and \ - attrs.getValueByQName("attr") == "val" and \ - attrs.getNameByQName("attr") == "attr" and \ - attrs["attr"] == "val" and \ - attrs.getQNameByName("attr") == "attr" - -def test_attrs_empty(): - return verify_empty_attrs(AttributesImpl({})) - -def test_attrs_wattr(): - return verify_attrs_wattr(AttributesImpl({"attr" : "val"})) - -# ===== AttributesImpl - -def verify_empty_nsattrs(attrs): - try: - attrs.getValue((ns_uri, "attr")) - gvk = 0 - except KeyError: - gvk = 1 - - try: - attrs.getValueByQName("ns:attr") - gvqk = 0 - except KeyError: - gvqk = 1 - - try: - attrs.getNameByQName("ns:attr") - gnqk = 0 - except KeyError: - gnqk = 1 - - try: - attrs.getQNameByName((ns_uri, "attr")) - gqnk = 0 - except KeyError: - gqnk = 1 - - try: - attrs[(ns_uri, "attr")] - gik = 0 - except KeyError: - gik = 1 - - return attrs.getLength() == 0 and \ - attrs.getNames() == [] and \ - attrs.getQNames() == [] and \ - len(attrs) == 0 and \ - not attrs.has_key((ns_uri, "attr")) and \ - attrs.keys() == [] and \ - attrs.get((ns_uri, "attr")) is None and \ - attrs.get((ns_uri, "attr"), 25) == 25 and \ - attrs.items() == [] and \ - attrs.values() == [] and \ - gvk and gvqk and gnqk and gik and gqnk - -def test_nsattrs_empty(): - return verify_empty_nsattrs(AttributesNSImpl({}, {})) - -def test_nsattrs_wattr(): - attrs = AttributesNSImpl({(ns_uri, "attr") : "val"}, - {(ns_uri, "attr") : "ns:attr"}) - - return attrs.getLength() == 1 and \ - attrs.getNames() == [(ns_uri, "attr")] and \ - attrs.getQNames() == ["ns:attr"] and \ - len(attrs) == 1 and \ - attrs.has_key((ns_uri, "attr")) and \ - attrs.keys() == [(ns_uri, "attr")] and \ - attrs.get((ns_uri, "attr")) == "val" and \ - attrs.get((ns_uri, "attr"), 25) == "val" and \ - attrs.items() == [((ns_uri, "attr"), "val")] and \ - attrs.values() == ["val"] and \ - attrs.getValue((ns_uri, "attr")) == "val" and \ - attrs.getValueByQName("ns:attr") == "val" and \ - attrs.getNameByQName("ns:attr") == (ns_uri, "attr") and \ - attrs[(ns_uri, "attr")] == "val" and \ - attrs.getQNameByName((ns_uri, "attr")) == "ns:attr" - - -# ===== Main program - -def make_test_output(): - parser = make_parser() - result = StringIO() - xmlgen = XMLGenerator(result) - - parser.setContentHandler(xmlgen) - parser.parse(findfile("test.xml")) - - outf = open(findfile("test.xml.out"), "w") - outf.write(result.getvalue()) - outf.close() - -import sys -java_14 = sys.platform.startswith("java1.4") -del sys - -items = locals().items() -items.sort() -for (name, value) in items: - if name.startswith('test_expat') and java_14: - #skip expat tests on java14 since the crimson parser is so crappy - continue - if name[:5] == "test_": - confirm(value(), name) - -if verbose: - print "%d tests, %d failures" % (tests, len(failures)) -if failures: - raise TestFailed("%d of %d tests failed: %s" - % (len(failures), tests, ", ".join(failures))) -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Fri Sep 26 19:44:20 2014 From: jython-checkins at python.org (jim.baker) Date: Fri, 26 Sep 2014 17:44:20 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Register_java=2Eutil=2E=7BL?= =?utf-8?q?ist=2CMap=2CSet=7D_with_ABCs_without_namespace_issues?= Message-ID: <20140926174405.53360.33400@mail.hg.python.org> https://hg.python.org/jython/rev/9fef5da411e5 changeset: 7394:9fef5da411e5 user: Jim Baker date: Fri Sep 26 11:43:55 2014 -0600 summary: Register java.util.{List,Map,Set} with ABCs without namespace issues files: Lib/_abcoll.py | 18 +++++++++++------- 1 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Lib/_abcoll.py b/Lib/_abcoll.py --- a/Lib/_abcoll.py +++ b/Lib/_abcoll.py @@ -19,7 +19,6 @@ "Sequence", "MutableSequence", ] -_is_jython = sys.platform.startswith("java") ### ONE-TRICK PONIES ### @@ -602,12 +601,17 @@ MutableSequence.register(list) -if _is_jython: +if sys.platform.startswith("java"): from org.python.core import PyFastSequenceIter - import java + # the only name conflict is with Set, but be consistent + from java.util import List as JList, Map as JMap, Set as JSet - MutableSequence.register(java.util.List) - MutableMapping.register(java.util.Map) - MutableSet.register(java.util.Set) + MutableSequence.register(JList) + MutableMapping.register(JMap) + MutableSet.register(JSet) Iterator.register(PyFastSequenceIter) - + + del PyFastSequenceIter + del JList + del JMap + del JSet -- Repository URL: https://hg.python.org/jython