def main(): from sys import argv if '--pickle' in argv: soft = stackless.enable_softswitch( False) # no crash, if soft switching try: p = pickle_current_frame() finally: stackless.enable_softswitch(soft) p = pickletools.optimize(p) print('Pickle as bytes: ', repr(p)) else: if bytes is str: # pickle created with Stackless v2.7.6r3, hg commt id 67088aa2da77 p = b'\x80\x02c_stackless._wrap\nframe\nc_stackless._wrap\ncode\nq\x01(K\x00K\x01K\x03J\x03`\x03\x00U?g\x00\x00\x89\x00\x00\x87\x00\x00f\x01\x00d\x01\x00\x86\x00\x00}\x00\x00t\x00\x00j\x01\x00\x83\x00\x00j\x02\x00|\x00\x00t\x00\x00j\x03\x00f\x01\x00\x83\x02\x00j\x04\x00\x83\x00\x00\x01\x88\x00\x00d\x02\x00\x19SNh\x01(K\x01K\x01K\x04J\x13`\x03\x00U \x88\x00\x00j\x00\x00t\x01\x00j\x02\x00|\x00\x00j\x03\x00d\x01\x00\x83\x02\x00\x83\x01\x00\x01d\x00\x00SNJ\xff\xff\xff\xff\x86(U\x06appendU\x06pickleU\x05dumpsU\x05frametU\x07currentq\n\x85U)Stackless/test/unpickle_crash_ticket61.pyU\x04funcq\rK\x12U\x02\x00\x01U\x06resultq\x0f\x85)tR)bK\x00\x87(U\tstacklessU\x07taskletU\x04bindh\nU\x03runth\r\x85U)Stackless/test/unpickle_crash_ticket61.pyU\x14pickle_current_frameK\x0fU\x08\x00\x01\x06\x02\x0f\x02"\x01)h\x0f\x85tRq\x1f)b\x85R(h\x1fK\x00U\x10eval_frame_valuec__builtin__\ngetattr\nc__builtin__\n__import__\n(U\x08__main__))U\x00\x85tRU\x08__dict__\x86RK\x00}NNK3K\x0f)Ntb.' else: # pickle created with Stackless v3.3.5 p = b'\x80\x03c_stackless._wrap\nframe\nc_stackless._wrap\ncode\nq\x01(K\x00K\x00K\x01K\x03K\x03CBg\x00\x00\x89\x00\x00\x87\x00\x00f\x01\x00d\x01\x00d\x02\x00\x86\x00\x00}\x00\x00t\x00\x00j\x01\x00\x83\x00\x00j\x02\x00|\x00\x00t\x00\x00j\x03\x00f\x01\x00\x83\x02\x00j\x04\x00\x83\x00\x00\x01\x88\x00\x00d\x03\x00\x19S(Nh\x01(K\x01K\x00K\x01K\x04K\x13C \x88\x00\x00j\x00\x00t\x01\x00j\x02\x00|\x00\x00j\x03\x00d\x02\x00\x83\x02\x00\x83\x01\x00\x01d\x00\x00SNK\x01J\xff\xff\xff\xff\x87(X\x06\x00\x00\x00appendX\x06\x00\x00\x00pickleX\x05\x00\x00\x00dumpsX\x05\x00\x00\x00frametX\x07\x00\x00\x00currentq\n\x85X)\x00\x00\x00Stackless/test/unpickle_crash_ticket61.pyq\x0cX\x04\x00\x00\x00funcq\rK\x0fC\x02\x00\x01X\x06\x00\x00\x00resultq\x0f\x85)tR)bX"\x00\x00\x00pickle_current_frame.<locals>.funcK\x00t(X\t\x00\x00\x00stacklessX\x07\x00\x00\x00taskletX\x04\x00\x00\x00bindh\nX\x03\x00\x00\x00runth\r\x85h\x0cX\x14\x00\x00\x00pickle_current_frameK\x0cC\x08\x00\x01\x06\x02\x12\x02"\x01)h\x0f\x85tRq\x1f)b\x85R(h\x1fK\x00X\x10\x00\x00\x00eval_frame_valuecbuiltins\ngetattr\ncimportlib\nimport_module\nX\x08\x00\x00\x00__main__\x85RX\x08\x00\x00\x00__dict__\x86RK\x00}NNK6K\x0c)Ntb.' if '--dis' in argv: pickletools.dis(p) else: frame = pickle.loads(p) frame.f_locals # this line crashes Stackless print("No Crash, OK")
def lifecycle(self, t): # Initial state - unrun self.assertTrue(t.alive) self.assertTrue(t.scheduled) self.assertEqual(t.recursion_depth, 0) # allow hard switching t.set_ignore_nesting(1) softSwitching = stackless.enable_softswitch(0); stackless.enable_softswitch(softSwitching) # Run a little res = stackless.run(10) self.assertEqual(t, res) self.assertTrue(t.alive) self.assertTrue(t.paused) self.assertFalse(t.scheduled) self.assertEqual(t.recursion_depth, softSwitching and 1 or 2) # Push back onto queue t.insert() self.assertFalse(t.paused) self.assertTrue(t.scheduled) # Run to completion stackless.run() self.assertFalse(t.alive) self.assertFalse(t.scheduled) self.assertEqual(t.recursion_depth, 0)
def lifecycle(self, t): # Initial state - unrun self.assertTrue(t.alive) self.assertTrue(t.scheduled) self.assertEqual(t.recursion_depth, 0) # allow hard switching t.set_ignore_nesting(1) softSwitching = stackless.enable_softswitch(0) stackless.enable_softswitch(softSwitching) # Run a little res = stackless.run(10) self.assertEqual(t, res) self.assertTrue(t.alive) self.assertTrue(t.paused) self.assertFalse(t.scheduled) self.assertEqual(t.recursion_depth, 1) # Push back onto queue t.insert() self.assertFalse(t.paused) self.assertTrue(t.scheduled) # Run to completion stackless.run() self.assertFalse(t.alive) self.assertFalse(t.scheduled) self.assertEqual(t.recursion_depth, 0)
def main(): soft = stackless.enable_softswitch(False) try: p_hard = reduce_current() finally: stackless.enable_softswitch(soft) p_soft = reduce_current() c = p_soft[1][0] c = dict(co_argcount=c.co_argcount, co_nlocals=c.co_nlocals, co_varnames=c.co_varnames, co_cellvars=c.co_cellvars, co_freevars=c.co_freevars, co_consts=c.co_consts, co_names=c.co_names, co_stacksize=c.co_stacksize) state_soft = dict(FrameState(*p_soft[2])._asdict()) state_hard = dict(FrameState(*p_hard[2])._asdict()) del state_hard['f_globals'] del state_soft['f_globals'] import pprint print("code") pprint.pprint(c) print("soft switching") pprint.pprint(state_soft) print("hard switching") pprint.pprint(state_hard)
def testTemporaryChannel(self): def f1(): stackless.channel().receive() stackless.tasklet(f1)() old = stackless.enable_softswitch(True) try: stackless.run() finally: stackless.enable_softswitch(old)
def prepare_tasklet(self, task=None): if task is None: task = self.__task self.tasklet_done = False t = stackless.tasklet(self.__task)() sw = stackless.enable_softswitch(False) try: t.run() finally: stackless.enable_softswitch(sw) return t
def setUpStacklessTestCase(self): """Initialisation This method must be called from :meth:`setUp`. """ self._StacklessTestCase__setup_called = True self.addCleanup(stackless.enable_softswitch, stackless.enable_softswitch(self.__enable_softswitch)) self.__active_test_cases[id(self)] = self self.__uncollectable_tasklets = [] self.__initial_cstack_serial = get_serial_last_jump() self.assertListEqual( [t for t in gc.garbage if isinstance(t, stackless.tasklet)], [], "Leakage from other tests, with tasklets in gc.garbage") watchdog_list = get_watchdog_list(-1) if watchdog_list is not None: self.assertListEqual( watchdog_list, [None], "Watchdog list is not empty: " + repr(watchdog_list)) if withThreads and self.__preexisting_threads is None: self.__preexisting_threads = frozenset(threading.enumerate()) for (watchdog_list, tid) in [(get_watchdog_list(tid), tid) for tid in stackless.threads if tid != stackless.current.thread_id ]: if watchdog_list is None: continue self.assertListEqual( watchdog_list, [None], "Thread %d: watchdog list is not empty: %r" % (tid, watchdog_list)) return len(self.__preexisting_threads) return 1
def test_bind(self): t = stackless.tasklet() wr = weakref.ref(t) self.assertFalse(t.alive) self.assertIsNone(t.frame) self.assertEquals(t.nesting_level, 0) t.bind(None) # must not change the tasklet self.assertFalse(t.alive) self.assertIsNone(t.frame) self.assertEquals(t.nesting_level, 0) t.bind(self.task) t.setup(False) stackless.run() self.assertFalse(t.scheduled) self.assertTrue(t.alive) if stackless.enable_softswitch(None): self.assertTrue(t.restorable) self.assertIsInstance(t.frame, types.FrameType) t.insert() stackless.run() # remove the tasklet. Must run the finally clause t = None self.assertIsNone(wr()) # tasklet has been deleted self.assertEqual(self.finally_run_count, 1)
def nestingLevelTest(self, cls): # check the nesting level and the ref counts def func(obj=None): if obj is None: self.assertGreater(stackless.current.nesting_level, 0) return None self.assertIs(obj.__class__, cls) obj.nesting_level = stackless.current.nesting_level return None cls(func ).__class__ # the first access of __class__ releases 1 ref to None with stackless.atomic(): # None-refcount needs protection, it the test suite is multithreaded gc.collect() rc_none = rc_none2 = sys.getrefcount(None) rc_cls = rc_cls2 = sys.getrefcount(cls) c = cls(func) rc_none2 = sys.getrefcount(None) rc_cls2 = sys.getrefcount(cls) self.assertEqual(rc_none, rc_none2) self.assertEqual(rc_cls + 1, rc_cls2) # one ref for c self.assertEqual(sys.getrefcount(c) - sys.getrefcount(object()), 1) self.assertIs(c.__class__, cls) current_nesting_level = stackless.current.nesting_level if hasattr(c, "nesting_level"): if stackless.enable_softswitch(None): self.assertEqual(c.nesting_level, current_nesting_level) else: self.assertGreater(c.nesting_level, current_nesting_level) c = None gc.collect() self.assertEqual(sys.getrefcount(cls), rc_cls)
def wrapper_hardswitch(self, method=func): self.assertTrue( self.__setup_called, "Broken test case: it didn't call super(..., self).setUp()") self.assertFalse(stackless.enable_softswitch(None), "softswitch is enabled") return method(self)
def test_deep_tasklets(self): # test for issue #103 https://bitbucket.org/stackless-dev/stackless/issues/103/ args = [] if not stackless.enable_softswitch(None): args.append("--hard") rc = subprocess.call([sys.executable, "-s", "-S", "-E", "-c", """from __future__ import print_function, absolute_import\nif 1: import stackless import sys from stackless import _test_nostacklesscall as apply if "--hard" in sys.argv: stackless.enable_softswitch(False) RECURSION_DEPTH = 200 def recurse(): if stackless.current.nesting_level < RECURSION_DEPTH: stackless.schedule() apply(recurse) else: stackless.schedule_remove() tasklets = [] for i in range(20): task = stackless.tasklet(recurse)() tasklets.append(task) # keep the tasklet objects alive stackless.run() # print("end") sys.stdout.flush() sys.exit(42) """] + args) self.assertEqual(rc, 42)
def testThreadShutdown_nl0_blocked(self): c = stackless.channel() def func(main): c.receive() self._test_thread_shutdown(func, not stackless.enable_softswitch(None))
def run(): try: # Test preconditions: current is main at level 0 if stackless.enable_softswitch(None): self.assertEqual(stackless.current.nesting_level, 0) self.assertIs(stackless.current, stackless.main) thread_initial_stub = current_initial_stub() # sanity check self.assertEqual(get_serial_last_jump(), thread_initial_stub.serial) # a tasklet with a different C-stack # test_cstate forces a hard switch from schedule_remove t = tasklet(test_cstate)(stackless.schedule_remove) t_cstate = t.cstate # now t has a cstate, that belongs to thread_initial_stub # check it self.assertIsNot(t_cstate, thread_initial_stub) self.assertEqual(t_cstate.serial, thread_initial_stub.serial) # Run t from a new entry point. # Hard switch to t, # run t and # hard switch back to the main tasklet test_outside() # run scheduled tasklets self.assertEqual(t.nesting_level, 1) # It was a hard switch back to main # t has now it's own stack created from a different entry point self.assertIsNot(t.cstate, t_cstate) self.assertNotEqual(t.cstate.serial, thread_initial_stub.serial) t_serial = t.cstate.serial # soft-to-hard switch to t, finish t and soft-switch back t.run() self.assertEqual(t.nesting_level, 0) # Soft switching was possible if stackless.enable_softswitch(None): # Final test: the current serial has changed. self.assertNotEqual(get_serial_last_jump(), thread_initial_stub.serial) self.assertEqual(get_serial_last_jump(), t_serial) else: self.assertEqual(get_serial_last_jump(), thread_initial_stub.serial) except Exception as e: self.result = e else: self.result = False
def test_aliveness3(self): """ Same as 1, but with a pickled run(slightly) tasklet. """ t = stackless.tasklet(runtask)() t.set_ignore_nesting(1) # Initial state - unrun self.assertTrue(t.alive) self.assertTrue(t.scheduled) self.assertEqual(t.recursion_depth, 0) softSwitching = stackless.enable_softswitch(0) stackless.enable_softswitch(softSwitching) # Run a little res = stackless.run(100) self.assertEqual(t, res) self.assertTrue(t.alive) self.assertTrue(t.paused) self.assertFalse(t.scheduled) self.assertEqual(t.recursion_depth, 1) # Now save & load dumped = self.dumps(t) t_new = self.loads(dumped) # Remove and insert & swap names around a bit t.remove() t = t_new del t_new t.insert() self.assertTrue(t.alive) self.assertFalse(t.paused) self.assertTrue(t.scheduled) self.assertEqual(t.recursion_depth, 1) # Run to completion if is_soft(): stackless.run() else: t.kill() self.assertFalse(t.alive) self.assertFalse(t.scheduled) self.assertEqual(t.recursion_depth, 0)
def interpreter_shutdown_test(): global ready stackless.enable_softswitch('--hard' not in sys.argv) sys.stdout = sys.stderr # This lock is used as a simple event variable. ready = thread.allocate_lock() ready.acquire() test = Test() detector = Detector(test.out, test.checks, test.tasklets) assert sys.getrefcount(detector) - sys.getrefcount(object()) == 2 detector = None # the last ref is now in bultins._ thread.start_new_thread(test.other_thread_main, ()) ready.acquire() # Be sure the other thread is ready. # print("at end") sys.exit(Detector.EXIT_BASE) # trigger interpreter shutdown
def test_aliveness3(self): """ Same as 1, but with a pickled run(slightly) tasklet. """ t = stackless.tasklet(runtask)() t.set_ignore_nesting(1) # Initial state - unrun self.assertTrue(t.alive) self.assertTrue(t.scheduled) self.assertEqual(t.recursion_depth, 0) softSwitching = stackless.enable_softswitch(0); stackless.enable_softswitch(softSwitching) # Run a little res = stackless.run(100) self.assertEqual(t, res) self.assertTrue(t.alive) self.assertTrue(t.paused) self.assertFalse(t.scheduled) self.assertEqual(t.recursion_depth, softSwitching and 1 or 2) # Now save & load dumped = pickle.dumps(t) t_new = pickle.loads(dumped) # Remove and insert & swap names around a bit t.remove() t = t_new del t_new t.insert() self.assertTrue(t.alive) self.assertFalse(t.paused) self.assertTrue(t.scheduled) self.assertEqual(t.recursion_depth, 1) # Run to completion if is_soft(): stackless.run() else: t.kill() self.assertFalse(t.alive) self.assertFalse(t.scheduled) self.assertEqual(t.recursion_depth, 0)
def other_thread_main(self): assert stackless.main is stackless.current self.main = stackless.main if self.debug: print("other thread started, soft %s, running %s, nl %d" % (stackless.enable_softswitch(None), self.running, self.main.nesting_level)) if isinstance(self.case, int) and self.case >= 0: assert 0 <= self.case < len(self.CASES) * 2 self.checks.append("failed to start %s, case %d" % (self.CASES[self.case >> 1][0], self.case))
def setUp(self): self._ran_AsTaskletTestCase_setUp = True if stackless.enable_softswitch(None): self.assertEqual(stackless.current.nesting_level, 0) super(StacklessTestCase, self).setUp() # yes, its intended: call setUp on the grand parent class self.assertEqual(stackless.getruncount(), 1, "Leakage from other tests, with %d tasklets still in the scheduler" % (stackless.getruncount() - 1)) if withThreads: self.assertEqual(threading.activeCount(), 1, "Leakage from other threads, with %d threads running (1 expected)" % (threading.activeCount()))
def _test_kill_without_thread_state(self, nl, block): channel = stackless.channel() loop = True def task(): while loop: try: if block: channel.receive() else: stackless.main.run() except TaskletExit: pass def other_thread_main(): tlet.bind_thread() tlet.run() if nl == 0: tlet = stackless.tasklet().bind(task, ()) else: tlet = stackless.tasklet().bind(apply, (task, ())) t = threading.Thread(target=other_thread_main, name="other thread") t.start() t.join() time.sleep(0.05) # time for other_thread to clear its state loop = False if block: self.assertTrue(tlet.blocked) else: self.assertFalse(tlet.blocked) self.assertFalse(tlet.alive) self.assertEqual(tlet.thread_id, -1) self.assertRaisesRegex(RuntimeError, "tasklet has no thread", tlet.throw, TaskletExit, pending=True) tlet.kill(pending=True) self.assertFalse(tlet.blocked) if self.SLP_TASKLET_KILL_REBINDS_THREAD and stackless.enable_softswitch( None) and nl == 0: # rebinding and soft switching self.assertTrue(tlet.scheduled) self.assertTrue(tlet.alive) tlet.remove() tlet.bind(None) else: # hard switching self.assertFalse(tlet.scheduled) self.assertIsNone(tlet.next) self.assertIsNone(tlet.prev) self.assertFalse(tlet.alive) tlet.remove() tlet.kill()
def callIndirect(self): if not stackless.enable_softswitch(None): # without soft switching, we always get an increased nesting level return self.assertEqual(stackless.getcurrent().nesting_level, 0) b = self.B() result = b(self.callback, 4711, post_callback=self.post_callback) self.assertTrue(self.callback_called) self.assertTrue(self.post_callback_called) self.assertEqual(result, 4711)
def callIndirect(self): if not stackless.enable_softswitch(None): # without soft switching, we always get an increased nesting level return self.assertEqual(stackless.getcurrent().nesting_level, 0) b=self.B() result = b(self.callback, 4711, post_callback=self.post_callback) self.assertTrue(self.callback_called) self.assertTrue(self.post_callback_called) self.assertEqual(result, 4711)
def wrapper(self): if soft_switching is not None and stackless.enable_softswitch( None) != soft_switching: # the leak happens only if soft switching is enables/disabled return testcase(self) for frameinfo in inspect.stack(0): # print("frameinfo[3]", frameinfo[3], file=sys.stderr) if frameinfo[3] == "dash_R": # it is a test.regrtest -R: run return self.skipTest("Test leaks references: " + leak_reason) return testcase(self)
def setUp(self): self._ran_AsTaskletTestCase_setUp = True if stackless.enable_softswitch(None): self.assertEqual(stackless.current.nesting_level, 0) # yes, its intended: call setUp on the grand parent class super(StacklessTestCase, self).setUp() expected_thread_count = self.setUpStacklessTestCase() self.assertEqual(stackless.getruncount( ), 1, "Leakage from other tests, with %d tasklets still in the scheduler" % (stackless.getruncount() - 1)) if withThreads: active_count = threading.active_count() self.assertEqual(active_count, expected_thread_count, "Leakage from other threads, with %d threads running (%d expected)" % (active_count, expected_thread_count))
def setUpStacklessTestCase(self): """Initialisation This method must be called from :meth:`setUp`. """ self._StacklessTestCase__setup_called = True self.addCleanup(stackless.enable_softswitch, stackless.enable_softswitch(self.__enable_softswitch)) self.__active_test_cases[id(self)] = self if withThreads and self.__preexisting_threads is None: self.__preexisting_threads = frozenset(threading.enumerate()) return len(self.__preexisting_threads) return 1
def main(): path = os.path.split(__file__)[0] hold = stackless.enable_softswitch(True) try: target = int(sys.argv[1]) except IndexError: try: target = TARGET except NameError: target = 0 try: flags = True, False if target: flags = (flags[target > 0],) if abs(target) == 42: target = 0 for switch in flags: stackless.enable_softswitch(switch) testSuite = makeSuite(abs(target), path) unittest.TextTestRunner().run(testSuite) finally: stackless.enable_softswitch(hold)
def test_exit_in_deep_tasklet2(self): # test for issue #103 https://github.com/stackless-dev/stackless/issues/103/ args = [] if not stackless.enable_softswitch(None): args.append("--hard") rc = subprocess.call([ sys.executable, "-s", "-S", "-E", "-c", dedent(""" from __future__ import print_function, absolute_import import stackless import sys from _stackless import _test_nostacklesscall as apply if "--hard" in sys.argv: stackless.enable_softswitch(False) RECURSION_DEPTH = 200 last = None def recurse(): global last if stackless.current.nesting_level < RECURSION_DEPTH: stackless.schedule() apply(recurse) else: last = stackless.current sys.exit(42) # deeply nested, non main tasklet tasklets = [] for i in range(20): task = stackless.tasklet(recurse)() tasklets.append(task) # keep the tasklet objects alive try: stackless.run() except TaskletExit: # print("Got TaskletExit", repr(stackless.current.cstate)) sys.stdout.flush() last.run() # switch back sys.exit(43) print("OOPS, must not be reached") sys.stdout.flush() sys.exit(44) """) ] + args) self.assertEqual(rc, 42)
def main(): path = os.path.split(__file__)[0] print path hold = stackless.enable_softswitch(True) try: target = int(sys.argv[1]) del sys.argv[1] except (IndexError, ValueError): try: target = TARGET except NameError: target = 0 for use_psyco in (False, True): if use_psyco: # we import psyco so late, because we want to avoid side-effects # from functions like sys.getframe, which are overridden at import # time. try: import psyco if not psyco._psyco.stackless_compatible: raise AttributeError psyco.full() except (ImportError, AttributeError): break try: flags = True, False if target: flags = (flags[target > 0],) if abs(target) == 42: target = 0 for switch in flags: stackless.enable_softswitch(switch) testSuite = makeSuite(abs(target), path) unittest.TextTestRunner(verbosity=2).run(testSuite) finally: stackless.enable_softswitch(hold)
def main(): from sys import argv if '--pickle' in argv: soft = stackless.enable_softswitch(False) # no crash, if soft switching try: p = pickle_current_frame() finally: stackless.enable_softswitch(soft) p = pickletools.optimize(p) print('Pickle as bytes: ', repr(p)) else: if bytes is str: # pickle created with Stackless v2.7.6r3, hg commt id 67088aa2da77 p = b'\x80\x02c_stackless._wrap\nframe\nc_stackless._wrap\ncode\nq\x01(K\x00K\x01K\x03J\x03`\x03\x00U?g\x00\x00\x89\x00\x00\x87\x00\x00f\x01\x00d\x01\x00\x86\x00\x00}\x00\x00t\x00\x00j\x01\x00\x83\x00\x00j\x02\x00|\x00\x00t\x00\x00j\x03\x00f\x01\x00\x83\x02\x00j\x04\x00\x83\x00\x00\x01\x88\x00\x00d\x02\x00\x19SNh\x01(K\x01K\x01K\x04J\x13`\x03\x00U \x88\x00\x00j\x00\x00t\x01\x00j\x02\x00|\x00\x00j\x03\x00d\x01\x00\x83\x02\x00\x83\x01\x00\x01d\x00\x00SNJ\xff\xff\xff\xff\x86(U\x06appendU\x06pickleU\x05dumpsU\x05frametU\x07currentq\n\x85U)Stackless/test/unpickle_crash_ticket61.pyU\x04funcq\rK\x12U\x02\x00\x01U\x06resultq\x0f\x85)tR)bK\x00\x87(U\tstacklessU\x07taskletU\x04bindh\nU\x03runth\r\x85U)Stackless/test/unpickle_crash_ticket61.pyU\x14pickle_current_frameK\x0fU\x08\x00\x01\x06\x02\x0f\x02"\x01)h\x0f\x85tRq\x1f)b\x85R(h\x1fK\x00U\x10eval_frame_valuec__builtin__\ngetattr\nc__builtin__\n__import__\n(U\x08__main__))U\x00\x85tRU\x08__dict__\x86RK\x00}NNK3K\x0f)Ntb.' else: # pickle created with Stackless v3.3.5 p = b'\x80\x03c_stackless._wrap\nframe\nc_stackless._wrap\ncode\nq\x01(K\x00K\x00K\x01K\x03K\x03CBg\x00\x00\x89\x00\x00\x87\x00\x00f\x01\x00d\x01\x00d\x02\x00\x86\x00\x00}\x00\x00t\x00\x00j\x01\x00\x83\x00\x00j\x02\x00|\x00\x00t\x00\x00j\x03\x00f\x01\x00\x83\x02\x00j\x04\x00\x83\x00\x00\x01\x88\x00\x00d\x03\x00\x19S(Nh\x01(K\x01K\x00K\x01K\x04K\x13C \x88\x00\x00j\x00\x00t\x01\x00j\x02\x00|\x00\x00j\x03\x00d\x02\x00\x83\x02\x00\x83\x01\x00\x01d\x00\x00SNK\x01J\xff\xff\xff\xff\x87(X\x06\x00\x00\x00appendX\x06\x00\x00\x00pickleX\x05\x00\x00\x00dumpsX\x05\x00\x00\x00frametX\x07\x00\x00\x00currentq\n\x85X)\x00\x00\x00Stackless/test/unpickle_crash_ticket61.pyq\x0cX\x04\x00\x00\x00funcq\rK\x0fC\x02\x00\x01X\x06\x00\x00\x00resultq\x0f\x85)tR)bX"\x00\x00\x00pickle_current_frame.<locals>.funcK\x00t(X\t\x00\x00\x00stacklessX\x07\x00\x00\x00taskletX\x04\x00\x00\x00bindh\nX\x03\x00\x00\x00runth\r\x85h\x0cX\x14\x00\x00\x00pickle_current_frameK\x0cC\x08\x00\x01\x06\x02\x12\x02"\x01)h\x0f\x85tRq\x1f)b\x85R(h\x1fK\x00X\x10\x00\x00\x00eval_frame_valuecbuiltins\ngetattr\ncimportlib\nimport_module\nX\x08\x00\x00\x00__main__\x85RX\x08\x00\x00\x00__dict__\x86RK\x00}NNK6K\x0c)Ntb.' if '--dis' in argv: pickletools.dis(p) else: frame = pickle.loads(p) frame.f_locals # this line crashes Stackless print("No Crash, OK")
def test_other_thread_Py_Exit(self): # test for issue #103 https://github.com/stackless-dev/stackless/issues/103/ try: import ctypes # @UnusedImport except ImportError: self.skipTest("test requires ctypes") args = [] if not stackless.enable_softswitch(None): args.append("--hard") rc = subprocess.call([ sys.executable, "-s", "-S", "-E", "-c", dedent(""" from __future__ import print_function, absolute_import import stackless import sys import ctypes import threading import time if "--hard" in sys.argv: stackless.enable_softswitch(False) Py_Exit = ctypes.pythonapi.Py_Exit Py_Exit.restype = None Py_Exit.argtypes = (ctypes.c_int,) def exit(): # print("Calling Py_Exit(42)") time.sleep(0.1) sys.stdout.flush() Py_Exit(42) t = threading.Thread(target=exit, name="othere_thread") t.daemon = True t.start() time.sleep(1) print("OOPS, must not be reached") sys.stdout.flush() sys.exit(43) """) ] + args) self.assertEqual(rc, 42)
def test_deep_Py_Exit(self): # test for issue #103 https://github.com/stackless-dev/stackless/issues/103/ try: import ctypes # @UnusedImport except ImportError: self.skipTest("test requires ctypes") args = [] if not stackless.enable_softswitch(None): args.append("--hard") rc = subprocess.call([ sys.executable, "-s", "-S", "-E", "-c", dedent(""" from __future__ import print_function, absolute_import import stackless import sys import ctypes from _stackless import _test_nostacklesscall as apply if "--hard" in sys.argv: stackless.enable_softswitch(False) RECURSION_DEPTH = 200 Py_Exit = ctypes.pythonapi.Py_Exit Py_Exit.restype = None Py_Exit.argtypes = (ctypes.c_int,) def recurse(): if stackless.current.nesting_level < RECURSION_DEPTH: apply(recurse) else: sys.stdout.flush() Py_Exit(42) recurse() print("OOPS, must not be reached") sys.stdout.flush() sys.exit(43) """) ] + args) self.assertEqual(rc, 42)
def do_test(self, CallableClass, methodCall): if not stackless.enable_softswitch(None): # without soft switching, we always get an increased nesting level return tasklet = stackless.getcurrent() current_nesting_level = tasklet.nesting_level self.assertEqual(current_nesting_level, 0, msg="Precondition not met: nesting level is %d" % (current_nesting_level,)) # create the callable object callable_object = CallableClass() self.assertTrue(callable(callable_object)) if methodCall: # invoke the method __call__. This works fine callable_object.__call__(self, current_nesting_level) else: # call the callable object via __call__ callable_object(self, current_nesting_level)
def testLocalplus(self): result = [] def reduce_current(): """This function has exactly one local variable (func), one cellvar (result2) and one freevar (result)""" result2 = result # create the cell variable def func(current): result2.append( stackless._stackless._wrap.frame.__reduce__(current.frame)) stackless.tasklet().bind(func, (stackless.current, )).run() return result[0] cell_type = type(reduce_current.__closure__[0]) state = reduce_current()[2] self.assertIsInstance(state, tuple) self.assertEqual(len(state), 11) code = state[0] self.assertIsInstance(code, types.CodeType) ncellvars = len(code.co_cellvars) nfreevars = len(code.co_freevars) self.assertEqual(ncellvars, 1) self.assertEqual(nfreevars, 1) localsplus_as_tuple = state[-1] valid = state[1] self.assertEqual( valid, int( stackless.enable_softswitch(None) and stackless.current.nesting_level == 0)) self.assertIsInstance(localsplus_as_tuple, tuple) self.assertGreaterEqual(len(localsplus_as_tuple), 1 + code.co_nlocals + ncellvars + nfreevars) for i in range(ncellvars + nfreevars): cell = localsplus_as_tuple[1 + code.co_nlocals + i] self.assertIsInstance(cell, cell_type) self.assertIs(cell.cell_contents, result)
def test_deep_thread(self): # test for issue #103 https://github.com/stackless-dev/stackless/issues/103/ args = [] if not stackless.enable_softswitch(None): args.append("--hard") rc = subprocess.call([ sys.executable, "-s", "-S", "-E", "-c", dedent(""" from __future__ import print_function, absolute_import import threading import stackless import time import sys from _stackless import _test_nostacklesscall as apply if "--hard" in sys.argv: stackless.enable_softswitch(False) RECURSION_DEPTH = 200 event = threading.Event() def recurse(): if stackless.current.nesting_level < RECURSION_DEPTH: apply(recurse) else: event.set() time.sleep(10) t = threading.Thread(target=recurse, name="other_thread") t.daemon = True t.start() event.wait(10) # print("end") sys.stdout.flush() sys.exit(42) """) ] + args) self.assertEqual(rc, 42)
def test_unbind_ok(self): if not stackless.enable_softswitch(None): # the test requires softswitching return t = stackless.tasklet(self.task)(False) wr = weakref.ref(t) # prepare a paused tasklet stackless.run() self.assertFalse(t.scheduled) self.assertTrue(t.alive) self.assertEqual(t.nesting_level, 0) self.assertIsInstance(t.frame, types.FrameType) t.bind(None) self.assertFalse(t.alive) self.assertIsNone(t.frame) # remove the tasklet. Must not run the finally clause t = None self.assertIsNone(wr()) # tasklet has been deleted self.assertEqual(self.finally_run_count, 0)
def do_test(self, CallableClass, methodCall): if not stackless.enable_softswitch(None): # without soft switching, we always get an increased nesting level return tasklet = stackless.getcurrent() current_nesting_level = tasklet.nesting_level self.assertEqual(current_nesting_level, 0, msg="Precondition not met: nesting level is %d" % (current_nesting_level, )) # create the callable object callable_object = CallableClass() self.assertTrue(callable(callable_object)) if methodCall: # invoke the method __call__. This works fine callable_object.__call__(self, current_nesting_level) else: # call the callable object via __call__ callable_object(self, current_nesting_level)
def test_kill_modifies_slp_cstack_chain(self): # test for issue #105 https://github.com/stackless-dev/stackless/issues/105/ args = [] if not stackless.enable_softswitch(None): args.append("--hard") rc = subprocess.call([ sys.executable, "-s", "-S", "-E", "-c", dedent(""" from __future__ import print_function, absolute_import, division import gc import threading import stackless import time import sys from _stackless import _test_nostacklesscall as apply DEBUG = False event = threading.Event() if not DEBUG: def print(*args, **kw): pass def mytask(): stackless.schedule_remove() class TaskHolder(object): def __init__(self, task): self.task = task def __del__(self): while self.task.alive: time.sleep(0.1) print("TaskHolder.__del__, task1 is still alive") print("TaskHolder.__del__: task1 is now dead") self.task = None def other_thread(): # create a paused tasklet task1 = stackless.tasklet(apply)(mytask) stackless.run() assert(task1.alive) assert(task1.paused) assert(task1.nesting_level > 0) assert(task1 is task1.cstate.task) assert(len(str(task1.cstate)) > 0) assert(sys.getrefcount(task1.cstate) - sys.getrefcount(object()) == 1) assert(task1.tempval is task1) assert(sys.getrefcount(task1) - sys.getrefcount(object()) == 2) task1.tempval = TaskHolder(task1) assert(sys.getrefcount(task1) - sys.getrefcount(object()) == 2) print("task1", task1) print("task1.cstate", repr(task1.cstate)) print("ending main tasklet of other_thread, going run the scheduler") task1 = None event.set() # sleep for a long time t = 10000 while t > 0: try: t -= 1 stackless.run() time.sleep(0.01) except: pass t = threading.Thread(target=other_thread, name="other_thread") t.daemon = True t.start() event.wait(5.0) print("end") gc.disable() # prevent "uncollectable objects at shutdown" warning sys.exit(42) """) ] + args) self.assertEqual(rc, 42)
for idx, filename in enumerate(glob.glob('test_*.py')): modname = os.path.splitext(os.path.basename(filename))[0] module = __import__(modname) tests = unittest.TestLoader().loadTestsFromModule(module) use_it = target == 0 or idx+1 == target if use_it: suite.addTest(tests) if target > 0: print "single test of '%s', switch=%s" % \ (filename, ("hard", "soft")[getsoft()]) return suite if __name__ == '__main__': hold = stackless.enable_softswitch(True) try: target = int(sys.argv[1]) except IndexError: try: target = TARGET except NameError: target = 0 try: flags = True, False if target: flags = (flags[target > 0],) if abs(target) == 42: target = 0 for switch in flags: stackless.enable_softswitch(switch)
def test_nestingLevel(self): if not stackless.enable_softswitch(None): # the test requires softswitching return stackless.tasklet(self.nestingLevel)() stackless.run()
def skipUnlessSoftswitching(self): if not stackless.enable_softswitch(None): self.skipTest("test requires softswitching")
def testThreadShutdown_nl0(self): def func(main): main.run() self._test_thread_shutdown(func, not stackless.enable_softswitch(None))
assert bool(self.stackless_getcurrent().nesting_level) is nesting_level, \ "wrong nesting level, expected %s, actual %s" % (nesting_level, bool(self.stackless_getcurrent().nesting_level)) self.main.switch() def tlet_blocked(self, nesting_level, case): assert bool(self.stackless_getcurrent().nesting_level) is nesting_level, \ "wrong nesting level, expected %s, actual %s" % (nesting_level, bool(self.stackless_getcurrent().nesting_level)) self.channel.receive() def wrapper(self, func_name, index, case, nesting_level, expect_kill, may_kill): func = getattr(self, func_name) msg = "killed other thread %s, case %d (with C-state %s)" % ( func_name, case, bool(nesting_level)) msg_killed = "Done: %s%s" % (msg, self.os_linesep) if stackless.enable_softswitch(None): assert self.stackless_getcurrent().nesting_level == 0 if expect_kill: self.checks[index] = "not " + msg checks_killed = None elif may_kill: checks_killed = None self.checks[index] = None else: self.checks[index] = None checks_killed = "unexpectedly " + msg try: if nesting_level == 0: func(bool(self.stackless_getcurrent().nesting_level), case) else:
self.assertEqual(self.done, 2) def test_watchdog_priority_soft(self): """Verify that outermost "real" watchdog gets awoken""" self._test_watchdog_priority(True) def test_watchdog_priority_hard(self): """Verify that outermost "real" watchdog gets awoken (hard)""" self._test_watchdog_priority(False) def load_tests(loader, tests, pattern): """custom loader to run just a subset""" suite = unittest.TestSuite() test_cases = [TestNewWatchdog]#, TestDeadlock] for test_class in test_cases: tests = loader.loadTestsFromTestCase(test_class) suite.addTests(tests) return suite del load_tests #disabled if __name__ == '__main__': import sys if not sys.argv[1:]: sys.argv.append('-v') stackless.enable_softswitch(True) unittest.main(exit=False) stackless.enable_softswitch(False) unittest.main()
def is_soft(): softswitch = stackless.enable_softswitch(0) stackless.enable_softswitch(softswitch) return softswitch and not in_psyco()
def is_soft(): softswitch = stackless.enable_softswitch(0) stackless.enable_softswitch(softswitch) return softswitch
def getsoft(): hold = stackless.enable_softswitch(False) stackless.enable_softswitch(hold) return hold