Skip to content

Conversation

@cxzhong
Copy link
Contributor

@cxzhong cxzhong commented Nov 5, 2025

This change replaces direct access to ob_refcnt with proper API functions:

  • Use _Py_REFCNT() for reading reference counts
  • Use Py_SET_REFCNT() for setting reference counts

This ensures compatibility with Python's free-threaded mode and follows Python's recommended practices for reference count manipulation.

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

⌛ Dependencies

This change replaces direct access to ob_refcnt with proper API functions:
- Use _Py_REFCNT() for reading reference counts
- Use Py_SET_REFCNT() for setting reference counts

This ensures compatibility with Python's free-threaded mode and follows
Python's recommended practices for reference count manipulation.

Changes:
- src/sage/matrix/args.pxd: Use _Py_REFCNT instead of direct ob_refcnt access
- src/sage/rings/integer.pyx: Use Py_SET_REFCNT for setting refcount
- src/sage/rings/real_double.pyx: Use Py_SET_REFCNT for setting refcount
- src/sage/symbolic/ginac/numeric.cpp: Refactor Py_INCREF/Py_DECREF macros

Backported from passagemath/passagemath#1761
@github-actions
Copy link

github-actions bot commented Nov 5, 2025

Documentation preview for this PR (built with commit cedb4c9; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@dimpase
Copy link
Member

dimpase commented Nov 5, 2025

I am not too sure about _Py* - these are not for the public use, or at least they cannot be considered a stable API, no? @tobiasdiez ?

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 5, 2025

I am not too sure about _Py* - these are not for the public use, or at least they cannot be considered a stable API, no? @tobiasdiez ?

from cpython.ref import _Py_REFCNT, it is from cython file, nor direcly from cpython.
https://github.com/cython/cython/blob/master/Cython/Includes/cpython/ref.pxd
It just like cdef extern from 'Python.h'
And we use it in cysignals and cypari2 several times.
So it is Open API in cpython

Copy link
Contributor

@tobiasdiez tobiasdiez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's public API, at least it's mentioned in the docs: https://cython.readthedocs.io/en/latest/src/userguide/language_basics.html#python-objects-as-parameters-and-return-values

It looks to me that the new Py_SET_REFCNT can be replaced by Py_INCREF/Py_DECREF, which are also available from cython.ref, and is a bit nicer.

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 5, 2025

I think it's public API, at least it's mentioned in the docs: https://cython.readthedocs.io/en/latest/src/userguide/language_basics.html#python-objects-as-parameters-and-return-values

It looks to me that the new Py_SET_REFCNT can be replaced by Py_INCREF/Py_DECREF, which are also available from cython.ref, and is a bit nicer.

But it does not like the original meaning. I think that The original meaning is to set the ref number is 1

@tobiasdiez
Copy link
Contributor

I think it's public API, at least it's mentioned in the docs: https://cython.readthedocs.io/en/latest/src/userguide/language_basics.html#python-objects-as-parameters-and-return-values
It looks to me that the new Py_SET_REFCNT can be replaced by Py_INCREF/Py_DECREF, which are also available from cython.ref, and is a bit nicer.

But it does not like the original meaning. I think that The original meaning is to set the ref number is 1

It increases it from 0 to 1, or not?

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 6, 2025

I think it's public API, at least it's mentioned in the docs: https://cython.readthedocs.io/en/latest/src/userguide/language_basics.html#python-objects-as-parameters-and-return-values
It looks to me that the new Py_SET_REFCNT can be replaced by Py_INCREF/Py_DECREF, which are also available from cython.ref, and is a bit nicer.

But it does not like the original meaning. I think that The original meaning is to set the ref number is 1

It increases it from 0 to 1, or not?

The annotation said

  # The global_dummy_Integer may have a reference count larger than
  # one, but it is expected that newly created objects have a
  # reference count of one. This is potentially unneeded if
  # everybody plays nice, because the global_dummy_Integer has only
  # one reference in that case.

So the ref count may be larger than 1

@tobiasdiez
Copy link
Contributor

oh, misread this part. Sorry. But in ginac it is really just increasing & decreasing, right?

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 6, 2025

oh, misread this part. Sorry. But in ginac it is really just increasing & decreasing, right?

It seems it redefine the Py_INCREF and Py_DECREF. I do not know why it needs to do that. I just preserve the original code's meaning.

@cxzhong
Copy link
Contributor Author

cxzhong commented Nov 6, 2025

oh, misread this part. Sorry. But in ginac it is really just increasing & decreasing, right?

And before that, it undefine the two functions

#undef Py_INCREF
#undef Py_DECREF

@cxzhong cxzhong requested a review from tobiasdiez November 11, 2025 06:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants