Fix passing of extra arguments to py_safe_call_once#7585
Merged
da-woods merged 2 commits intocython:masterfrom Apr 1, 2026
Merged
Fix passing of extra arguments to py_safe_call_once#7585da-woods merged 2 commits intocython:masterfrom
da-woods merged 2 commits intocython:masterfrom
Conversation
It wasn't compiling because I wasn't using `std::forward` correctly - they should be consistently forwarding references. Being able to pass arguments is useful because it can avoid the need for a closure in some cases.
Contributor
|
I can confirm this lets me remove the wrapper object I added in scipy/scipy#24799: diff --git a/scipy/spatial/_ckdtree.pyx b/scipy/spatial/_ckdtree.pyx
index 74de92ef58..31edd4acda 100644
--- a/scipy/spatial/_ckdtree.pyx
+++ b/scipy/spatial/_ckdtree.pyx
@@ -14,7 +14,7 @@ from scipy._lib._util import copy_if_needed
cimport numpy as np
from cpython.mem cimport PyMem_Malloc, PyMem_Free
-from libcpp.mutex cimport py_safe_call_object_once, py_safe_once_flag
+from libcpp.mutex cimport py_safe_call_once, py_safe_once_flag
from libcpp.vector cimport vector
from libcpp cimport bool
from libc.math cimport isinf, INFINITY
@@ -408,17 +408,11 @@ cdef np.intp_t get_num_workers(workers: object, kwargs: dict) except -1:
return n
-cdef class call_once_wrapper:
- cdef:
- cKDTree tree
-
- def __cinit__(call_once_wrapper self, cKDTree tree):
- self.tree = tree
-
- def __call__(self):
- n = cKDTreeNode()
- n._setup(self.tree, node=self.tree.cself.ctree, level=0)
- self.tree._python_tree = n
+cdef void init_pytree(void *void_tree):
+ cdef cKDTree tree = <cKDTree>void_tree
+ n = cKDTreeNode()
+ n._setup(tree, node=tree.cself.ctree, level=0)
+ tree._python_tree = n
# Main cKDTree class
@@ -558,9 +552,9 @@ cdef class cKDTree:
def __get__(cKDTree self):
cdef cKDTreeNode n
cdef ckdtree *cself = self.cself
- cdef call_once_wrapper wrapper
- wrapper = call_once_wrapper(self)
- py_safe_call_object_once(self.flag, wrapper)
+ # cast to void* is safe because it is either used to construct the
+ # python tree and then discarded or immediately discarded
+ py_safe_call_once(self.flag, init_pytree, <void *>self)
return self._python_tree
def __cinit__(cKDTree self): |
Contributor
Author
|
Try doing I think that might work with the current Cython version so wouldn't need to wait for the bug fix. Not an absolute promise though (this is typed on my phone without an easy way to test it) |
Contributor
I appreciate your phone programming! It does build. |
da-woods
added a commit
that referenced
this pull request
Apr 1, 2026
It wasn't compiling because I wasn't using `std::forward` correctly - they should be consistently forwarding references. Being able to pass arguments is useful because it can avoid the need for a closure in some cases.
Contributor
Author
|
3.2.x commit d7d6ae5 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
It wasn't compiling because I wasn't using
std::forwardcorrectly - they should be consistently forwarding references.Being able to pass arguments is useful because it can avoid the need for a closure in some cases.