Commit 80559a94 authored by Jérome Perrin's avatar Jérome Perrin Committed by Kirill Smelkov

zodbdump: support --pretty option with a format to show pickles disassembly

Showing pickle disassembly can sometimes be useful to analyse details of
the pickle content. We realized that in some data structures used in
ERP5 the same string was saved multiple times in the same pickle and by
using the exact same string (ie. for which `s1 is s2` is True), the
pickle will have the string only once and pickles are a bit smaller. For
more reference, the context was
nexedi/erp5!1560 (comment 154825)

This introduces a new --pretty option that we will be able to extend
later with more output formats.
Co-authored-by: Kirill Smelkov's avatarKirill Smelkov <kirr@nexedi.com>
Reviewed-on: nexedi/zodbtools!22
parent aa7e1966
# -*- coding: utf-8 -*-
# Copyright (C) 2017-2020 Nexedi SA and Contributors.
# Copyright (C) 2017-2022 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
# Jérome Perrin <jerome@nexedi.com>
#
......@@ -31,19 +31,20 @@ from io import BytesIO
from os.path import dirname
from zodbtools.test.testutil import zext_supported
from pytest import raises, xfail
from pytest import mark, raises, xfail
# verify zodbdump output against golden
def test_zodbdump(zext):
@mark.parametrize('pretty', ('raw', 'zpickledis'))
def test_zodbdump(zext, pretty):
tdir = dirname(__file__)
zkind = '_!zext' if zext.disabled else ''
stor = FileStorage('%s/testdata/1%s.fs' % (tdir, zkind), read_only=True)
with open('%s/testdata/1%s.zdump.ok' % (tdir, zkind), 'rb') as f:
with open('%s/testdata/1%s.zdump.%s.ok' % (tdir, zkind, pretty), 'rb') as f:
dumpok = f.read()
out = BytesIO()
zodbdump(stor, None, None, out=out)
zodbdump(stor, None, None, pretty=pretty, out=out)
assert out.getvalue() == dumpok
......
# -*- coding: utf-8 -*-
# Copyright (C) 2021 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
# Copyright (C) 2021-2022 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
......@@ -40,7 +40,7 @@ def test_zodbrestore(zext):
tdata = dirname(__file__) + "/testdata"
@func
def _():
zdump = open("%s/1%s.zdump.ok" % (tdata, zkind), 'rb')
zdump = open("%s/1%s.zdump.raw.ok" % (tdata, zkind), 'rb')
defer(zdump.close)
stor = storageFromURL('%s/2.fs' % tmpd)
......
txn 0285cbac258bf266 " "
user ""
description "initial database creation"
extension ""
obj 0000000000000000 61 sha1:664e6de0f153d8eaeda638d616a320c6e3c5feb1
0: \x80 PROTO 2
2: c GLOBAL 'persistent.mapping PersistentMapping'
40: q BINPUT 1
42: . STOP
highest protocol among opcodes = 2
43: \x80 PROTO 2
45: } EMPTY_DICT
46: q BINPUT 2
48: U SHORT_BINSTRING 'data'
54: q BINPUT 3
56: } EMPTY_DICT
57: q BINPUT 4
59: s SETITEM
60: . STOP
highest protocol among opcodes = 2
txn 0285cbac3d0369e6 " "
user "user0.0"
description "step 0.0"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieS'
17: U SHORT_BINSTRING 'RF9IE'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (f)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000000 98 sha1:eba252d1984f975ecb636bc1b3a89c953dd20527
0: \x80 PROTO 2
2: c GLOBAL 'persistent.mapping PersistentMapping'
40: q BINPUT 1
42: . STOP
highest protocol among opcodes = 2
43: \x80 PROTO 2
45: } EMPTY_DICT
46: q BINPUT 2
48: U SHORT_BINSTRING 'data'
54: q BINPUT 3
56: } EMPTY_DICT
57: q BINPUT 4
59: U SHORT_BINSTRING 'f'
62: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x01'
72: q BINPUT 5
74: c GLOBAL '__main__ Object'
91: q BINPUT 6
93: \x86 TUPLE2
94: Q BINPERSID
95: s SETITEM
96: s SETITEM
97: . STOP
highest protocol among opcodes = 2
obj 0000000000000001 33 sha1:1e4a07534b581b8c84c6d887042b3a3469bd4a5c
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'f0.0'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac41b4e833 " "
user "user0.1"
description "step 0.1"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieM'
17: U SHORT_BINSTRING 'LWIAR'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (d)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000000 118 sha1:1690c43fd17c00da24ce037dd0ff935a27a764bc
0: \x80 PROTO 2
2: c GLOBAL 'persistent.mapping PersistentMapping'
40: q BINPUT 1
42: . STOP
highest protocol among opcodes = 2
43: \x80 PROTO 2
45: } EMPTY_DICT
46: q BINPUT 2
48: U SHORT_BINSTRING 'data'
54: q BINPUT 3
56: } EMPTY_DICT
57: q BINPUT 4
59: ( MARK
60: U SHORT_BINSTRING 'd'
63: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x02'
73: q BINPUT 5
75: c GLOBAL '__main__ Object'
92: q BINPUT 6
94: \x86 TUPLE2
95: Q BINPERSID
96: U SHORT_BINSTRING 'f'
99: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x01'
109: q BINPUT 7
111: h BINGET 6
113: \x86 TUPLE2
114: Q BINPERSID
115: u SETITEMS (MARK at 59)
116: s SETITEM
117: . STOP
highest protocol among opcodes = 2
obj 0000000000000002 33 sha1:5aa1e99b47fb9f190222f35d8c297ad1602028be
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'd0.1'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac46666680 " "
user "user0.2"
description "step 0.2"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-generator'
19: q BINPUT 2
21: U SHORT_BINSTRING 'zodb/py2 (g)'
35: U SHORT_BINSTRING 'x-cookieW'
46: U SHORT_BINSTRING 'ZTWBQ'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000000 137 sha1:f4d83e65109e15c94dc889132b2052b1d20020de
0: \x80 PROTO 2
2: c GLOBAL 'persistent.mapping PersistentMapping'
40: q BINPUT 1
42: . STOP
highest protocol among opcodes = 2
43: \x80 PROTO 2
45: } EMPTY_DICT
46: q BINPUT 2
48: U SHORT_BINSTRING 'data'
54: q BINPUT 3
56: } EMPTY_DICT
57: q BINPUT 4
59: ( MARK
60: U SHORT_BINSTRING 'd'
63: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x02'
73: q BINPUT 5
75: c GLOBAL '__main__ Object'
92: q BINPUT 6
94: \x86 TUPLE2
95: Q BINPERSID
96: U SHORT_BINSTRING 'g'
99: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x03'
109: q BINPUT 7
111: h BINGET 6
113: \x86 TUPLE2
114: Q BINPERSID
115: U SHORT_BINSTRING 'f'
118: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x01'
128: q BINPUT 8
130: h BINGET 6
132: \x86 TUPLE2
133: Q BINPERSID
134: u SETITEMS (MARK at 59)
135: s SETITEM
136: . STOP
highest protocol among opcodes = 2
obj 0000000000000003 33 sha1:e1d41cf78ad2cc8f78c0b689fb6969fb6e63629b
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'g0.2'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac4b17e4cc " "
user "user0.3"
description "step 0.3"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieH'
17: U SHORT_BINSTRING '3FLWY'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (d)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000002 33 sha1:197dbea033be32447c915075e46065eb38322499
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'd0.3'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac4fc96319 " "
user "user0.4"
description "step 0.4"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieT'
17: U SHORT_BINSTRING 'SJ0PE'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (b)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000000 156 sha1:99ee7f2016d878efeea2b85c52a96efdd818609d
0: \x80 PROTO 2
2: c GLOBAL 'persistent.mapping PersistentMapping'
40: q BINPUT 1
42: . STOP
highest protocol among opcodes = 2
43: \x80 PROTO 2
45: } EMPTY_DICT
46: q BINPUT 2
48: U SHORT_BINSTRING 'data'
54: q BINPUT 3
56: } EMPTY_DICT
57: q BINPUT 4
59: ( MARK
60: U SHORT_BINSTRING 'b'
63: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x04'
73: q BINPUT 5
75: c GLOBAL '__main__ Object'
92: q BINPUT 6
94: \x86 TUPLE2
95: Q BINPERSID
96: U SHORT_BINSTRING 'd'
99: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x02'
109: q BINPUT 7
111: h BINGET 6
113: \x86 TUPLE2
114: Q BINPERSID
115: U SHORT_BINSTRING 'g'
118: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x03'
128: q BINPUT 8
130: h BINGET 6
132: \x86 TUPLE2
133: Q BINPERSID
134: U SHORT_BINSTRING 'f'
137: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x01'
147: q BINPUT 9
149: h BINGET 6
151: \x86 TUPLE2
152: Q BINPERSID
153: u SETITEMS (MARK at 59)
154: s SETITEM
155: . STOP
highest protocol among opcodes = 2
obj 0000000000000004 33 sha1:b43766925d709c95d71e523cac76b914c59a81ff
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'b0.4'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac547ae166 " "
user "user0.5"
description "step 0.5"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookie6'
17: U SHORT_BINSTRING 'HV8BV'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (a)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000000 175 sha1:e91a78ae65df78376be0cccccc46cd507c0883ba
0: \x80 PROTO 2
2: c GLOBAL 'persistent.mapping PersistentMapping'
40: q BINPUT 1
42: . STOP
highest protocol among opcodes = 2
43: \x80 PROTO 2
45: } EMPTY_DICT
46: q BINPUT 2
48: U SHORT_BINSTRING 'data'
54: q BINPUT 3
56: } EMPTY_DICT
57: q BINPUT 4
59: ( MARK
60: U SHORT_BINSTRING 'a'
63: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x05'
73: q BINPUT 5
75: c GLOBAL '__main__ Object'
92: q BINPUT 6
94: \x86 TUPLE2
95: Q BINPERSID
96: U SHORT_BINSTRING 'b'
99: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x04'
109: q BINPUT 7
111: h BINGET 6
113: \x86 TUPLE2
114: Q BINPERSID
115: U SHORT_BINSTRING 'd'
118: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x02'
128: q BINPUT 8
130: h BINGET 6
132: \x86 TUPLE2
133: Q BINPERSID
134: U SHORT_BINSTRING 'g'
137: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x03'
147: q BINPUT 9
149: h BINGET 6
151: \x86 TUPLE2
152: Q BINPERSID
153: U SHORT_BINSTRING 'f'
156: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x01'
166: q BINPUT 10
168: h BINGET 6
170: \x86 TUPLE2
171: Q BINPERSID
172: u SETITEMS (MARK at 59)
173: s SETITEM
174: . STOP
highest protocol among opcodes = 2
obj 0000000000000005 33 sha1:942565d4293c16a7244816620f36dc7de29613ea
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'a0.5'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac592c5fb3 " "
user "user0.6"
description "step 0.6"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieI'
17: U SHORT_BINSTRING 'YSG2B'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (b)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000004 33 sha1:6bc59a113b81cb4a61a66035a981b366c2ab42f2
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'b0.6'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac5dddde00 " "
user "user0.7"
description "step 0.7"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieY'
17: U SHORT_BINSTRING 'JPJTJ'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (a)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000005 33 sha1:c32b9a2d79a1557e57ed757889d22e4f5cc29e56
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'a0.7'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac628f5c4c " "
user "user0.8"
description "step 0.8"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookie6'
17: U SHORT_BINSTRING 'GLDKA'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (e)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000000 194 sha1:8bcaf05126609647586f4299684e34f011f3fe3a
0: \x80 PROTO 2
2: c GLOBAL 'persistent.mapping PersistentMapping'
40: q BINPUT 1
42: . STOP
highest protocol among opcodes = 2
43: \x80 PROTO 2
45: } EMPTY_DICT
46: q BINPUT 2
48: U SHORT_BINSTRING 'data'
54: q BINPUT 3
56: } EMPTY_DICT
57: q BINPUT 4
59: ( MARK
60: U SHORT_BINSTRING 'a'
63: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x05'
73: q BINPUT 5
75: c GLOBAL '__main__ Object'
92: q BINPUT 6
94: \x86 TUPLE2
95: Q BINPERSID
96: U SHORT_BINSTRING 'b'
99: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x04'
109: q BINPUT 7
111: h BINGET 6
113: \x86 TUPLE2
114: Q BINPERSID
115: U SHORT_BINSTRING 'e'
118: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x06'
128: q BINPUT 8
130: h BINGET 6
132: \x86 TUPLE2
133: Q BINPERSID
134: U SHORT_BINSTRING 'd'
137: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x02'
147: q BINPUT 9
149: h BINGET 6
151: \x86 TUPLE2
152: Q BINPERSID
153: U SHORT_BINSTRING 'g'
156: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x03'
166: q BINPUT 10
168: h BINGET 6
170: \x86 TUPLE2
171: Q BINPERSID
172: U SHORT_BINSTRING 'f'
175: U SHORT_BINSTRING '\x00\x00\x00\x00\x00\x00\x00\x01'
185: q BINPUT 11
187: h BINGET 6
189: \x86 TUPLE2
190: Q BINPERSID
191: u SETITEMS (MARK at 59)
192: s SETITEM
193: . STOP
highest protocol among opcodes = 2
obj 0000000000000006 33 sha1:260a873b0e1157c3818eac9016e10ee41f0c1a4c
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'e0.8'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac6740da99 " "
user "user0.9"
description "step 0.9"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieX'
17: U SHORT_BINSTRING 'NH3RV'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (e)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000006 33 sha1:18afafa1c0c3856880ca5e6ab31c267bc43f4a2b
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'e0.9'
30: q BINPUT 2
32: . STOP
highest protocol among opcodes = 2
txn 0285cbac6bf258e6 " "
user "user0.10"
description "step 0.10"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieT'
17: U SHORT_BINSTRING 'XJEP9'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (g)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000003 34 sha1:4b61abd85c8cd0ca40f4b8c0c847877aac67631e
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'g0.10'
31: q BINPUT 2
33: . STOP
highest protocol among opcodes = 2
txn 0285cbac70a3d733 " "
user "user0.11"
description "step 0.11"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieZ'
17: U SHORT_BINSTRING 'LYKGN'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (g)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000003 34 sha1:484358413b2746e8a05b1e3173051abedd28e1fa
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'g0.11'
31: q BINPUT 2
33: . STOP
highest protocol among opcodes = 2
txn 0285cbac75555580 " "
user "user0.12"
description "step 0.12"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookie8'
17: U SHORT_BINSTRING '2MHMU'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (f)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000001 34 sha1:9fae782fe3e33273b520c954925704856ca90dc6
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'f0.12'
31: q BINPUT 2
33: . STOP
highest protocol among opcodes = 2
txn 0285cbac7a06d3cc " "
user "user0.13"
description "step 0.13"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookie5'
17: U SHORT_BINSTRING '7SBT3'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (a)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000005 34 sha1:704bb7a3e67bdfb32c917020f5209548f96a7870
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'a0.13'
31: q BINPUT 2
33: . STOP
highest protocol among opcodes = 2
txn 0285cbac7eb85219 " "
user "user0.14"
description "step 0.14"
extension
0: \x80 PROTO 2
2: } EMPTY_DICT
3: q BINPUT 1
5: ( MARK
6: U SHORT_BINSTRING 'x-cookieM'
17: U SHORT_BINSTRING 'KWJO0'
24: U SHORT_BINSTRING 'x-generator'
37: q BINPUT 2
39: U SHORT_BINSTRING 'zodb/py2 (a)'
53: u SETITEMS (MARK at 5)
54: . STOP
highest protocol among opcodes = 2
obj 0000000000000005 34 sha1:625f66b63030f06ad8e30120b0c06f9089dc8c90
0: \x80 PROTO 2
2: c GLOBAL '__main__ Object'
19: q BINPUT 1
21: . STOP
highest protocol among opcodes = 2
22: \x80 PROTO 2
24: U SHORT_BINSTRING 'a0.14'
31: q BINPUT 2
33: . STOP
highest protocol among opcodes = 2
txn 0285cbac8369d066 " "
user "user0.15"
description "step 0.15"
extension