Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-129342: Explain how to replace Py_GetProgramName() in C #129361

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Jan 27, 2025

@@ -622,7 +622,8 @@ Process-wide parameters
It now returns ``NULL`` if called before :c:func:`Py_Initialize`.

.. deprecated-removed:: 3.13 3.15
Get :data:`sys.executable` instead.
Use ``PySys_GetObject("executable")`` (:data:`sys.executable`) or
Copy link
Member

Choose a reason for hiding this comment

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

I think that PyConfig_Get("executable") is more preferable in a new code, isn't it?

PySys_GetObject() will be deprecated in future (it returns a borrowed reference and silences errors).

Copy link
Member Author

Choose a reason for hiding this comment

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

PySys_GetObject() works on all Python versions, whereas PyConfig_Get() is new in Python 3.14. The note can be updated once PySys_GetObject() will be deprecated.

Copy link
Member

Choose a reason for hiding this comment

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

We should suggest first what will work in future versions. We do not want users to rewrite the same code twice (and curse us twice).

Copy link
Contributor

Choose a reason for hiding this comment

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

PySys_GetObject() works on all Python versions, whereas PyConfig_Get() is new in Python 3.14.

I don't understand; this PR is for the 3.14 docs, so it should be ok to mention new-in-3.14 APIs here, no?

Copy link
Member Author

Choose a reason for hiding this comment

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

If possible, I would prefer to provide a replacement working on old Python versions as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

I updated the PR to use only PyConfig_Get().

@@ -622,7 +622,8 @@ Process-wide parameters
It now returns ``NULL`` if called before :c:func:`Py_Initialize`.

.. deprecated-removed:: 3.13 3.15
Copy link
Member

Choose a reason for hiding this comment

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

I think that we should postpone hard deprecation until there is a non-deprecated replacement that works in all maintained Python versions.

Copy link
Member Author

Choose a reason for hiding this comment

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

PySys_GetObject() works on all Python versions, it's not deprecated: https://docs.python.org/dev/c-api/sys.html#c.PySys_GetObject

Copy link
Member Author

Choose a reason for hiding this comment

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

You can use pythoncapi-compat to get PyConfig_Get() on Python 3.13 and older.

@vstinner
Copy link
Member Author

@serhiy-storchaka: I think that we already had this discusssion about PySys_GetObject() which returns a borrowed reference. So I created #129367 to propose adding PySys_GetAttr() function which returns a strong reference and doesn't ignore errors :-)

@jwuttke
Copy link
Contributor

jwuttke commented Jan 27, 2025

Much better than status quo, but in my opinion not sufficient to resolve #129342.

Imagine the worst-case scenario, which is exactly what happened to me: Somebody has to maintain a huge amount of C code, with lots of dependencies, and without being an expert for each library dependency. Such a user, after hitting a deprecation warning, needs complete, self-contained instructions how to replace the deprecated code.

The current MR won't do, because the functions proposed for replacement return a different data type than the deprecated functions.

Therefore, in addition to the changes proposed here, we need a link to a separate page that explains how to replace a function that returned a const wchar_t* by a function that returns a PyObject*.

@vstinner
Copy link
Member Author

Therefore, in addition to the changes proposed here, we need a link to a separate page that explains how to replace a function that returned a const wchar_t* by a function that returns a PyObject*.

If you have a Python str object, wstr = PyUnicode_AsWideCharString(str, NULL) can be used to get a wchar_t* string. It requires calling PyMem_Free(wstr) once done with the wide string.

@jwuttke
Copy link
Contributor

jwuttke commented Jan 27, 2025

If you have a Python str object, wstr = PyUnicode_AsWideCharString(str, NULL) can be used to get a wchar_t* string. It requires calling PyMem_Free(wstr) once done with the wide string.

Excellent. Just two sentences to be added to each deprecation note.

Copy link
Contributor

@StanFromIreland StanFromIreland left a comment

Choose a reason for hiding this comment

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

Everything looks good to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting core review docs Documentation in the Doc dir skip news
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.

5 participants