Skip to content

Commit 6e50943

Browse files
matajohmjp41
authored andcommitted
Proposed code changes for [PEP XXX](link).
1 parent 754e7c9 commit 6e50943

83 files changed

Lines changed: 3810 additions & 86 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,5 @@ CLAUDE.local.md
179179
#### main branch only stuff below this line, things to backport go above. ####
180180
# main branch only: ABI files are not checked/maintained.
181181
Doc/data/python*.abi
182+
# Ignore the build directory.
183+
build*

Include/Python.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@
145145
#include "fileutils.h"
146146
#include "cpython/pyfpe.h"
147147
#include "cpython/tracemalloc.h"
148+
#include "immutability.h"
148149

149150
// Restore warning filter
150151
#ifdef _MSC_VER

Include/cpython/immutability.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef Py_CPYTHON_IMMUTABLE_H
2+
# error "this header file must not be included directly"
3+
#endif
4+
5+
PyAPI_DATA(PyTypeObject) _PyNotFreezable_Type;
6+
7+
PyAPI_FUNC(int) _PyImmutability_Freeze(PyObject*);
8+
PyAPI_FUNC(int) _PyImmutability_RegisterFreezable(PyTypeObject*);

Include/cpython/listobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) {
4444
PyListObject *list = _PyList_CAST(op);
4545
assert(0 <= index);
4646
assert(index < list->allocated);
47+
// TODO(Immutable): Add assert to check if the list is immutable
4748
list->ob_item[index] = value;
4849
}
4950
#define PyList_SET_ITEM(op, index, value) \

Include/cpython/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ typedef struct _heaptypeobject {
291291
PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *);
292292
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
293293
PyAPI_FUNC(PyObject *) _PyType_LookupRef(PyTypeObject *, PyObject *);
294+
PyAPI_FUNC(int) _PyType_HasExtensionSlots(PyTypeObject *);
294295
PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *);
295296

296297
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);

Include/descrobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct PyMemberDef {
8484
#define Py_AUDIT_READ 2 // Added in 3.10, harmless no-op before that
8585
#define _Py_WRITE_RESTRICTED 4 // Deprecated, no-op. Do not reuse the value.
8686
#define Py_RELATIVE_OFFSET 8
87+
// TODO(Immutable): Could use this to mark members as needing a lock.
8788

8889
PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, PyMemberDef *);
8990
PyAPI_FUNC(int) PyMember_SetOne(char *, PyMemberDef *, PyObject *);

Include/dictobject.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
2323
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
2424
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
2525
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
26-
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
26+
// Note(Immutable): If dictionary is immutable, then clear can fail. Had to change signature here!
27+
PyAPI_FUNC(int) PyDict_Clear(PyObject *mp);
2728
PyAPI_FUNC(int) PyDict_Next(
2829
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
2930
PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);

Include/immutability.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef Py_IMMUTABILITY_H
2+
#define Py_IMMUTABILITY_H
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
9+
#ifndef Py_LIMITED_API
10+
# define Py_CPYTHON_IMMUTABLE_H
11+
# include "cpython/immutability.h"
12+
# undef Py_CPYTHON_IMMUTABLE_H
13+
#endif
14+
15+
16+
#ifdef __cplusplus
17+
}
18+
#endif
19+
#endif /* !Py_IMMUTABILITY_H */

Include/internal/pycore_cell.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,30 @@ extern "C" {
1616
// Sets the cell contents to `value` and return previous contents. Steals a
1717
// reference to `value`.
1818
static inline PyObject *
19-
PyCell_SwapTakeRef(PyCellObject *cell, PyObject *value)
19+
PyCell_SwapTakeRef(PyCellObject *cell, PyObject *value, int* result)
2020
{
21-
PyObject *old_value;
21+
PyObject *old_value = NULL;
22+
*result = 0;
2223
Py_BEGIN_CRITICAL_SECTION(cell);
23-
old_value = cell->ob_ref;
24-
FT_ATOMIC_STORE_PTR_RELEASE(cell->ob_ref, value);
24+
if(Py_CHECKWRITE(cell)){
25+
old_value = cell->ob_ref;
26+
FT_ATOMIC_STORE_PTR_RELEASE(cell->ob_ref, value);
27+
}
28+
else {
29+
*result = -1;
30+
Py_XDECREF(value);
31+
}
2532
Py_END_CRITICAL_SECTION();
2633
return old_value;
2734
}
2835

29-
static inline void
36+
static inline int
3037
PyCell_SetTakeRef(PyCellObject *cell, PyObject *value)
3138
{
32-
PyObject *old_value = PyCell_SwapTakeRef(cell, value);
39+
int result = 0;
40+
PyObject *old_value = PyCell_SwapTakeRef(cell, value, &result);
3341
Py_XDECREF(old_value);
42+
return result;
3443
}
3544

3645
// Gets the cell contents. Returns a new reference.

Include/internal/pycore_ceval.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ PyAPI_FUNC(int) _PyEval_ExceptionGroupMatch(_PyInterpreterFrame *, PyObject* exc
267267
PyAPI_FUNC(void) _PyEval_FormatAwaitableError(PyThreadState *tstate, PyTypeObject *type, int oparg);
268268
PyAPI_FUNC(void) _PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, const char *format_str, PyObject *obj);
269269
PyAPI_FUNC(void) _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg);
270+
PyAPI_FUNC(void) _PyEval_FormatExcNotWriteable(PyThreadState *tstate, PyCodeObject *co, int oparg);
270271
PyAPI_FUNC(void) _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs);
271272
PyAPI_FUNC(PyObject *) _PyEval_ImportFrom(PyThreadState *, PyObject *, PyObject *);
272273
PyAPI_FUNC(PyObject *) _PyEval_ImportName(PyThreadState *, _PyInterpreterFrame *, PyObject *, PyObject *, PyObject *);

0 commit comments

Comments
 (0)