Staging
v0.5.1
https://github.com/python/cpython
Revision 049039832da3d02592d680cebf71ab8a665a6564 authored by Antoine Pitrou on 10 June 2020, 20:37:21 UTC, committed by GitHub on 10 June 2020, 20:37:21 UTC


The doccumentation at https://docs.python.org/3.10/library/weakref.html cautions that the `WeakKeyDictionary` and `WeakValueDictionary` are susceptible to the problem of dictionary mutation during iteration.

These notes present the user with a problem that has no easy solution.

I dug into the implementation and found that fortunately, Antoine Pitrou already addressed this challenge (10 years ago!) by introducing an `_IterationGuard` context manager to the implementation, which delays mutation while an iteration is in progress.

I asked for confirmation and @pitrou agreed that these notes could be removed:
https://github.com/python/cpython/commit/c1baa601e2b558deb690edfdf334fceee3b03327GH-commitcomment-39514438.
(cherry picked from commit 1642c0ef750f96664a98cadb09301d492098d2fb)

Co-authored-by: Daniel Fortunov <asqui@users.noreply.github.com>

Automerge-Triggered-By: @pitrou
1 parent 4b378ac
Raw File
Tip revision: 049039832da3d02592d680cebf71ab8a665a6564 authored by Antoine Pitrou on 10 June 2020, 20:37:21 UTC
[3.7] bpo-40895: Update weakref documentation to remove old warnings (GH-20687) (GH-20793)
Tip revision: 0490398
bytearrayobject.h
/* ByteArray object interface */

#ifndef Py_BYTEARRAYOBJECT_H
#define Py_BYTEARRAYOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif

#include <stdarg.h>

/* Type PyByteArrayObject represents a mutable array of bytes.
 * The Python API is that of a sequence;
 * the bytes are mapped to ints in [0, 256).
 * Bytes are not characters; they may be used to encode characters.
 * The only way to go between bytes and str/unicode is via encoding
 * and decoding.
 * For the convenience of C programmers, the bytes type is considered
 * to contain a char pointer, not an unsigned char pointer.
 */

/* Object layout */
#ifndef Py_LIMITED_API
typedef struct {
    PyObject_VAR_HEAD
    Py_ssize_t ob_alloc; /* How many bytes allocated in ob_bytes */
    char *ob_bytes;      /* Physical backing buffer */
    char *ob_start;      /* Logical start inside ob_bytes */
    /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */
    int ob_exports;      /* How many buffer exports */
} PyByteArrayObject;
#endif

/* Type object */
PyAPI_DATA(PyTypeObject) PyByteArray_Type;
PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type;

/* Type check macros */
#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type)
#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type)

/* Direct API functions */
PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *);
PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t);
PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *);
PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *);
PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t);

/* Macros, trading safety for speed */
#ifndef Py_LIMITED_API
#define PyByteArray_AS_STRING(self) \
    (assert(PyByteArray_Check(self)), \
     Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_start : _PyByteArray_empty_string)
#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)), Py_SIZE(self))

PyAPI_DATA(char) _PyByteArray_empty_string[];
#endif

#ifdef __cplusplus
}
#endif
#endif /* !Py_BYTEARRAYOBJECT_H */
back to top