def test_native_list_selfcontaining(self): l = ["Hello", "lovely", "world"] l[1] = l DemoExtension.listModifyTest(l, 0) self.assertEqual(l[0], "natively modified") self.assertEqual(len(l), 3) self.assertEqual(str(l), "['natively modified', [...], 'world']")
def test_integer_passing(self): self.assertEqual(DemoExtension.intSquare.__doc__, "Returns the square of the given int.") self.assertEqual(str(DemoExtension.intSquare), "<built-in function intSquare>") self.assertEqual(str(DemoExtension.intSquare.__class__), "<type 'builtin_function_or_method'>") self.assertEqual(DemoExtension.intSquare.__name__, "intSquare") self.assertEqual(DemoExtension.intSquare(16), 256) self.assertEqual(DemoExtension.intSquare(19), 361)
def test_native_tuple_selfcontaining(self): l = ["Hello", "lovely", "world"] l[1] = (11, 12, l) DemoExtension.listModifyTest(l, 2) self.assertEqual(l[2], "natively modified") self.assertEqual(len(l), 3) self.assertEqual(str(l), "['Hello', (11, 12, [...]), 'natively modified']")
def test_argument_passing(self): self.assertEqual( DemoExtension.concatFirstWithLastString.__doc__, "Concatenates first with last element. Returns empty string, if less than two args are available.", ) self.assertEqual(DemoExtension.concatFirstWithLastString("begin_", "ignore", "ignore too", "end"), "begin_end") self.assertEqual(DemoExtension.argCountToString.__doc__, "Returns number of arguments as string.") self.assertEqual(DemoExtension.argCountToString("a", "b", "c", "d", "e", "f"), "(6)")
def test_exception(self): self.assertRaisesRegexp(SystemError, "This is a test exception message for JyNI.", DemoExtension.exceptionTest) try: DemoExtension.exceptionTest() self.assertEqual(1, 2) #would always fail, but is not reached if everything works as expected except SystemError: exc = sys.exc_info() self.assertEqual(exc[0], SystemError) self.assertEqual(str(exc[1]), "This is a test exception message for JyNI.")
def test_native_sequence_selfcontaining(self): # In early JyNI-days self-containing sequences used # to trigger infinite conversion loops l = ["Hello", "lovely", "world"] l[1] = (11, 12, l) DemoExtension.listModifyTest(l, 2) self.assertEqual(l[2], "natively modified") self.assertEqual(len(l), 3) self.assertEqual(str(l), "['Hello', (11, 12, [...]), 'natively modified']")
def test_custom_classes(self): from JyNI import JyNIImporter #, PyShadowString strType = type("") intType = type(6) nobj = JyNIImporter() self.assertTrue(DemoExtension.newstyleCheck(nobj)) self.assertFalse(DemoExtension.newstyleCheckSubtype(nobj, strType)) self.assertFalse(DemoExtension.newstyleCheckSubtype(nobj, intType))
def test_new_style_classes(self): class testnewstyle(object): pass class testnewstyleString(str): pass class testnewstyleInt(int): pass strType = type("") intType = type(6) nobj = testnewstyle() self.assertTrue(DemoExtension.newstyleCheck(nobj)) self.assertFalse(DemoExtension.newstyleCheckSubtype(nobj, strType)) self.assertFalse(DemoExtension.newstyleCheckSubtype(nobj, intType)) nobj = testnewstyleString() self.assertTrue(DemoExtension.newstyleCheck(nobj)) self.assertTrue(DemoExtension.newstyleCheckSubtype(nobj, strType)) self.assertFalse(DemoExtension.newstyleCheckSubtype(nobj, intType)) nobj = testnewstyleInt() self.assertTrue(DemoExtension.newstyleCheck(nobj)) self.assertFalse(DemoExtension.newstyleCheckSubtype(nobj, strType)) self.assertTrue(DemoExtension.newstyleCheckSubtype(nobj, intType))
def test_integer_passing(self): self.assertEqual(DemoExtension.intSquare.__doc__, "Returns the square of the given int.") self.assertEqual(str(DemoExtension.intSquare), "<built-in function intSquare>") self.assertEqual(str(DemoExtension.intSquare.__class__), "<type 'builtin_function_or_method'>") self.assertEqual(DemoExtension.intSquare.__name__, "intSquare") self.assertEqual(DemoExtension.intSquare(16), 256) self.assertEqual(DemoExtension.intSquare(19), 361) self.assertEqual(DemoExtension.intSquare1(-19), 361)
def test_exception(self): self.assertRaisesRegexp(SystemError, "This is a test exception message for JyNI.", DemoExtension.exceptionTest) try: DemoExtension.exceptionTest() self.assertEqual( 1, 2 ) #would always fail, but is not reached if everything works as expected except SystemError: exc = sys.exc_info() self.assertEqual(exc[0], SystemError) self.assertEqual(str(exc[1]), "This is a test exception message for JyNI.")
def test_gc_list_cycle(self): #print "test_gc_list_cycle" l = (123, [0, "test1"]) l[1][0] = l #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) DemoExtension.argCountToString(l) del l self.assertIsNotNone(wkl.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 4) runGC() self.assertIsNone(wkl.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) del wkl
def test_argument_passing(self): self.assertEqual( DemoExtension.concatFirstWithLastString.__doc__, "Concatenates first with last element. Returns empty string, if less than two args are available." ) self.assertEqual( DemoExtension.concatFirstWithLastString("begin_", "ignore", "ignore too", "end"), "begin_end") self.assertEqual(DemoExtension.argCountToString.__doc__, "Returns number of arguments as string.") self.assertEqual( DemoExtension.argCountToString("a", "b", "c", "d", "e", "f"), "(6)")
def run4(): import DemoExtension JyNI.JyRefMonitor_setMemDebugFlags(1) l = ([0, "test"],) l[0][0] = l DemoExtension.argCountToString(l) del l #l[0][1] = None print "Leaks before GC:" monitor.listLeaks() System.gc() time.sleep(2) print "Leaks after GC:" monitor.listLeaks()
def run4(): import DemoExtension JyNI.JyRefMonitor_setMemDebugFlags(1) l = ([0, "test"], ) l[0][0] = l DemoExtension.argCountToString(l) del l #l[0][1] = None print "Leaks before GC:" monitor.listLeaks() System.gc() time.sleep(2) print "Leaks after GC:" monitor.listLeaks()
def test_gc_list_modify_silent(self): #print "test_gc_list_modify_silent" clearCurrentLeaks() self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) l = [0, "test1"] d = {'a': 7, 'b': "test6"} wkl = WeakReference(l) wkd = WeakReference(d) wkl2 = weakref.ref(l) wkd2 = weakref.ref(d) self.assertIsNotNone(wkl.get()) self.assertIsNotNone(wkd.get()) self.assertIsNotNone(wkl2()) self.assertIsNotNone(wkd2()) DemoExtension.listSetIndex(l, 0, d) del d self.assertEqual(len(monitor.getCurrentNativeLeaks()), 4) #monitor.listAll() runGC() #monitor.listAll() self.assertFalse(monitor.lastClearGraphValid) self.assertIsNotNone(wkl.get()) self.assertIsNone(wkd.get()) self.assertIsNotNone(wkl2()) self.assertIsNotNone(wkd2()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 3) self.assertIsNotNone(l[0]) self.assertEqual(len(l[0]), 2) del l runGC() #monitor.listAll() self.assertTrue(monitor.lastClearGraphValid) # For some reason resurrected objects persist one more # gc-cycle in principle. So we have to run gc again before # we can observe wkd2 to die. It is currently unclear whether # this behavior is a JyNI-bug or natural Java-gc behavior, # but for now (with some evidence) we assume the latter. # Note: Since WeakRef-support wkd2 actually keeps the native # referent alive for one more cycle. So also the monitor-refcount # test only passes after another gc-run now. runGC() #monitor.listAll() self.assertTrue(monitor.lastClearGraphValid) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) self.assertIsNone(wkl2()) self.assertIsNone(wkd2())
def test_native_set(self): basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] fruit = set(basket) p = 2 DemoExtension.setPopTest(fruit, p) self.assertEqual(len(fruit), 2) count = 0 if "pear" in fruit: count += 1 if "apple" in fruit: count += 1 if "orange" in fruit: count += 1 if "banana" in fruit: count += 1 self.assertEqual(count, 2)
def test_gc_list_cycle(self): #print "test_gc_list_cycle" clearCurrentLeaks() self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) l = (123, [0, "test1"]) l[1][0] = l #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) DemoExtension.argCountToString(l) del l self.assertIsNotNone(wkl.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 4) runGC() self.assertIsNone(wkl.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) del wkl
def test_gc_dict_cycle(self): #print "test_gc_dict_cycle" l = (123, {'a': 0, 'b': "test3"}) l[1]['a'] = l #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) DemoExtension.argCountToString(l) del l self.assertIsNotNone(wkl.get()) #monitor.listLeaks() self.assertEqual(len(monitor.getCurrentNativeLeaks()), 3) runGC() self.assertIsNone(wkl.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) #print "" #monitor.listLeaks() del wkl
def test_gc_list_modify_silent(self): #print "test_gc_list_modify_silent" clearCurrentLeaks() self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) l = [0, "test1"] d = {'a': 7, 'b': "test6"} wkl = WeakReference(l) wkd = WeakReference(d) wkl2 = weakref.ref(l) wkd2 = weakref.ref(d) self.assertIsNotNone(wkl.get()) self.assertIsNotNone(wkd.get()) self.assertIsNotNone(wkl2()) self.assertIsNotNone(wkd2()) DemoExtension.listSetIndex(l, 0, d) del d self.assertEqual(len(monitor.getCurrentNativeLeaks()), 4) runGC() self.assertFalse(monitor.lastClearGraphValid) self.assertIsNotNone(wkl.get()) self.assertIsNone(wkd.get()) self.assertIsNotNone(wkl2()) self.assertIsNotNone(wkd2()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 3) self.assertIsNotNone(l[0]) self.assertEqual(len(l[0]), 2) del l runGC() self.assertTrue(monitor.lastClearGraphValid) # For some reason resurrected objects persist one more # gc-cycle in principle. So we have to run gc again before # we can observe wkd2 to die. It is currently unclear whether # this behavior is a JyNI-bug or natural Java-gc behavior, # but for now (with some evidence) we assume the latter. # Note: Since WeakRef-support wkd2 actually keeps the native # referent alive for one more cycle. So also the monitor-refcount # test only passes after another gc-run now. runGC() self.assertTrue(monitor.lastClearGraphValid) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) self.assertIsNone(wkl2()) self.assertIsNone(wkd2())
def test_gc_list_cycle2(self): #print "test_gc_list_cycle2" clearCurrentLeaks() self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) l2 = (127, [0, "test2"]) l2[1][0] = l2 #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l2) DemoExtension.argCountToString(l2) self.assertIsNotNone(wkl.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 4) runGC() self.assertIsNotNone(wkl.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 3) del l2 runGC() self.assertIsNone(wkl.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) del wkl
def test_gc_list_modify_silent(self): #print "test_gc_list_modify_silent" l = [0, "test1"] d = {'a': 7, 'b': "test6"} wkl = WeakReference(l) wkd = WeakReference(d) wkl2 = weakref.ref(l) wkd2 = weakref.ref(d) self.assertIsNotNone(wkl.get()) self.assertIsNotNone(wkd.get()) self.assertIsNotNone(wkl2()) self.assertIsNotNone(wkd2()) DemoExtension.listSetIndex(l, 0, d) del d self.assertEqual(len(monitor.getCurrentNativeLeaks()), 4) #print "run1" runGC() #print "run1 done" self.assertFalse(monitor.lastClearGraphValid) self.assertIsNotNone(wkl.get()) self.assertIsNone(wkd.get()) self.assertIsNotNone(wkl2()) self.assertIsNotNone(wkd2()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 3) self.assertIsNotNone(l[0]) self.assertEqual(len(l[0]), 2) del l #print "run2" runGC() #print "run2 done" self.assertTrue(monitor.lastClearGraphValid) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) self.assertIsNone(wkl2()) # For some reason resurrected objects persist one more # gc-cycle in principle. So we have to run gc again before # we can observe wkd2 to die. It is currently unclear whether # this behavior is a JyNI-bug or natural Java-gc behavior, # but for now (with some evidence) we assume the latter. #print "run3" runGC() #print "run3 done" self.assertIsNone(wkd2())
def test_gc_list_modify_update(self): #print "test_gc_list_modify_update" l = [0, "test1"] d = {'a': 7, 'b': "test6"} #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) wkd = WeakReference(d) #l[0] = d DemoExtension.argCountToString(l) l[0] = d del d self.assertEqual(len(monitor.getCurrentNativeLeaks()), 4) runGC() self.assertIsNotNone(wkl.get()) self.assertIsNotNone(wkd.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 3) del l runGC() self.assertIsNone(wkl.get()) self.assertIsNone(wkd.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0)
def test_boolean_passing(self): self.assertEqual(DemoExtension.booleanToInt(False), 0) self.assertEqual(DemoExtension.booleanToInt(True), 1) self.assertIsNone(DemoExtension.booleanToInt(99)) self.assertTrue(DemoExtension.intToBoolean(1)) self.assertFalse(DemoExtension.intToBoolean(0)) self.assertIsNone(DemoExtension.intToBoolean(2))
def test_gc_list_modify_update(self): #print "test_gc_list_modify_update" clearCurrentLeaks() self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0) l = [0, "test1"] d = {'a': 7, 'b': "test6"} #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) wkd = WeakReference(d) #l[0] = d DemoExtension.argCountToString(l) l[0] = d del d self.assertEqual(len(monitor.getCurrentNativeLeaks()), 4) runGC() self.assertIsNotNone(wkl.get()) self.assertIsNotNone(wkd.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 3) del l runGC() self.assertIsNone(wkl.get()) self.assertIsNone(wkd.get()) self.assertEqual(len(monitor.getCurrentNativeLeaks()), 0)
def run3(): JyNI.JyRefMonitor_setMemDebugFlags(1) JyWeakReferenceGC.monitorNativeCollection = True import DemoExtension #JyNI.JyRefMonitor_setMemDebugFlags(1) #JyWeakReferenceGC.monitorNativeCollection = True l = [0, "test1"] # print l # DemoExtension.listSetIndex(l, 0, 100.7) # print l d = {'a': 7, 'b': "test6"} #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) wkd = WeakReference(d) wkl2 = weakref.ref(l) wkd2 = weakref.ref(d) #Note: #===== #To make this work we'll have to ensure that d gets a GCHead even though #l doesn't recognize the insertion of d and thus would not explore it. #In fact every C-stub object must get a GCHead when going native, regardless #of whether it is inserted somewhere or not, because it might be silently #inserted and a GCHead is the only way to detect this and fix it. #Add a call (e.g. to size) to the dict in l on native side to test that #d still works (which it currently shouldn't). #Later use d's GCHead to detect the invalid graph and resurrect d's java-part. #Take care of the GIL here. CStubs must release the GIL when they detect a #failing backend, so the GC-thread can acquire it and resurrect the backend. #How to fix the weak reference etc? #l[0] = d print "weak(l): " + str(wkl.get()) print "weak(d): " + str(wkd.get()) print "weak2(l): " + str(wkl2()) print "weak2(d): " + str(wkd2()) print "make l native..." #l[0] = d #DemoExtension.argCountToString(l) #l[0] = d DemoExtension.listSetIndex(l, 0, d) print "Delete l... (but GC not yet ran)" #del l del d #l = None #print "weak(l) after del: "+str(wkl.get()) print "weak(d) after del: " + str(wkd.get()) print "weak2(d) after del: " + str(wkd2()) print "" print "Leaks before GC:" monitor.listLeaks() print "" print "calling Java-GC..." System.gc() time.sleep(2) # if monitor.lastClearGraphValid: # print "valid graph" # else: # print "invalid graph" # monitor.lastClearGraphValid = False print "weak(l) after GC: " + str(wkl.get()) #print "l after GC: "+str(l) print "weak(d) after GC: " + str(wkd.get()) print "weak2(l) after GC: " + str(wkl2()) print "weak2(d) after GC: " + str(wkd2()) wkd = WeakReference(l[0]) print "" #monitor.listWouldDeleteNative() print "" #print "leaks after GC:" #monitor.listLeaks() print "l[0], i.e. d after gc:" #print l[0] #print len(l[0]) print "------" print "del l..." del l System.gc() time.sleep(2) # if monitor.lastClearGraphValid: # print "valid graph" # else: # print "invalid graph" # monitor.lastClearGraphValid = False print "" monitor.listWouldDeleteNative() print "" #print "leaks after GC (l deleted):" #monitor.listLeaks() #print DemoExtension.argCountToString.__doc__ #monitor.listFreeStatus("dict") #monitor.listAll() #GlobalRef.processDelayedCallbacks() print "weak(d) after GC2: " + str(wkd.get()) print "weak2(l) after GC2: " + str(wkl2()) print "weak2(d) after GC2: " + str(wkd2()) System.gc() time.sleep(2) print "weak(d) after GC3: " + str(wkd.get()) monitor.listWouldDeleteNative() print "" print "leaks after GC3:" monitor.listLeaks() print "" print "====" print "exit" print "===="
def test_native_list_access_writing(self): l = ["Hello", "lovely", "world"] DemoExtension.listModifyTest(l, 2) self.assertEqual(l[2], "natively modified") self.assertEqual(len(l), 3)
print DemoExtension.__doc__ # If you run this via Jython, you can uncomment the following lines to prove that Jython is running. # With these lines this demo becomes a program that neither Jython without JyNI, # nor ordinary CPython could run. #print "To prove that Jython is running, we make a java call:" #from java.lang import System #print "System.currentTimeMillis: "+str(System.currentTimeMillis()) print "" print "--------Hello World----------" print DemoExtension.hello_world print DemoExtension.hello_world.__doc__ DemoExtension.hello_world() print "" print "--------Argument passing----------" print DemoExtension.concatFirstWithLastString.__doc__ print DemoExtension.concatFirstWithLastString("begin_", "ignore", "ignore too", "end") print DemoExtension.argCountToString.__doc__ print DemoExtension.argCountToString("a", "b", "c", "d", "e", "f") print "" print "--------Argument passing with keywords----------" DemoExtension.keywordTest("first", "second", right = "Hey", wrong = "nothing") print "(in JyNI-case see bottom for native outputs)" print "" print "----------------Integer passing-----------------"
def run1(): JyNI.JyRefMonitor_setMemDebugFlags(1) JyWeakReferenceGC.monitorNativeCollection = True # PyType <- Make native ref-cycle test with heap type to test partly-stub-mode. # PySet, but no native link to other PyObject # PyFrozenSet, " # PyCode, not GC-relevant in CPython import DemoExtension #Note: # For now we attempt to verify JyNI's GC-functionality independently from # Jython concepts like Jython weak references or Jython GC-module. # So we use java.lang.ref.WeakReference and java.lang.System.gc to monitor # and control Java-gc. #JyNI.JyRefMonitor_setMemDebugFlags(1) #JyWeakReferenceGC.monitorNativeCollection = True #l = (123,) l = ([0, "test"],) l[0][0] = l #l = (123, {'a': 0, 'b': "test"}) #l[1]['a'] = l #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) print "weak(l): "+str(wkl.get()) # We pass down l to some native method. We don't care for the method itself, # but conversion to native side causes creation of native PyObjects that # correspond to l and its elements. We will then track the life-cycle of these. print "make l native..." DemoExtension.argCountToString(l) #print "argCountToString.__doc__-address: "+str(JyNI.lookupNativeHandle(DemoExtension.argCountToString.__doc__)) #print "We access a method-doc as this used to cause problems with GC:" #print " "+DemoExtension.argCountToString.__doc__ #print "Native static objects so far:" #print JyNI.nativeStaticPyObjectHeads.keySet() print "Delete l... (but GC not yet ran)" del l #l = None print "weak(l) after del: "+str(wkl.get()) print "" # monitor.list-methods display the following format: # [native pointer]{'' | '_GC_J' | '_J'} ([type]) #[native ref-count]: [repr] *[creation time] # _GC_J means that JyNI tracks the object # _J means that a JyNI-GC-head exists, but the object is not actually treated by GC # This can serve monitoring purposes or soft-keep-alive (c.f. java.lang.ref.SoftReference) # for caching. print "Leaks before GC:" monitor.listLeaks() print "" # By inserting this line you can confirm that native # leaks would persist if JyNI-GC is not working: #JyWeakReferenceGC.nativecollectionEnabled = False print "calling Java-GC..." System.gc() time.sleep(2) print "weak(l) after GC: "+str(wkl.get()) print "" monitor.listWouldDeleteNative() print "" print "leaks after GC:" monitor.listLeaks() print "" print " "+DemoExtension.argCountToString.__doc__ monitor.listLeaks() #print "----" #print monitor.listAll() print "" print "====" print "exit" print "===="
def run3(): JyNI.JyRefMonitor_setMemDebugFlags(1) JyWeakReferenceGC.monitorNativeCollection = True import DemoExtension #JyNI.JyRefMonitor_setMemDebugFlags(1) #JyWeakReferenceGC.monitorNativeCollection = True l = [0, "test1"] # print l # DemoExtension.listSetIndex(l, 0, 100.7) # print l d = {'a': 7, 'b': "test6"} #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) wkd = WeakReference(d) wkl2 = weakref.ref(l) wkd2 = weakref.ref(d) #Note: #===== #To make this work we'll have to ensure that d gets a GCHead even though #l doesn't recognize the insertion of d and thus would not explore it. #In fact every C-stub object must get a GCHead when going native, regardless #of whether it is inserted somewhere or not, because it might be silently #inserted and a GCHead is the only way to detect this and fix it. #Add a call (e.g. to size) to the dict in l on native side to test that #d still works (which it currently shouldn't). #Later use d's GCHead to detect the invalid graph and resurrect d's java-part. #Take care of the GIL here. CStubs must release the GIL when they detect a #failing backend, so the GC-thread can acquire it and resurrect the backend. #How to fix the weak reference etc? #l[0] = d print "weak(l): "+str(wkl.get()) print "weak(d): "+str(wkd.get()) print "weak2(l): "+str(wkl2()) print "weak2(d): "+str(wkd2()) print "make l native..." #l[0] = d #DemoExtension.argCountToString(l) #l[0] = d DemoExtension.listSetIndex(l, 0, d) print "Delete l... (but GC not yet ran)" #del l del d #l = None #print "weak(l) after del: "+str(wkl.get()) print "weak(d) after del: "+str(wkd.get()) print "weak2(d) after del: "+str(wkd2()) print "" print "Leaks before GC:" monitor.listLeaks() print "" print "calling Java-GC..." System.gc() time.sleep(2) # if monitor.lastClearGraphValid: # print "valid graph" # else: # print "invalid graph" # monitor.lastClearGraphValid = False print "weak(l) after GC: "+str(wkl.get()) #print "l after GC: "+str(l) print "weak(d) after GC: "+str(wkd.get()) print "weak2(l) after GC: "+str(wkl2()) print "weak2(d) after GC: "+str(wkd2()) wkd = WeakReference(l[0]) print "" #monitor.listWouldDeleteNative() print "" #print "leaks after GC:" #monitor.listLeaks() print "l[0], i.e. d after gc:" #print l[0] #print len(l[0]) print "------" print "del l..." del l System.gc() time.sleep(2) # if monitor.lastClearGraphValid: # print "valid graph" # else: # print "invalid graph" # monitor.lastClearGraphValid = False print "" monitor.listWouldDeleteNative() print "" #print "leaks after GC (l deleted):" #monitor.listLeaks() #print DemoExtension.argCountToString.__doc__ #monitor.listFreeStatus("dict") #monitor.listAll() #GlobalRef.processDelayedCallbacks() print "weak(d) after GC2: "+str(wkd.get()) print "weak2(l) after GC2: "+str(wkl2()) print "weak2(d) after GC2: "+str(wkd2()) System.gc() time.sleep(2) print "weak(d) after GC3: "+str(wkd.get()) monitor.listWouldDeleteNative() print "" print "leaks after GC3:" monitor.listLeaks() print "" print "====" print "exit" print "===="
def test_native_create_tuple_selfcontaining(self): l = DemoExtension.createTupleSelfContaining() self.assertEqual(str(l[:2]), "('tp1', 'tp2')") self.assertEqual(str(l[2]), "['lst1', ('tp1', 'tp2', [...])]")
#build with an IDE in debug mode: sys.path.append('../../DemoExtension/Debug') #in case you run it from src dir sys.path.append('./DemoExtension/Debug') #in case you run it from base dir #build with an IDE in release mode: sys.path.append('../../DemoExtension/Release') #in case you run it from src dir sys.path.append('./DemoExtension/Release') #in case you run it from base dir #build with setup.py on 64 bit machine: sys.path.append('../../DemoExtension/build/lib.linux-x86_64-2.7') #in case you run it from src dir sys.path.append('./DemoExtension/build/lib.linux-x86_64-2.7') #in case you run it from base dir #build with setup.py on 32 bit machine: sys.path.append('../../DemoExtension/build/lib.linux-i686-2.7') #in case you run it from src dir sys.path.append('./DemoExtension/build/lib.linux-i686-2.7') #in case you run it from base dir import DemoExtension #import java.lang.System as jsys #jsys.out.println("Jython is running!") #print "-------------------" print "sys.exc_info, initial: "+str(sys.exc_info()) try: print "We call a native method that creates an exception. However, this time we handle it..." DemoExtension.exceptionTest() except SystemError: print "...and entered except-area!" print "sys.exc_info: "+str(sys.exc_info()) print "Now lets look, what happens, if the exception is uncaught:" DemoExtension.exceptionTest() print "------------------- this line should never be printed"
def test_native_import_API_and_methoddescr(self): self.assertEqual(DemoExtension.importAPIandMethodDescrTest(), 0)
def test_unicode(self): uc = u'a\xac\u1234\u20ac\U00008000' uc2 = DemoExtension.unicodeTest(uc) self.assertEqual(uc, uc2)
def run1(): JyNI.JyRefMonitor_setMemDebugFlags(1) JyWeakReferenceGC.monitorNativeCollection = True # PyType <- Make native ref-cycle test with heap type to test partly-stub-mode. # PySet, but no native link to other PyObject # PyFrozenSet, " # PyCode, not GC-relevant in CPython import DemoExtension #Note: # For now we attempt to verify JyNI's GC-functionality independently from # Jython concepts like Jython weak references or Jython GC-module. # So we use java.lang.ref.WeakReference and java.lang.System.gc to monitor # and control Java-gc. #JyNI.JyRefMonitor_setMemDebugFlags(1) #JyWeakReferenceGC.monitorNativeCollection = True #l = (123,) l = ([0, "test"], ) l[0][0] = l #l = (123, {'a': 0, 'b': "test"}) #l[1]['a'] = l #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) print "weak(l): " + str(wkl.get()) # We pass down l to some native method. We don't care for the method itself, # but conversion to native side causes creation of native PyObjects that # correspond to l and its elements. We will then track the life-cycle of these. print "make l native..." DemoExtension.argCountToString(l) #print "argCountToString.__doc__-address: "+str(JyNI.lookupNativeHandle(DemoExtension.argCountToString.__doc__)) #print "We access a method-doc as this used to cause problems with GC:" #print " "+DemoExtension.argCountToString.__doc__ #print "Native static objects so far:" #print JyNI.nativeStaticPyObjectHeads.keySet() print "Delete l... (but GC not yet ran)" del l #l = None print "weak(l) after del: " + str(wkl.get()) print "" # monitor.list-methods display the following format: # [native pointer]{'' | '_GC_J' | '_J'} ([type]) #[native ref-count]: [repr] *[creation time] # _GC_J means that JyNI tracks the object # _J means that a JyNI-GC-head exists, but the object is not actually treated by GC # This can serve monitoring purposes or soft-keep-alive (c.f. java.lang.ref.SoftReference) # for caching. print "Leaks before GC:" monitor.listLeaks() print "" # By inserting this line you can confirm that native # leaks would persist if JyNI-GC is not working: #JyWeakReferenceGC.nativecollectionEnabled = False print "calling Java-GC..." System.gc() time.sleep(2) print "weak(l) after GC: " + str(wkl.get()) print "" monitor.listWouldDeleteNative() print "" print "leaks after GC:" monitor.listLeaks() print "" print " " + DemoExtension.argCountToString.__doc__ monitor.listLeaks() #print "----" #print monitor.listAll() print "" print "====" print "exit" print "===="
#built with an IDE in debug mode: sys.path.append('../../DemoExtension/Debug') #in case you run it from src dir sys.path.append('./DemoExtension/Debug') #in case you run it from base dir #built with an IDE in release mode: sys.path.append( '../../DemoExtension/Release') #in case you run it from src dir sys.path.append('./DemoExtension/Release') #in case you run it from base dir #built with setup.py: sys.path.append('../../DemoExtension/build/lib.' + buildf + '-2.7') #in case you run it from src dir sys.path.append('./DemoExtension/build/lib.' + buildf + '-2.7') #in case you run it from base dir import DemoExtension #import java.lang.System as jsys #jsys.out.println("Jython is running!") #print "-------------------" print "sys.exc_info, initial: " + str(sys.exc_info()) try: print "We call a native method that creates an exception. However, this time we handle it..." DemoExtension.exceptionTest() except SystemError: print "...and entered except-area!" print "sys.exc_info: " + str(sys.exc_info()) print "Now lets look, what happens, if the exception is uncaught:" DemoExtension.exceptionTest() print "------------------- this line should never be printed"
def test_native_create_list_selfcontaining(self): l = DemoExtension.createListSelfContaining() self.assertEqual(str(l), "['element1', 'element2', [...]]")
# and control Java-gc. JyNI.JyRefMonitor_setMemDebugFlags(1) JyWeakReferenceGC.monitorNativeCollection = True l = (123, [0, "test"]) l[1][0] = l #We create weak reference to l to monitor collection by Java-GC: wkl = WeakReference(l) print "weak(l): "+str(wkl.get()) # We pass down l to some native method. We don't care for the method itself, # but conversion to native side causes creation of native PyObjects that # correspond to l and its elements. We will then track the life-cycle of these. print "make l native..." DemoExtension.argCountToString(l) print "Delete l... (but GC not yet ran)" del l print "weak(l) after del: "+str(wkl.get()) print "" # monitor.list-methods display the following format: # [native pointer]{'' | '_GC_J' | '_J'} ([type]) #[native ref-count]: [repr] *[creation time] # _GC_J means that JyNI tracks the object # _J means that a JyNI-GC-head exists, but the object is not actually treated by GC # This can serve monitoring purposes or soft-keep-alive (c.f. java.lang.ref.SoftReference) # for caching. print "Leaks before GC:" monitor.listLeaks() print ""
print DemoExtension print DemoExtension.__doc__ # If you run this via Jython, you can uncomment the following lines to prove that Jython is running. # With these lines this demo becomes a program that neither Jython without JyNI, # nor ordinary CPython could run. #print "To prove that Jython is running, we make a java call:" #from java.lang import System #print "System.currentTimeMillis: "+str(System.currentTimeMillis()) print "" print "--------Hello World----------" print DemoExtension.hello_world print DemoExtension.hello_world.__doc__ DemoExtension.hello_world() print "" print "--------Argument passing----------" print DemoExtension.concatFirstWithLastString.__doc__ print DemoExtension.concatFirstWithLastString("begin_", "ignore", "ignore too", "end") print DemoExtension.argCountToString.__doc__ print DemoExtension.argCountToString("a", "b", "c", "d", "e", "f") print "" print "--------Argument passing with keywords----------" DemoExtension.keywordTest("first", "second", right="Hey", wrong="nothing") print "(in JyNI-case see bottom for native outputs)" print ""