Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions Include/refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,24 @@ static inline Py_ALWAYS_INLINE int _Py_IsImmutable(PyObject *op)
}
#define _Py_IsImmutable(op) _Py_IsImmutable(_PyObject_CAST(op))

// Artifact[Implementation]: The definition of the `Py_CHECKWRITE` macro
#ifndef Py_LIMITED_API
// Cold path for Py_CHECKWRITE: called when the object is immutable.
// Returns 1 if the object is still writable (ImmModule or finalizing).
PyAPI_FUNC(int) _Py_CheckWriteImmutable(PyObject *op);

// Check whether an object is writeable.
// This check will always succeed during runtime finalization.
#define Py_CHECKWRITE(op) ((op) && (!_Py_IsImmutable(op) || _PyImmModule_Check(op) || Py_IsFinalizing()))
// The fast path just checks the immutable flag; the ImmModule and
// finalizing checks are pushed into a cold out-of-line function.
static inline int Py_CHECKWRITE(PyObject *op)
{
if (_Py_IsImmutable(op)) {
return _Py_CheckWriteImmutable(op);
}
return 1;
}
#define Py_CHECKWRITE(op) Py_CHECKWRITE(_PyObject_CAST(op))
#define Py_REQUIREWRITE(op, msg) {if (Py_CHECKWRITE(op)) { _PyObject_ASSERT_FAILED_MSG(op, msg); }}
#endif // !Py_LIMITED_API

static inline Py_ALWAYS_INLINE void _Py_CLEAR_IMMUTABLE(PyObject *op)
{
Expand Down
9 changes: 9 additions & 0 deletions Python/immutability.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@
return true;
}

static PyObject* get_next(PyObject* obj, struct FreezeState *freeze_state)

Check warning on line 678 in Python/immutability.c

View workflow job for this annotation

GitHub Actions / Cross build Linux

‘get_next’ defined but not used [-Wunused-function]

Check warning on line 678 in Python/immutability.c

View workflow job for this annotation

GitHub Actions / Address sanitizer (ubuntu-24.04)

‘get_next’ defined but not used [-Wunused-function]
{
(void)freeze_state;
PyObject* next = scc_next(obj);
Expand Down Expand Up @@ -1846,6 +1846,15 @@
return 1;
}

// Cold path for Py_CHECKWRITE: the object is known to be immutable.
// Returns 1 (writable) if the object's type is _PyImmModule_Type or
// the runtime is finalizing.
int
_Py_CheckWriteImmutable(PyObject *op)
{
return _PyImmModule_Check(op) || Py_IsFinalizing();
}

// Perform a decref on an immutable object
// returns true if the object should be deallocated.
int _Py_DecRef_Immutable(PyObject *op)
Expand Down Expand Up @@ -2130,7 +2139,7 @@
return 0;
}
#else
#error "Immutability currently only works on 64bit platforms"

Check failure on line 2142 in Python/immutability.c

View workflow job for this annotation

GitHub Actions / Windows / Build and test (x64)

#error: "Immutability currently only works on 64bit platforms" [D:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]

Check failure on line 2142 in Python/immutability.c

View workflow job for this annotation

GitHub Actions / Windows / Build and test (arm64)

#error: "Immutability currently only works on 64bit platforms" [C:\a\cpython\cpython\PCbuild\_freeze_module.vcxproj]
#endif

// Mark pre-freeze hook as completed. This has to be set before calling
Expand Down
2 changes: 1 addition & 1 deletion Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1386,7 +1386,7 @@ PyModuleObject* _PyInterpreterState_GetModuleState(PyObject *mod) {
if (modules_mod == mod) {
// The modules in `sys.modules` is this frozen mod but there is
// no mutable state in `sys.mut_modules`, probably because it was
// unimported? Either way:
// unimported? Either way:
// Remove `mod` from `sys.modules` and trigger a reimport.
if (PyDict_DelItem(modules, self->md_name) < 0) {
Py_DECREF(modules_mod);
Expand Down
Loading