-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
gh-108512: Add and use new replacements for PySys_GetObject() #111035
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
base: main
Are you sure you want to change the base?
Changes from all commits
4d0f508
eb42b39
2d4588d
2eb9533
9fc2f3d
65713ce
e6ecf11
8a0f5f2
516829e
9503aaf
e2857ef
dc26ec2
104dcc2
cf75fc3
9434659
56639d8
b40a665
03b9c0a
5d793c5
09869ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -258,10 +258,55 @@ These are utility functions that make functionality from the :mod:`sys` module | |||||||||||||||||||||||||
accessible to C code. They all work with the current interpreter thread's | ||||||||||||||||||||||||||
:mod:`sys` module's dict, which is contained in the internal thread state structure. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. c:function:: PyObject *PySys_GetAttr(PyObject *name) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Get the attribute *name* of the :mod:`sys` module. Return a :term:`strong reference`. | ||||||||||||||||||||||||||
Raise :exc:`RuntimeError` and return ``NULL`` if it does not exist. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
If the non-existing object should not be treated as a failure, you can use | ||||||||||||||||||||||||||
:c:func:`PySys_GetOptionalAttr` instead. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. versionadded:: next | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. c:function:: PyObject *PySys_GetAttrString(const char *name) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
This is the same as :c:func:`PySys_GetAttr`, but *name* is | ||||||||||||||||||||||||||
specified as a :c:expr:`const char*` UTF-8 encoded bytes string, | ||||||||||||||||||||||||||
rather than a :c:expr:`PyObject*`. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
If the non-existing object should not be treated as a failure, you can use | ||||||||||||||||||||||||||
:c:func:`PySys_GetOptionalAttrString` instead. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. versionadded:: next | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. c:function:: int PySys_GetOptionalAttr(PyObject *name, PyObject **result); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Variant of :c:func:`PySys_GetAttr` which doesn't raise | ||||||||||||||||||||||||||
exception if the object does not exist. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
If the object exists, set *\*result* to a new :term:`strong reference` | ||||||||||||||||||||||||||
to the object and return ``1``. | ||||||||||||||||||||||||||
If the object does not exist, set *\*result* to ``NULL`` and return ``0``, | ||||||||||||||||||||||||||
without setting an exception. | ||||||||||||||||||||||||||
If other error occurred, set an exception, set *\*result* to ``NULL`` and | ||||||||||||||||||||||||||
return ``-1``. | ||||||||||||||||||||||||||
Comment on lines
+287
to
+292
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest to use a list and start with the return value, so it's easier to see the 3 cases:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Return and then set exception and variable" looks like a wrong sequence to me. It cannot do anything after returning. |
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. versionadded:: next | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. c:function:: int PySys_GetOptionalAttrString(const char *name, PyObject **result); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
This is the same as :c:func:`PySys_GetOptionalAttr`, but *name* is | ||||||||||||||||||||||||||
specified as a :c:expr:`const char*` UTF-8 encoded bytes string, | ||||||||||||||||||||||||||
rather than a :c:expr:`PyObject*`. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. versionadded:: next | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. c:function:: PyObject *PySys_GetObject(const char *name) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Return the object *name* from the :mod:`sys` module or ``NULL`` if it does | ||||||||||||||||||||||||||
not exist, without setting an exception. | ||||||||||||||||||||||||||
Similar to :c:func:`PySys_GetAttrString`, but return a :term:`borrowed | ||||||||||||||||||||||||||
reference` and return ``NULL`` *without* setting exception on failure. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Preserves exception that was set before the call. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
.. c:function:: int PySys_SetObject(const char *name, PyObject *v) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#ifndef Py_CPYTHON_SYSMODULE_H | ||
# error "this header file must not be included directly" | ||
#endif | ||
|
||
typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); | ||
|
||
PyAPI_FUNC(int) PySys_Audit( | ||
const char *event, | ||
const char *format, | ||
...); | ||
PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); | ||
|
||
typedef struct { | ||
FILE* perf_map; | ||
PyThread_type_lock map_lock; | ||
} PerfMapState; | ||
|
||
PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void); | ||
PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry( | ||
const void *code_addr, | ||
unsigned int code_size, | ||
const char *entry_name); | ||
PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Add functions :c:func:`PySys_GetAttr`, :c:func:`PySys_GetAttrString`, | ||
:c:func:`PySys_GetOptionalAttr` and :c:func:`PySys_GetOptionalAttrString`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to raise AttributeError.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we would need a new pair of functions that raise RuntimeError to use in the CPython code. Or you can add a pair of functions that raise AttributeError later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind to elaborate why RuntimeError is needed by CPython?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Status quo. And it looks to me it is justified by the purpose of RuntimeError: "Raised when an error is detected that doesn’t fall in any of the other categories."
If you want to change RuntimeError's in the existing code to something other, you should justify that change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my implementation #129369,
PySys_SetAttr()
raisesRuntimeError
if thesys
module cannot be retrieved. But it raisesAttributeError
if the attribute doesn't exist.PySys_GetObject()
ignores all errors and returnsNULL
on error or if the attribute doesn't exist. So I'm confused, which function usingPySys_GetObject()
currently rely on theRuntimeError
? Do you have an example?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About a half of functions that use
PySys_GetObject()
or_PySys_GetAttr()
raise RuntimeError if they return NULL. See my statistics in capi-workgroup/decisions#54. Look at usages ofPySys_GetAttr()
andPySys_GetAttrString()
in this PR.