Skip to content

gh-127405: Emit a deprecation warning about a future change of sys.abiflags availability on Windows #131717

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

Open
wants to merge 61 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
55c1c16
Emit a deprecation warning about a future change of `sys.abiflags` av…
XuehaiPan Mar 25, 2025
198ee26
📜🤖 Added by blurb_it.
blurb-it[bot] Mar 25, 2025
4a1ed1b
Update test regex
XuehaiPan Mar 25, 2025
2ebe498
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 25, 2025
6bc3d73
Remove unexpected new entry
XuehaiPan Mar 25, 2025
85a8bae
ignore unused variable warning
XuehaiPan Mar 25, 2025
5172fda
Set custom `sys.__getattr__`
XuehaiPan Mar 25, 2025
e2c0326
Catch warnings in stdlib
XuehaiPan Mar 25, 2025
50a37fb
Catch warnings in stdlib
XuehaiPan Mar 25, 2025
2236ed6
Add comments for `sys.__getattr__`
XuehaiPan Mar 25, 2025
3467028
Catch warnings in stdlib
XuehaiPan Mar 25, 2025
5b4f0eb
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 25, 2025
143145f
Resolve leak reference on warning failure
XuehaiPan Mar 25, 2025
0fd098f
Revert "Resolve leak reference on warning failure"
XuehaiPan Mar 25, 2025
abc1638
Add more tests
XuehaiPan Mar 25, 2025
0a69992
Only add `sys.__getattr__` on Windows
XuehaiPan Mar 25, 2025
d49abc9
Update code examples in docs
XuehaiPan Mar 25, 2025
8aa5556
Update code examples in docs
XuehaiPan Mar 25, 2025
299c0d3
properly indent code
XuehaiPan Mar 25, 2025
6c4bb07
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 25, 2025
4503529
Revert "Only add `sys.__getattr__` on Windows"
XuehaiPan Mar 25, 2025
437ba52
Extract common code into defs
XuehaiPan Mar 25, 2025
f20232a
Add migration guide in docs
XuehaiPan Mar 25, 2025
5401970
Add blanklines
XuehaiPan Mar 25, 2025
55160bf
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 25, 2025
2eeac04
Add more details in warning message
XuehaiPan Mar 26, 2025
ac8005c
Add more details in warning message
XuehaiPan Mar 26, 2025
cfeaa3c
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 26, 2025
65297cd
Resolve unused variable warning
XuehaiPan Mar 26, 2025
ba015a3
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 27, 2025
4148d8c
Fix code indentation
XuehaiPan Mar 27, 2025
78c0cab
Merge branch 'main' into windows-add-sys-abiflags
graingert Mar 29, 2025
7e84118
Handle warnings in unittest marker
XuehaiPan Mar 29, 2025
49f8d89
Clarify comments
XuehaiPan Mar 29, 2025
56c7d91
Update docs
XuehaiPan Mar 29, 2025
7884a62
Simplify `sys.abiflags` in `sysconfig` and `site`
XuehaiPan Mar 29, 2025
a5739ba
Simplify `sys.abiflags` in `sysconfig` and `site`
XuehaiPan Mar 29, 2025
21ae49d
Revert "Simplify `sys.abiflags` in `sysconfig` and `site`"
XuehaiPan Mar 29, 2025
74454ab
Revert "Simplify `sys.abiflags` in `sysconfig` and `site`"
XuehaiPan Mar 29, 2025
45be11d
Simplify `sys.abiflags` in `site`
XuehaiPan Mar 29, 2025
0864441
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 30, 2025
1b8439b
Apply suggestions from code review
XuehaiPan Mar 30, 2025
bec62dc
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 30, 2025
66c7b90
Resolve unused function warning
XuehaiPan Mar 30, 2025
0d30914
Add todo comments around workarounds
XuehaiPan Mar 30, 2025
659e573
Move migration guide to What's New docs
XuehaiPan Mar 30, 2025
458ef7d
Apply suggestions from code review
XuehaiPan Mar 30, 2025
2ff7082
Apply suggestions from code review
XuehaiPan Mar 30, 2025
2e79345
Add a todo note in docs
XuehaiPan Mar 30, 2025
36efb72
Add message regex in warning filters
XuehaiPan Mar 31, 2025
25b299a
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Mar 31, 2025
d23ab00
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Apr 13, 2025
c8ec513
Add `sysconfig.get_config_vars` to what's new notes
XuehaiPan Apr 13, 2025
a4c575b
Fix auto merge commit
XuehaiPan Apr 13, 2025
96b224d
Update tests
XuehaiPan Apr 13, 2025
81ef28e
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Apr 14, 2025
1b634c4
Update todo comments
XuehaiPan Apr 14, 2025
2381107
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan Apr 16, 2025
958dd06
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan May 1, 2025
5ad6305
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan May 6, 2025
9b7d586
Merge branch 'main' into windows-add-sys-abiflags
XuehaiPan May 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ always available. Unless explicitly noted otherwise, all variables are read-only

.. availability:: Unix.

.. versionchanged:: next
A :exc:`DeprecationWarning` will be emitted if the :data:`sys.abiflags`
member is accessed on Windows before Python 3.16. The :data:`!sys.abiflags`
member will be set to a meaningful value on Windows in Python 3.16. This
means the :data:`!sys.abiflags` member will always be available on all
platforms starting from Python 3.16.

See the notes for :ref:`incoming change to sys.abiflags
<whatsnew314-sys-abiflags-change>` on the *What's New in 3.14*
page for more details.
Comment on lines +34 to +36
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The first beta version of Python 3.14 is out. Any comment on this?


.. TODO: When we're in Python 3.16:
- Add a **CAUTION** section about the differences of :data:`sys.abiflags`
between prior-3.14, 3.14-3.15, and 3.16+ on Windows.
- Move porting recommendations from whatsnew/3.14.rst.


.. function:: addaudithook(hook)

Expand Down
62 changes: 62 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,66 @@ sys
* Raise :exc:`DeprecationWarning` for :func:`sys._clear_type_cache`. This
function was deprecated in Python 3.13 but it didn't raise a runtime warning.

* Schedule a change for availability of :data:`sys.abiflags` on Windows. A
:exc:`DeprecationWarning` will be emitted if the :data:`!sys.abiflags` member
is accessed on Windows before Python 3.16.
(Contributed by Xuehai Pan in :gh:`131717`.)


.. _whatsnew314-sys-abiflags-change:

sys.abiflags
------------

A :exc:`DeprecationWarning` will be emitted if the :data:`sys.abiflags` member
is accessed on Windows before Python 3.16.
For example:

.. code-block:: python

>>> import sys
>>> getattr(sys, 'abiflags', None) # on Windows
<python-input-1>:1: DeprecationWarning: sys.abiflags will be set to a meaningful value on all platforms ...
>>> hasattr(sys, 'abiflags') # on Windows
<python-input-2>:1: DeprecationWarning: sys.abiflags will be set to a meaningful value on all platforms ...
False

To suppress this warning, use the :mod:`warnings` module:

.. code-block:: python

import warnings

with warnings.catch_warnings():
# ignore DeprecationWarning on incoming sys.abiflags change on Windows before 3.16
warnings.simplefilter('ignore', DeprecationWarning)
abiflags = getattr(sys, 'abiflags', '')

Due to historical reasons, :data:`sys.abiflags` is not covered by
:pep:`3149` on Windows. Now we have multiple builds, such as the
:term:`free-threaded <free threading>` build, that provide different ABIs.
:data:`!sys.abiflags` is now required under many circumstances to determine
the ABI of the Python interpreter.

The :data:`!sys.abiflags` member will be set to a meaningful value on
Windows in Python 3.16. This means the :data:`!sys.abiflags` member will
always be available on all platforms starting from Python 3.16.
Before this incoming change is made, :func:`sysconfig.get_config_vars` would be
useful. See also :ref:`Changes of **sysconfig** <whatsnew314-sysconfig-abiflags>`.

The following table shows how to migrate from the old code to the new code
without changing the behavior:

+---------------------------------------+---------------------------------------------------------------------+
| Code prior to Python 3.14 | Code prior to Python 3.16 with the same behavior |
+=======================================+=====================================================================+
| ``sys.abiflags`` | ``sys.abiflags`` |
+---------------------------------------+---------------------------------------------------------------------+
| ``getattr(sys, 'abiflags', default)`` | ``sys.abiflags if not sys.platform.startswith('win') else default`` |
+---------------------------------------+---------------------------------------------------------------------+
| ``hasattr(sys, 'abiflags')`` | ``not sys.platform.startswith('win')`` |
+---------------------------------------+---------------------------------------------------------------------+


sys.monitoring
--------------
Expand All @@ -1701,6 +1761,8 @@ sys.monitoring
:monitoring-event:`BRANCH_RIGHT`. The ``BRANCH`` event is deprecated.


.. _whatsnew314-sysconfig-abiflags:

sysconfig
---------

Expand Down
13 changes: 3 additions & 10 deletions Lib/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,6 @@ def joinuser(*args):
# Same to sysconfig.get_path('purelib', os.name+'_user')
def _get_path(userbase):
version = sys.version_info
if hasattr(sys, 'abiflags') and 't' in sys.abiflags:
abi_thread = 't'
else:
abi_thread = ''

implementation = _get_implementation()
implementation_lower = implementation.lower()
if os.name == 'nt':
Expand All @@ -332,6 +327,7 @@ def _get_path(userbase):
if sys.platform == 'darwin' and sys._framework:
return f'{userbase}/lib/{implementation_lower}/site-packages'

abi_thread = 't' if 't' in sys.abiflags else ''
return f'{userbase}/lib/python{version[0]}.{version[1]}{abi_thread}/site-packages'


Expand Down Expand Up @@ -400,11 +396,8 @@ def getsitepackages(prefixes=None):

implementation = _get_implementation().lower()
ver = sys.version_info
if hasattr(sys, 'abiflags') and 't' in sys.abiflags:
abi_thread = 't'
else:
abi_thread = ''
if os.sep == '/':
if os.name != 'nt':
abi_thread = 't' if 't' in sys.abiflags else ''
libdirs = [sys.platlibdir]
if sys.platlibdir != "lib":
libdirs.append("lib")
Expand Down
22 changes: 17 additions & 5 deletions Lib/sysconfig/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ def get_default_scheme():

def get_makefile_filename():
"""Return the path of the Makefile."""
import warnings

# GH-127429: When cross-compiling, use the Makefile from the target, instead of the host Python.
if cross_base := os.environ.get('_PYTHON_PROJECT_BASE'):
Expand All @@ -322,7 +323,14 @@ def get_makefile_filename():
if _PYTHON_BUILD:
return os.path.join(_PROJECT_BASE, "Makefile")

if hasattr(sys, 'abiflags'):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are there any details about the existence of sys.abiflags for cross-compiling for Windows on Ubuntu? I found it might be non-trivial to replace the following with one another:

hasattr(sys, 'abiflags')
os.name == 'nt'  # os.name != 'posix'
not sys.platform.startswith('win')

# TODO: Remove this in Python 3.16.
# This flag will always be True since Python 3.16.
with warnings.catch_warnings():
# ignore DeprecationWarning on sys.abiflags change on Windows
warnings.filterwarnings('ignore', r'sys\.abiflags', category=DeprecationWarning)
has_abiflags = hasattr(sys, 'abiflags')

if has_abiflags:
config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}'
else:
config_dir_name = 'config'
Expand Down Expand Up @@ -496,6 +504,8 @@ def get_path(name, scheme=get_default_scheme(), vars=None, expand=True):


def _init_config_vars():
import warnings

global _CONFIG_VARS
_CONFIG_VARS = {}

Expand All @@ -504,10 +514,12 @@ def _init_config_vars():
base_prefix = _BASE_PREFIX
base_exec_prefix = _BASE_EXEC_PREFIX

try:
abiflags = sys.abiflags
except AttributeError:
abiflags = ''
# XXX: Remove this context manager in Python 3.16
# sys.abiflags will always be available on all platforms since Python 3.16
with warnings.catch_warnings():
# ignore DeprecationWarning on sys.abiflags change on Windows
warnings.simplefilter('ignore', DeprecationWarning)
abiflags = getattr(sys, 'abiflags', '')

if os.name == 'posix':
_init_posix(_CONFIG_VARS)
Expand Down
9 changes: 8 additions & 1 deletion Lib/test/pythoninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ def get_infos(self):

def copy_attributes(info_add, obj, name_fmt, attributes, *, formatter=None):
for attr in attributes:
value = getattr(obj, attr, None)
if attr == 'abiflags':
# TODO: Remove this special case handling in Python 3.16
with warnings.catch_warnings():
# ignore DeprecationWarning on sys.abiflags change on Windows
warnings.filterwarnings('ignore', r'sys\.abiflags', category=DeprecationWarning)
value = getattr(obj, attr, None)
else:
value = getattr(obj, attr, None)
if value is None:
continue
name = name_fmt % attr
Expand Down
9 changes: 9 additions & 0 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,15 @@ def check_bolt_optimized():
return '--enable-bolt' in config_args


# TODO: Remove this in Python 3.16.
# This flag will always be True since Python 3.16.
with warnings.catch_warnings():
# ignore DeprecationWarning on sys.abiflags change on Windows
warnings.filterwarnings('ignore', r'sys\.abiflags', category=DeprecationWarning)
# Equal to `not sys.platform.startswith('win')` prior to 3.16
HAS_SYS_ABIFLAGS = hasattr(sys, 'abiflags')


Py_GIL_DISABLED = bool(sysconfig.get_config_var('Py_GIL_DISABLED'))

def requires_gil_enabled(msg="needs the GIL enabled"):
Expand Down
29 changes: 27 additions & 2 deletions Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,9 +723,34 @@ def test_attributes(self):
self.assertIsInstance(sys.float_repr_style, str)
self.assertIn(sys.float_repr_style, ('short', 'legacy'))
if not sys.platform.startswith('win'):
self.assertEqual(os.name, 'posix')
self.assertIsInstance(sys.abiflags, str)
else:
self.assertFalse(hasattr(sys, 'abiflags'))
self.assertEqual(os.name, 'nt')
# TODO: Simpify the tests.
# sys.abiflags will be defined on Windows in Python 3.16.
absent = object()
with self.assertWarnsRegex(
DeprecationWarning,
r'sys\.abiflags will be set\b.*\bon all platforms',
):
self.assertIs(getattr(sys, 'abiflags', absent), absent)
with self.assertWarnsRegex(
DeprecationWarning,
r'sys\.abiflags will be set\b.*\bon all platforms',
):
self.assertFalse(hasattr(sys, 'abiflags'))

# Emit a deprecated warning and also raise an AttributeError
with self.assertRaisesRegex(
AttributeError,
r"module 'sys' has no attribute 'abiflags'",
):
with self.assertWarnsRegex(
DeprecationWarning,
r'sys\.abiflags will be set\b.*\bon all platforms',
):
_ = sys.abiflags

def test_thread_info(self):
info = sys.thread_info
Expand Down Expand Up @@ -1341,7 +1366,7 @@ def test_pystats(self):
sys._stats_dump()

@test.support.cpython_only
@unittest.skipUnless(hasattr(sys, 'abiflags'), 'need sys.abiflags')
@unittest.skipUnless(support.HAS_SYS_ABIFLAGS, 'need sys.abiflags')
def test_disable_gil_abi(self):
self.assertEqual('t' in sys.abiflags, support.Py_GIL_DISABLED)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Emit a :exc:`DeprecationWarning` about a future change of :data:`sys.abiflags` availability on Windows. Patch by Xuehai Pan.
Loading
Loading