Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cd916df

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents adb1571 + 8173a03 commit cd916df

File tree

5 files changed

+65
-12
lines changed

5 files changed

+65
-12
lines changed

‎doc/sphinx/source/cpp_and_cpython.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ It is sometimes useful to wrap up a ``PyObject*`` in a class that will manage th
1414

1515
* Construction with a ``PyObject *`` and access this with ``operator PyObject*() const``.
1616
* ``PyObject **operator&()`` to reset the underlying pointer, for example when using it with ``PyArg_ParseTupleAndKeywords``.
17-
* Decrementing the reference count on destruction (potientially freeing the object).
17+
* Decrementing the reference count on destruction (potentially freeing the object).
1818

1919
.. code-block:: cpp
2020

‎doc/sphinx/source/exceptions.rst

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Incidentially ``PyObject_TypeCheck`` is defined as:
130130
(Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp)))
131131
132132
---------------------------------
133-
Creating Specialised Excpetions
133+
Creating Specialised Exceptions
134134
---------------------------------
135135

136136
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
155155
{
156156
PyObject* m;
157157
158-
noddy_NoddyType.tp_new = PyType_GenericNew;
159-
if (PyType_Ready(&noddy_NoddyType) < 0)
160-
return NULL;
161-
162158
m = PyModule_Create(&noddymodule);
163159
if (m == NULL)
164160
return NULL;
165161
166-
Py_INCREF(&noddy_NoddyType);
167-
PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
168-
162+
169163
/* Initialise exceptions here.
170164
*
171165
* Firstly a base class exception that inherits from the builtin Exception.

‎doc/sphinx/source/pickle.rst

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,65 @@ Here is some Python code that exercises our module:
276276
277277
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.
278278

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.
334+
101: . STOP Stop the unpickling machine.
335+
highest protocol among opcodes = 4
336+
337+
279338
Pickling Objects with External State
280339
-----------------------------------------
281340

‎doc/sphinx/source/refcount.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Here is an example of a normal ``PyObject`` creation and deallocation:
4040
PyObject *pObj = NULL;
4141
4242
pObj = PyBytes_FromString("Hello world\n"); /* Object creation, ref count = 1. */
43-
PyObject_Print(pLast, stdout, 0);
43+
PyObject_Print(pObj, stdout, 0);
4444
Py_DECREF(pObj); /* ref count becomes 0, object deallocated.
4545
* Miss this step and you have a memory leak. */
4646
}
@@ -64,7 +64,7 @@ Taking the above example of a normal ``PyObject`` creation and deallocation then
6464
#include "Python.h"
6565
6666
void print_hello_world(void) {
67-
PyObject *pObj = NULL:
67+
PyObject *pObj = NULL;
6868
6969
pObj = PyBytes_FromString("Hello world\n"); /* Object creation, ref count = 1. */
7070
PyObject_Print(pLast, stdout, 0);

‎doc/sphinx/source/thread_safety.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,4 @@ And that is pretty much it.
230230

231231
.. [#f1] I won't pretend to understand all that is going on here, it does work however.
232232
.. [#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

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /