From 2bc751b6e9d6144f8f0ce5c1bf3c577877d1a5e1 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:37:50 -0400 Subject: [PATCH 01/25] Add new dictionary functions and extern declarations Added new functions for dictionary operations and updated extern declarations. --- pyo3-ffi/src/cpython/dictobject.rs | 31 +++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 37991ee4ebe..3d7e4de9f04 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -3,6 +3,8 @@ use crate::object::*; #[cfg(not(any(PyPy, GraalPy)))] use crate::pyport::Py_ssize_t; +use std::ffi::{c_int, c_char}; + #[cfg(not(PyPy))] opaque_struct!(pub PyDictKeysObject); @@ -39,19 +41,33 @@ pub struct PyDictObject { _tmpkeys: *mut PyObject, } +extern_libpython! { + pub fn PyDict_SetDefault(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject) -> *mut PyObject; + #[cfg(all(Py_3_13, not(Py_3_15))] + pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: **mut PyObject) -> c_int; + #[cfg(Py_3_13)] + pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const char) -> c_int; + #[cfg(Py_3_13)] + pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: **mut PyObject) -> c_int; + #[cfg(Py_3_13)] + pub fn PyDict_PopString(dict: *mut PyObject, key: *const c_char, result: **mut PyObject) -> c_int; + #[cfg(Py_3_12)] + pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; + #[cfg(Py_3_12] + pub fn PyDict_Watch(watcher_id: c_int, dict: *mut PyObject) -> c_int; + #[cfg(Py_3_12] + pub fn PyDict_Unwatch(watcher_id: c_int, dict: *mut PyObject) -> c_int; + #[cfg(Py_3_15)] + pub fn PyFrozenDict_New(iterable: *mut PyObject) -> *mut PyObject; +} + // skipped private _PyDict_GetItem_KnownHash // skipped private _PyDict_GetItemStringWithError -// skipped PyDict_SetDefault -// skipped PyDict_SetDefaultRef - // skipped PyDict_GET_SIZE -// skipped PyDict_ContainsString // skipped private _PyDict_NewPresized -// skipped PyDict_Pop -// skipped PyDict_PopString // skipped private _PyDict_Pop @@ -61,7 +77,4 @@ pub struct PyDictObject { // skipped PyDict_WatchCallback // skipped PyDict_AddWatcher -// skipped PyDict_ClearWatcher -// skipped PyDict_Watch -// skipped PyDict_Unwatch From 607ecf265aa43ae355ba93be18efc783f05ece58 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:41:54 -0400 Subject: [PATCH 02/25] Add PyDict_SetDefaultRef function declaration --- pyo3-ffi/src/dictobject.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index 4afa2ffb5e8..57a304cf981 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -18,6 +18,8 @@ pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { } extern_libpython! { + #[cfg(any(Py_3_15), not(Py_LIMITED_API))] + pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: **mut PyObject) -> c_int; #[cfg_attr(PyPy, link_name = "PyPyDict_New")] pub fn PyDict_New() -> *mut PyObject; #[cfg_attr(PyPy, link_name = "PyPyDict_GetItem")] From f0939846a5e4749cae56b177a346828c1e479a8f Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:44:08 -0400 Subject: [PATCH 03/25] Create 5947.added.md --- newsfragments/5947.added.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 newsfragments/5947.added.md diff --git a/newsfragments/5947.added.md b/newsfragments/5947.added.md new file mode 100644 index 00000000000..16480541f22 --- /dev/null +++ b/newsfragments/5947.added.md @@ -0,0 +1,11 @@ +Added the following functions: + +* pub fn PyDict_SetDefault(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject) -> *mut PyObject; +* pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: **mut PyObject) -> c_int; +* pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const char) -> c_int; +* pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: **mut PyObject) -> c_int; +* pub fn PyDict_PopString(dict: *mut PyObject, key: *const c_char, result: **mut PyObject) -> c_int; +* pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; +* pub fn PyDict_Watch(watcher_id: c_int, dict: *mut PyObject) -> c_int; +* pub fn PyDict_Unwatch(watcher_id: c_int, dict: *mut PyObject) -> c_int; +* pub fn PyFrozenDict_New(iterable: *mut PyObject) -> *mut PyObject; From 6807fccad41009ef1a6355bf5cea835ea91b12f4 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:45:35 -0400 Subject: [PATCH 04/25] Fix syntax errors in dictobject.rs configuration flags --- pyo3-ffi/src/cpython/dictobject.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 3d7e4de9f04..3c8972d6717 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -43,7 +43,7 @@ pub struct PyDictObject { extern_libpython! { pub fn PyDict_SetDefault(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject) -> *mut PyObject; - #[cfg(all(Py_3_13, not(Py_3_15))] + #[cfg(all(Py_3_13, not(Py_3_15)))] pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: **mut PyObject) -> c_int; #[cfg(Py_3_13)] pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const char) -> c_int; @@ -53,9 +53,9 @@ extern_libpython! { pub fn PyDict_PopString(dict: *mut PyObject, key: *const c_char, result: **mut PyObject) -> c_int; #[cfg(Py_3_12)] pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; - #[cfg(Py_3_12] + #[cfg(Py_3_12)] pub fn PyDict_Watch(watcher_id: c_int, dict: *mut PyObject) -> c_int; - #[cfg(Py_3_12] + #[cfg(Py_3_12)] pub fn PyDict_Unwatch(watcher_id: c_int, dict: *mut PyObject) -> c_int; #[cfg(Py_3_15)] pub fn PyFrozenDict_New(iterable: *mut PyObject) -> *mut PyObject; From fb3a9a16f1078573c7ff33e7b0550df92be97958 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:47:18 -0400 Subject: [PATCH 05/25] Reorder imports in dictobject.rs --- pyo3-ffi/src/cpython/dictobject.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 3c8972d6717..4797d5f7795 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -3,7 +3,7 @@ use crate::object::*; #[cfg(not(any(PyPy, GraalPy)))] use crate::pyport::Py_ssize_t; -use std::ffi::{c_int, c_char}; +use std::ffi::{c_char, c_int}; #[cfg(not(PyPy))] opaque_struct!(pub PyDictKeysObject); @@ -68,7 +68,6 @@ extern_libpython! { // skipped private _PyDict_NewPresized - // skipped private _PyDict_Pop // skipped PY_FOREACH_DICT_EVENT @@ -77,4 +76,3 @@ extern_libpython! { // skipped PyDict_WatchCallback // skipped PyDict_AddWatcher - From 728a911e23074bff73c9225b8a056b70fd26cf25 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:49:01 -0400 Subject: [PATCH 06/25] Update PyDict_SetDefaultRef and PyDict_Pop signatures --- pyo3-ffi/src/cpython/dictobject.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 4797d5f7795..fdd16c65be7 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -44,13 +44,13 @@ pub struct PyDictObject { extern_libpython! { pub fn PyDict_SetDefault(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject) -> *mut PyObject; #[cfg(all(Py_3_13, not(Py_3_15)))] - pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: **mut PyObject) -> c_int; + pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: *mut *mut PyObject) -> c_int; #[cfg(Py_3_13)] pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const char) -> c_int; #[cfg(Py_3_13)] - pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: **mut PyObject) -> c_int; + pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: *mut *mut PyObject) -> c_int; #[cfg(Py_3_13)] - pub fn PyDict_PopString(dict: *mut PyObject, key: *const c_char, result: **mut PyObject) -> c_int; + pub fn PyDict_PopString(dict: *mut PyObject, key: *const c_char, result: *mut *mut PyObject) -> c_int; #[cfg(Py_3_12)] pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; #[cfg(Py_3_12)] From 59c92c492861ef74cdf3bb5d551d91f37ea478bc Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:49:25 -0400 Subject: [PATCH 07/25] Fix pointer type in PyDict_SetDefaultRef function --- pyo3-ffi/src/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index 57a304cf981..d83d8f38e15 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -19,7 +19,7 @@ pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { extern_libpython! { #[cfg(any(Py_3_15), not(Py_LIMITED_API))] - pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: **mut PyObject) -> c_int; + pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: *mut *mut PyObject) -> c_int; #[cfg_attr(PyPy, link_name = "PyPyDict_New")] pub fn PyDict_New() -> *mut PyObject; #[cfg_attr(PyPy, link_name = "PyPyDict_GetItem")] From 81ec769fd2aa2b4dbcaa2febd0eae776b0629244 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Sat, 4 Apr 2026 01:54:03 +0000 Subject: [PATCH 08/25] Fmt --- pyo3-ffi/src/cpython/dictobject.rs | 22 ++++++++++++++++++---- pyo3-ffi/src/dictobject.rs | 7 ++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index fdd16c65be7..1e274aaced9 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -42,15 +42,29 @@ pub struct PyDictObject { } extern_libpython! { - pub fn PyDict_SetDefault(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject) -> *mut PyObject; + pub fn PyDict_SetDefault( + mp: *mut PyObject, + key: *mut PyObject, + default_obj: *mut PyObject, + ) -> *mut PyObject; #[cfg(all(Py_3_13, not(Py_3_15)))] - pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: *mut *mut PyObject) -> c_int; + pub fn PyDict_SetDefaultRef( + mp: *mut PyObject, + key: *mut PyObject, + default_obj: *mut PyObject, + result: *mut *mut PyObject, + ) -> c_int; #[cfg(Py_3_13)] pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const char) -> c_int; #[cfg(Py_3_13)] - pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: *mut *mut PyObject) -> c_int; + pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: *mut *mut PyObject) + -> c_int; #[cfg(Py_3_13)] - pub fn PyDict_PopString(dict: *mut PyObject, key: *const c_char, result: *mut *mut PyObject) -> c_int; + pub fn PyDict_PopString( + dict: *mut PyObject, + key: *const c_char, + result: *mut *mut PyObject, + ) -> c_int; #[cfg(Py_3_12)] pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; #[cfg(Py_3_12)] diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index d83d8f38e15..e43ff1ea3b4 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -19,7 +19,12 @@ pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { extern_libpython! { #[cfg(any(Py_3_15), not(Py_LIMITED_API))] - pub fn PyDict_SetDefaultRef(mp: *mut PyObject, key: *mut PyObject, default_obj: *mut PyObject, result: *mut *mut PyObject) -> c_int; + pub fn PyDict_SetDefaultRef( + mp: *mut PyObject, + key: *mut PyObject, + default_obj: *mut PyObject, + result: *mut *mut PyObject, + ) -> c_int; #[cfg_attr(PyPy, link_name = "PyPyDict_New")] pub fn PyDict_New() -> *mut PyObject; #[cfg_attr(PyPy, link_name = "PyPyDict_GetItem")] From 0c1b437a90e5fce44720c520c8026c2c9f398a51 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:55:54 -0400 Subject: [PATCH 09/25] Fix conditional compilation directive for PyDict_SetDefaultRef --- pyo3-ffi/src/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index e43ff1ea3b4..eed0ccabb36 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -18,7 +18,7 @@ pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { } extern_libpython! { - #[cfg(any(Py_3_15), not(Py_LIMITED_API))] + #[cfg(any(Py_3_15, not(Py_LIMITED_API)))] pub fn PyDict_SetDefaultRef( mp: *mut PyObject, key: *mut PyObject, From 73cb54b5d1b3ad056bbac9f8dfedd307bcb264c5 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 21:58:14 -0400 Subject: [PATCH 10/25] Update conditional compilation for PyDict_SetDefaultRef --- pyo3-ffi/src/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index eed0ccabb36..d412d8386bd 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -18,7 +18,7 @@ pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { } extern_libpython! { - #[cfg(any(Py_3_15, not(Py_LIMITED_API)))] + #[cfg(all(Py_3_15, not(Py_LIMITED_API)))] pub fn PyDict_SetDefaultRef( mp: *mut PyObject, key: *mut PyObject, From 8067d5c64dada7181de13995758130708a4efcd4 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 22:00:37 -0400 Subject: [PATCH 11/25] Change key parameter type from char to c_char --- pyo3-ffi/src/cpython/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 1e274aaced9..9090558293c 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -55,7 +55,7 @@ extern_libpython! { result: *mut *mut PyObject, ) -> c_int; #[cfg(Py_3_13)] - pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const char) -> c_int; + pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const c_char) -> c_int; #[cfg(Py_3_13)] pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: *mut *mut PyObject) -> c_int; From 85df96fca2abd3ea43f915175e056e9aa42294f3 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 22:30:34 -0400 Subject: [PATCH 12/25] Update imports for Python version compatibility Conditionally include c_char and c_int based on Python version. --- pyo3-ffi/src/cpython/dictobject.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 9090558293c..fbb6f0844a7 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -3,7 +3,10 @@ use crate::object::*; #[cfg(not(any(PyPy, GraalPy)))] use crate::pyport::Py_ssize_t; -use std::ffi::{c_char, c_int}; +#[cfg(all(not(PyPy), Py_3_13))] +use std::ffi::c_char; +#[cfg(all(not(PyPy), Py_3_12))] +use std::fii::c_int; #[cfg(not(PyPy))] opaque_struct!(pub PyDictKeysObject); From 30f89dfc78f28f1c12a39986d91134b0f376dedd Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 3 Apr 2026 22:39:11 -0400 Subject: [PATCH 13/25] Fix typo in import statement for c_int --- pyo3-ffi/src/cpython/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index fbb6f0844a7..8b2aee41d13 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -6,7 +6,7 @@ use crate::pyport::Py_ssize_t; #[cfg(all(not(PyPy), Py_3_13))] use std::ffi::c_char; #[cfg(all(not(PyPy), Py_3_12))] -use std::fii::c_int; +use std::ffi::c_int; #[cfg(not(PyPy))] opaque_struct!(pub PyDictKeysObject); From 614c2687d9c02301a02ab709f7269b1c1de6fd65 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Sat, 11 Apr 2026 07:57:20 -0400 Subject: [PATCH 14/25] Reintroduce PyDict_SetDefaultRef for Python 3.15 --- pyo3-ffi/src/dictobject.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index d412d8386bd..35f2317558a 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -1,6 +1,8 @@ use crate::object::*; use crate::pyport::Py_ssize_t; use std::ffi::{c_char, c_int}; +#cfg[(not(Py_LIMITED_API))] +use std::ffi::c_void; extern_libpython! { #[cfg_attr(PyPy, link_name = "PyPyDict_Type")] @@ -18,13 +20,6 @@ pub unsafe fn PyDict_CheckExact(op: *mut PyObject) -> c_int { } extern_libpython! { - #[cfg(all(Py_3_15, not(Py_LIMITED_API)))] - pub fn PyDict_SetDefaultRef( - mp: *mut PyObject, - key: *mut PyObject, - default_obj: *mut PyObject, - result: *mut *mut PyObject, - ) -> c_int; #[cfg_attr(PyPy, link_name = "PyPyDict_New")] pub fn PyDict_New() -> *mut PyObject; #[cfg_attr(PyPy, link_name = "PyPyDict_GetItem")] @@ -85,6 +80,15 @@ extern_libpython! { key: *const c_char, result: *mut *mut PyObject, ) -> c_int; + #[cfg(all(Py_3_15, not(Py_LIMITED_API)))] + pub fn PyDict_SetDefaultRef( + mp: *mut PyObject, + key: *mut PyObject, + default_obj: *mut PyObject, + result: *mut *mut PyObject, + ) -> c_int; + #[cfg(not(Py_LIMITED_API))] + pub fn PyObject_GenericGetDict(o: *mut PyObject, context: *mut c_void) -> *mut PyObject; // skipped 3.10 / ex-non-limited PyObject_GenericGetDict } From 87b4dd1fbcdd66ee828335a6645f20a911d3e4fd Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Sat, 11 Apr 2026 08:02:51 -0400 Subject: [PATCH 15/25] Fix cfg attribute syntax in dictobject.rs --- pyo3-ffi/src/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index 35f2317558a..6fe44c0b160 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -1,7 +1,7 @@ use crate::object::*; use crate::pyport::Py_ssize_t; use std::ffi::{c_char, c_int}; -#cfg[(not(Py_LIMITED_API))] +#[cfg(not(Py_LIMITED_API))] use std::ffi::c_void; extern_libpython! { From e493c644eb2ab925851ba464672d3c4fe83990d3 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Sat, 11 Apr 2026 08:07:55 -0400 Subject: [PATCH 16/25] Reorganize use statements in dictobject.rs --- pyo3-ffi/src/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index 6fe44c0b160..d7bbb9682ec 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -1,8 +1,8 @@ use crate::object::*; use crate::pyport::Py_ssize_t; -use std::ffi::{c_char, c_int}; #[cfg(not(Py_LIMITED_API))] use std::ffi::c_void; +use std::ffi::{c_char, c_int}; extern_libpython! { #[cfg_attr(PyPy, link_name = "PyPyDict_Type")] From 3ac9a04bc9e72148f17984c7a133cff2b8a407e5 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Sat, 11 Apr 2026 08:14:51 -0400 Subject: [PATCH 17/25] Remove PyObject_GenericGetDict declaration Removed PyObject_GenericGetDict function declaration for non-limited API. --- pyo3-ffi/src/dictobject.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index d7bbb9682ec..d23686d2498 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -87,8 +87,6 @@ extern_libpython! { default_obj: *mut PyObject, result: *mut *mut PyObject, ) -> c_int; - #[cfg(not(Py_LIMITED_API))] - pub fn PyObject_GenericGetDict(o: *mut PyObject, context: *mut c_void) -> *mut PyObject; // skipped 3.10 / ex-non-limited PyObject_GenericGetDict } From b2684536249bbee8c9bc0aca4675e08b6676495f Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Sat, 11 Apr 2026 08:19:07 -0400 Subject: [PATCH 18/25] Remove unused c_void import in dictobject.rs Removed unused import of c_void for non-limited API. --- pyo3-ffi/src/dictobject.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index d23686d2498..3b4dedf5b05 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -1,7 +1,5 @@ use crate::object::*; use crate::pyport::Py_ssize_t; -#[cfg(not(Py_LIMITED_API))] -use std::ffi::c_void; use std::ffi::{c_char, c_int}; extern_libpython! { From bfdbe1b9a4088660492cfdd6237a9e045d4ea84d Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Sat, 11 Apr 2026 08:44:40 -0400 Subject: [PATCH 19/25] Update PyDict_SetDefaultRef for Python 3.13 compatibility --- pyo3-ffi/src/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index 3b4dedf5b05..446bfd7bf71 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -78,7 +78,7 @@ extern_libpython! { key: *const c_char, result: *mut *mut PyObject, ) -> c_int; - #[cfg(all(Py_3_15, not(Py_LIMITED_API)))] + #[cfg(all(Py_3_13, not(Py_LIMITED_API)))] pub fn PyDict_SetDefaultRef( mp: *mut PyObject, key: *mut PyObject, From d8ff2f7e2e2dee642893ca7273076d4bf014475d Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Sat, 11 Apr 2026 08:45:19 -0400 Subject: [PATCH 20/25] Comment out PyDict_SetDefaultRef function Comment out the PyDict_SetDefaultRef function definition for specific Python versions. --- pyo3-ffi/src/cpython/dictobject.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 8b2aee41d13..f6f0887bc7c 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -50,6 +50,7 @@ extern_libpython! { key: *mut PyObject, default_obj: *mut PyObject, ) -> *mut PyObject; + /* #[cfg(all(Py_3_13, not(Py_3_15)))] pub fn PyDict_SetDefaultRef( mp: *mut PyObject, @@ -57,6 +58,7 @@ extern_libpython! { default_obj: *mut PyObject, result: *mut *mut PyObject, ) -> c_int; + */ #[cfg(Py_3_13)] pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const c_char) -> c_int; #[cfg(Py_3_13)] From 86ddff955bbb366fa96417675468a60237cd5329 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 17 Apr 2026 11:50:52 -0400 Subject: [PATCH 21/25] Member naming Co-authored-by: Thomas Tanon --- pyo3-ffi/src/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index 446bfd7bf71..28b7ac1d4f1 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -82,7 +82,7 @@ extern_libpython! { pub fn PyDict_SetDefaultRef( mp: *mut PyObject, key: *mut PyObject, - default_obj: *mut PyObject, + default_value: *mut PyObject, result: *mut *mut PyObject, ) -> c_int; // skipped 3.10 / ex-non-limited PyObject_GenericGetDict From 88332715775e9e4377468a0e59435c00d54ee954 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 17 Apr 2026 11:51:25 -0400 Subject: [PATCH 22/25] Mark function as part of Stable API as of 3.15 Co-authored-by: Thomas Tanon --- pyo3-ffi/src/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/dictobject.rs b/pyo3-ffi/src/dictobject.rs index 28b7ac1d4f1..4df1265d4b8 100644 --- a/pyo3-ffi/src/dictobject.rs +++ b/pyo3-ffi/src/dictobject.rs @@ -78,7 +78,7 @@ extern_libpython! { key: *const c_char, result: *mut *mut PyObject, ) -> c_int; - #[cfg(all(Py_3_13, not(Py_LIMITED_API)))] + #[cfg(all(Py_3_13, any(not(Py_LIMITED_API), Py_3_15)))] pub fn PyDict_SetDefaultRef( mp: *mut PyObject, key: *mut PyObject, From 56a39010b80bba60d98f7b3f24b659aefbc322e2 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 17 Apr 2026 12:10:18 -0400 Subject: [PATCH 23/25] Reorder dictobject.rs to mirror upstream C header --- pyo3-ffi/src/cpython/dictobject.rs | 44 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index f6f0887bc7c..43db5312fc7 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -44,6 +44,14 @@ pub struct PyDictObject { _tmpkeys: *mut PyObject, } +extern_libpython! { + #[cfg(Py_3_15)] + pub fn PyFrozenDict_New(iterable: *mut PyObject) -> *mut PyObject; +} + +// skipped private _PyDict_GetItem_KnownHash +// skipped private _PyDict_GetItemStringWithError + extern_libpython! { pub fn PyDict_SetDefault( mp: *mut PyObject, @@ -58,9 +66,19 @@ extern_libpython! { default_obj: *mut PyObject, result: *mut *mut PyObject, ) -> c_int; - */ + */ +} + +// skipped PyDict_GET_SIZE + +extern_libpython! { #[cfg(Py_3_13)] pub fn PyDict_ContainsString(mp: *mut PyObject, key: *const c_char) -> c_int; +} + +// skipped private _PyDict_NewPresized + +extern_libpython! { #[cfg(Py_3_13)] pub fn PyDict_Pop(dict: *mut PyObject, key: *mut PyObject, result: *mut *mut PyObject) -> c_int; @@ -70,23 +88,8 @@ extern_libpython! { key: *const c_char, result: *mut *mut PyObject, ) -> c_int; - #[cfg(Py_3_12)] - pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; - #[cfg(Py_3_12)] - pub fn PyDict_Watch(watcher_id: c_int, dict: *mut PyObject) -> c_int; - #[cfg(Py_3_12)] - pub fn PyDict_Unwatch(watcher_id: c_int, dict: *mut PyObject) -> c_int; - #[cfg(Py_3_15)] - pub fn PyFrozenDict_New(iterable: *mut PyObject) -> *mut PyObject; } -// skipped private _PyDict_GetItem_KnownHash -// skipped private _PyDict_GetItemStringWithError - -// skipped PyDict_GET_SIZE - -// skipped private _PyDict_NewPresized - // skipped private _PyDict_Pop // skipped PY_FOREACH_DICT_EVENT @@ -95,3 +98,12 @@ extern_libpython! { // skipped PyDict_WatchCallback // skipped PyDict_AddWatcher + +extern_libpython! { + #[cfg(Py_3_12)] + pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; + #[cfg(Py_3_12)] + pub fn PyDict_Watch(watcher_id: c_int, dict: *mut PyObject) -> c_int; + #[cfg(Py_3_12)] + pub fn PyDict_Unwatch(watcher_id: c_int, dict: *mut PyObject) -> c_int; +} From 3d41d5f8502146d80ea25cb9d244d6c5543c11ab Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 17 Apr 2026 13:09:54 -0400 Subject: [PATCH 24/25] Space --- pyo3-ffi/src/cpython/dictobject.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 43db5312fc7..7b13e484eae 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -66,7 +66,7 @@ extern_libpython! { default_obj: *mut PyObject, result: *mut *mut PyObject, ) -> c_int; - */ + */ } // skipped PyDict_GET_SIZE From 86220d3561d2c0d13cceb02b4dd32401830cd42f Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Fri, 17 Apr 2026 14:36:03 -0400 Subject: [PATCH 25/25] Add GraalPy conditional compilation for dict functions --- pyo3-ffi/src/cpython/dictobject.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyo3-ffi/src/cpython/dictobject.rs b/pyo3-ffi/src/cpython/dictobject.rs index 7b13e484eae..cf5be14f3ee 100644 --- a/pyo3-ffi/src/cpython/dictobject.rs +++ b/pyo3-ffi/src/cpython/dictobject.rs @@ -53,6 +53,7 @@ extern_libpython! { // skipped private _PyDict_GetItemStringWithError extern_libpython! { + #[cfg(not(GraalPy))] pub fn PyDict_SetDefault( mp: *mut PyObject, key: *mut PyObject, @@ -103,7 +104,9 @@ extern_libpython! { #[cfg(Py_3_12)] pub fn PyDict_ClearWatcher(watcher_id: c_int) -> c_int; #[cfg(Py_3_12)] + #[cfg(not(GraalPy))] pub fn PyDict_Watch(watcher_id: c_int, dict: *mut PyObject) -> c_int; #[cfg(Py_3_12)] + #[cfg(not(GraalPy))] pub fn PyDict_Unwatch(watcher_id: c_int, dict: *mut PyObject) -> c_int; }