You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Often you need to create an Exception class that is specialised to a particular module. This can be done quite easily using either the ``PyErr_NewException`` or the ``PyErr_NewExceptionWithDoc`` functions. These create new exception classes that can be added to a module. For example:
@@ -155,17 +155,11 @@ Often you need to create an Exception class that is specialised to a particular
Copy file name to clipboardExpand all lines: doc/sphinx/source/pickle.rst
+59Lines changed: 59 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -276,6 +276,65 @@ Here is some Python code that exercises our module:
276
276
277
277
So we have pickled one object and recreated a different, but equivalent, instance from the pickle of the original object which is what we set out to do.
278
278
279
+
The Pickled Object in Detail
280
+
-------------------------------------
281
+
282
+
If you are curious about the contents of the pickled object the the Python standard library provides the `pickletools <https://docs.python.org/3/library/pickletools.html#module-pickletools>`_ module.
283
+
This allows you to inspect the pickled object.
284
+
So if we run this code:
285
+
286
+
.. code-block:: python
287
+
288
+
import pickle
289
+
import pickletools
290
+
291
+
import custom2
292
+
293
+
original = custom2.Custom('FIRST', 'LAST', 11)
294
+
pickled_value = pickle.dumps(original)
295
+
print(f'Pickled original is {pickled_value}')
296
+
#NOTE: Here we are adding annotations.
297
+
pickletools.dis(pickled_value, annotate=1)
298
+
299
+
The output will be something like this:
300
+
301
+
.. code-block:: text
302
+
303
+
Pickled original is b'\x80\x04\x95[\x00\x00\x00\x00\x00\x00\x00\x8c\x07custom2\x94\x8c\x06Custom\x94\x93\x94)\x81\x94}\x94(\x8c\x05first\x94\x8c\x05FIRST\x94\x8c\x04last\x94\x8c\x04LAST\x94\x8c\x06number\x94K\x0b\x8c\x0f_pickle_version\x94K\x01ub.'
304
+
0: \x80 PROTO 4 Protocol version indicator.
305
+
2: \x95 FRAME 91 Indicate the beginning of a new frame.
306
+
11: \x8c SHORT_BINUNICODE 'custom2' Push a Python Unicode string object.
307
+
20: \x94 MEMOIZE (as 0) Store the stack top into the memo. The stack is not popped.
308
+
21: \x8c SHORT_BINUNICODE 'Custom' Push a Python Unicode string object.
309
+
29: \x94 MEMOIZE (as 1) Store the stack top into the memo. The stack is not popped.
310
+
30: \x93 STACK_GLOBAL Push a global object (module.attr) on the stack.
311
+
31: \x94 MEMOIZE (as 2) Store the stack top into the memo. The stack is not popped.
312
+
32: ) EMPTY_TUPLE Push an empty tuple.
313
+
33: \x81 NEWOBJ Build an object instance.
314
+
34: \x94 MEMOIZE (as 3) Store the stack top into the memo. The stack is not popped.
315
+
35: } EMPTY_DICT Push an empty dict.
316
+
36: \x94 MEMOIZE (as 4) Store the stack top into the memo. The stack is not popped.
317
+
37: ( MARK Push markobject onto the stack.
318
+
38: \x8c SHORT_BINUNICODE 'first' Push a Python Unicode string object.
319
+
45: \x94 MEMOIZE (as 5) Store the stack top into the memo. The stack is not popped.
320
+
46: \x8c SHORT_BINUNICODE 'FIRST' Push a Python Unicode string object.
321
+
53: \x94 MEMOIZE (as 6) Store the stack top into the memo. The stack is not popped.
322
+
54: \x8c SHORT_BINUNICODE 'last' Push a Python Unicode string object.
323
+
60: \x94 MEMOIZE (as 7) Store the stack top into the memo. The stack is not popped.
324
+
61: \x8c SHORT_BINUNICODE 'LAST' Push a Python Unicode string object.
325
+
67: \x94 MEMOIZE (as 8) Store the stack top into the memo. The stack is not popped.
326
+
68: \x8c SHORT_BINUNICODE 'number' Push a Python Unicode string object.
327
+
76: \x94 MEMOIZE (as 9) Store the stack top into the memo. The stack is not popped.
328
+
77: K BININT1 11 Push a one-byte unsigned integer.
329
+
79: \x8c SHORT_BINUNICODE '_pickle_version' Push a Python Unicode string object.
330
+
96: \x94 MEMOIZE (as 10) Store the stack top into the memo. The stack is not popped.
331
+
97: K BININT1 1 Push a one-byte unsigned integer.
332
+
99: u SETITEMS (MARK at 37) Add an arbitrary number of key+value pairs to an existing dict.
333
+
100: b BUILD Finish building an object, via __setstate__ or dict update.
Copy file name to clipboardExpand all lines: doc/sphinx/source/thread_safety.rst
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -230,4 +230,4 @@ And that is pretty much it.
230
230
231
231
.. [#f1] I won't pretend to understand all that is going on here, it does work however.
232
232
.. [#f2] What I don't understand is why putting this code in the ``SkipList_new`` function does not work, the lock does not get initialised and segfaults typically in ``_pthread_mutex_check_init``. The order has to be: set the lock pointer NULL in ``_new``, allocate it in ``_init``, free it in ``_dealloc``.
233
-
.. [#f3] A potiential weakness of this code is that we might be deallocating the lock *whilst the lock is acquired* which could lead to deadlock. This is very much implementation defined in ``pythreads`` and may vary from platform to platform. There is no obvious API in ``pythreads`` that allows us to determine if a lock is held so we can release it before deallocation. I notice that in the Python threading module (*Modules/_threadmodule.c*) there is an additional ``char`` field that acts as a flag to say when the lock is held so that the ``lock_dealloc()`` function in that module can release the lock before freeing the lock.
233
+
.. [#f3] A potential weakness of this code is that we might be deallocating the lock *whilst the lock is acquired* which could lead to deadlock. This is very much implementation defined in ``pythreads`` and may vary from platform to platform. There is no obvious API in ``pythreads`` that allows us to determine if a lock is held so we can release it before deallocation. I notice that in the Python threading module (*Modules/_threadmodule.c*) there is an additional ``char`` field that acts as a flag to say when the lock is held so that the ``lock_dealloc()`` function in that module can release the lock before freeing the lock.
0 commit comments