Skip to content

Commit 55c1c16

Browse files
committed
Emit a deprecation warning about a future change of sys.abiflags availability on Windows
1 parent f1967e7 commit 55c1c16

File tree

4 files changed

+84
-3
lines changed

4 files changed

+84
-3
lines changed

Doc/library/sys.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@ always available. Unless explicitly noted otherwise, all variables are read-only
2222
Default flags became an empty string (``m`` flag for pymalloc has been
2323
removed).
2424

25+
.. versionchanged:: 3.14
26+
A deprecation warning will be emitted if the :data:`sys.abiflags` member
27+
is accessed on Windows.
28+
For example:
29+
30+
.. code-block:: python
31+
32+
>>> import sys
33+
>>> getattr(sys, 'abiflags', '')
34+
DeprecationWarning: sys.abiflags will be set to a meaningful value on all platforms ...
35+
36+
Due to historical reasons, :data:`sys.abiflags` is not covered by
37+
:pep:`3149` on Windows. Now we have multiple builds, such as the
38+
:term:`free-threaded <free threading>` build, that provide different ABIs.
39+
:data:`sys.abiflags` is now required under many circumstances to determine
40+
the ABI of the Python interpreter.
41+
42+
The :data:`sys.abiflags` member will be set to a meaningful value on
43+
Windows in Python 3.16. This means the :data:`sys.abiflags` member will
44+
always be available on all platforms starting from Python 3.16.
45+
2546
.. availability:: Unix.
2647

2748

Lib/test/test_sys.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,13 @@ def test_attributes(self):
698698
self.assertIn(sys.float_repr_style, ('short', 'legacy'))
699699
if not sys.platform.startswith('win'):
700700
self.assertIsInstance(sys.abiflags, str)
701+
else:
702+
absent = object()
703+
with self.assertWarnsRegex(
704+
DeprecationWarning,
705+
r'sys\.abiflags is going to be set.*on all platforms',
706+
):
707+
self.assertIs(getattr(sys, 'abiflags', absent), absent)
701708

702709
def test_thread_info(self):
703710
info = sys.thread_info

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,7 @@ Todd R. Palmer
14021402
Juan David Ibáñez Palomar
14031403
Nicola Palumbo
14041404
Jan Palus
1405+
Xuehai Pan
14051406
Yongzhi Pan
14061407
Martin Panter
14071408
Mathias Panzenböck

Python/sysmodule.c

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ _PySys_GetRequiredAttr(PyObject *name)
9292
}
9393
PyObject *value;
9494
if (PyDict_GetItemRef(sysdict, name, &value) == 0) {
95+
#ifndef ABIFLAGS
96+
if (_PyUnicode_EqualToASCIIString(name, "abiflags")) {
97+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
98+
"sys.abiflags will be set to a meaningful value "
99+
"on all platforms in Python 3.16 instead of absent",
100+
/*stack_level=*/1) < 0) {
101+
return NULL;
102+
}
103+
}
104+
#endif
95105
PyErr_Format(PyExc_RuntimeError, "lost sys.%U", name);
96106
}
97107
return value;
@@ -108,6 +118,16 @@ _PySys_GetRequiredAttrString(const char *name)
108118
}
109119
PyObject *value;
110120
if (PyDict_GetItemStringRef(sysdict, name, &value) == 0) {
121+
#ifndef ABIFLAGS
122+
if (strcmp(name, "abiflags") == 0) {
123+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
124+
"sys.abiflags will be set to a meaningful value "
125+
"on all platforms in Python 3.16 instead of absent",
126+
/*stack_level=*/1) < 0) {
127+
return NULL;
128+
}
129+
}
130+
#endif
111131
PyErr_Format(PyExc_RuntimeError, "lost sys.%s", name);
112132
}
113133
return value;
@@ -129,7 +149,18 @@ _PySys_GetOptionalAttr(PyObject *name, PyObject **value)
129149
*value = NULL;
130150
return 0;
131151
}
132-
return PyDict_GetItemRef(sysdict, name, value);
152+
int ret = PyDict_GetItemRef(sysdict, name, value);
153+
#ifndef ABIFLAGS
154+
if (ret == 0 && _PyUnicode_EqualToASCIIString(name, "abiflags")) {
155+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
156+
"sys.abiflags will be set to a meaningful value "
157+
"on all platforms in Python 3.16 instead of absent",
158+
/*stack_level=*/1) < 0) {
159+
return -1;
160+
}
161+
}
162+
#endif
163+
return ret;
133164
}
134165

135166
int
@@ -141,7 +172,18 @@ _PySys_GetOptionalAttrString(const char *name, PyObject **value)
141172
*value = NULL;
142173
return 0;
143174
}
144-
return PyDict_GetItemStringRef(sysdict, name, value);
175+
int ret = PyDict_GetItemStringRef(sysdict, name, value);
176+
#ifndef ABIFLAGS
177+
if (ret == 0 && strcmp(name, "abiflags") == 0) {
178+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
179+
"sys.abiflags will be set to a meaningful value "
180+
"on all platforms in Python 3.16 instead of absent",
181+
/*stack_level=*/1) < 0) {
182+
return -1;
183+
}
184+
}
185+
#endif
186+
return ret;
145187
}
146188

147189
PyObject *
@@ -154,14 +196,24 @@ PySys_GetObject(const char *name)
154196
}
155197
PyObject *exc = _PyErr_GetRaisedException(tstate);
156198
PyObject *value;
157-
(void) PyDict_GetItemStringRef(sysdict, name, &value);
199+
int ret = PyDict_GetItemStringRef(sysdict, name, &value);
158200
/* XXX Suppress a new exception if it was raised and restore
159201
* the old one. */
160202
if (_PyErr_Occurred(tstate)) {
161203
PyErr_FormatUnraisable("Exception ignored in PySys_GetObject()");
162204
}
163205
_PyErr_SetRaisedException(tstate, exc);
164206
Py_XDECREF(value); // return a borrowed reference
207+
#ifndef ABIFLAGS
208+
if (ret == 0 && strcmp(name, "abiflags") == 0) {
209+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
210+
"sys.abiflags will be set to a meaningful value "
211+
"on all platforms in Python 3.16 instead of absent",
212+
/*stack_level=*/1) < 0) {
213+
return NULL;
214+
}
215+
}
216+
#endif
165217
return value;
166218
}
167219

0 commit comments

Comments
 (0)