Skip to content

Commit 1ea32bb

Browse files
author
Anselm Kruis
committed
merge 3.4-slp (Stackless python#107)
2 parents 9457dae + e495a12 commit 1ea32bb

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

Stackless/changelog.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ What's New in Stackless 3.X.X?
99

1010
*Release date: 20XX-XX-XX*
1111

12+
- https://bitbucket.org/stackless-dev/stackless/issues/107
13+
Improve unpickling of traceback objects. Stackless now reconstructs the
14+
frame.f_back linkage in frames directly referenced by traceback objects.
15+
1216
- https://bitbucket.org/stackless-dev/stackless/issues/110
1317
Remove the already non functional remains of psyco support.
1418

Stackless/pickling/prickelpit.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,14 @@ tb_setstate(PyObject *self, PyObject *args)
12061206
tb->tb_lineno = lineno;
12071207
Py_TYPE(tb) = Py_TYPE(tb)->tp_base;
12081208

1209+
if (frame != NULL && next != NULL && next->tb_frame != NULL &&
1210+
(PyObject *)(next->tb_frame->f_back) == Py_None) {
1211+
/* Reconstruct the f_back chain as far as possible. */
1212+
next->tb_frame->f_back = frame;
1213+
Py_INCREF(frame);
1214+
Py_DECREF(Py_None);
1215+
}
1216+
12091217
Py_INCREF(self);
12101218
return self;
12111219
}

Stackless/unittests/test_pickle.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import unittest
44
import pickle
55
import gc
6+
import inspect
67

78
from stackless import schedule, tasklet, stackless
89

@@ -606,6 +607,50 @@ class TestDictViewPicklingPy(AbstractTestPickledTasklets, DictViewPicklingTestCa
606607
class TestDictViewPicklingC(AbstractTestPickledTasklets, DictViewPicklingTestCases, CPickleMixin):
607608
pass
608609

610+
611+
class Traceback_TestCases(object):
612+
def testTracebackFrameLinkage(self):
613+
def a():
614+
# raise an exception
615+
1 // 0
616+
617+
def b():
618+
return a()
619+
620+
def c():
621+
return b()
622+
623+
try:
624+
c()
625+
except ZeroDivisionError:
626+
tb = sys.exc_info()[2]
627+
628+
innerframes_orig = inspect.getinnerframes(tb)
629+
p = self.dumps(tb)
630+
tb2 = self.loads(p)
631+
# basics
632+
self.assertIs(type(tb), type(tb2))
633+
self.assertIsNot(tb, tb2)
634+
innerframes = inspect.getinnerframes(tb2)
635+
# compare the content
636+
self.assertListEqual([i[1:] for i in innerframes_orig], [i[1:] for i in innerframes])
637+
# check linkage
638+
all_outerframes_orig = inspect.getouterframes(innerframes_orig[-1][0])
639+
all_outerframes = inspect.getouterframes(innerframes[-1][0])
640+
l = len(innerframes_orig)
641+
self.assertGreater(len(all_outerframes_orig), l)
642+
self.assertGreaterEqual(len(all_outerframes), l)
643+
# compare the content
644+
self.assertListEqual([i[1:] for i in all_outerframes_orig[:l - 1]], [i[1:] for i in all_outerframes[:l - 1]])
645+
646+
647+
class TestTracebackPy(StacklessTestCase, Traceback_TestCases, PyPickleMixin):
648+
pass
649+
650+
651+
class TestTracebackC(StacklessTestCase, Traceback_TestCases, CPickleMixin):
652+
pass
653+
609654
if __name__ == '__main__':
610655
if not sys.argv[1:]:
611656
sys.argv.append('-v')

0 commit comments

Comments
 (0)