Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
31b7eab
Add `ABIFLAGS` to `sysconfig.get_config_vars()` on Windows
XuehaiPan Mar 27, 2025
dc45897
📜🤖 Added by blurb_it.
blurb-it[bot] Mar 27, 2025
9a4586a
Add tests
XuehaiPan Mar 27, 2025
76c85bb
Move `ABIFLAGS` definition to C code
XuehaiPan Mar 28, 2025
b98419b
Revert now unrelated changes
XuehaiPan Mar 28, 2025
4729f76
Fix variable name
XuehaiPan Mar 28, 2025
04cbb1c
Refactor string concatination
XuehaiPan Mar 28, 2025
a6045ea
Set `Py_DEBUG` flag in sysconfig
XuehaiPan Mar 28, 2025
584e0b0
Update comments from code review
XuehaiPan Mar 28, 2025
93257be
Prefer `Py_DEBUG` over `_DEBUG`
XuehaiPan Mar 28, 2025
30c7b56
Add tests
XuehaiPan Mar 28, 2025
97942b2
Add tests
XuehaiPan Mar 28, 2025
917874c
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Mar 28, 2025
f49067e
Update tests
XuehaiPan Mar 28, 2025
8fa952b
Update tests
XuehaiPan Mar 28, 2025
08d92db
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Mar 29, 2025
b667dd9
Remove unnecessary comments
XuehaiPan Mar 30, 2025
30cf6c7
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Mar 30, 2025
5df9540
Update What's New
XuehaiPan Mar 30, 2025
018aae3
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Mar 30, 2025
4f22ff3
Revert `PCbuild/pyproject.props`
XuehaiPan Mar 31, 2025
f918241
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Mar 31, 2025
a4646c5
Revert `_DEBUG` -> `Py_DEBUG`
XuehaiPan Mar 31, 2025
7b21d7d
Revert `_DEBUG` -> `Py_DEBUG`
XuehaiPan Mar 31, 2025
1ee8230
Add underscore prefix to `d` on Windows
XuehaiPan Mar 31, 2025
084deac
Fix key name
XuehaiPan Mar 31, 2025
af50632
Add comments for test for `d` flag in `ABIFLAGS`
XuehaiPan Mar 31, 2025
b397f40
Fix failing test
XuehaiPan Mar 31, 2025
1a82cd1
Update tests
XuehaiPan Mar 31, 2025
7990798
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Mar 31, 2025
0744690
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 3, 2025
518137b
Add a test for `sysconfig.get_config_var('ABIFLAGS')` on Windows
XuehaiPan Apr 3, 2025
486e2a8
Rename test function
XuehaiPan Apr 3, 2025
3bccf1d
Move test location
XuehaiPan Apr 3, 2025
780f340
Move test location
XuehaiPan Apr 3, 2025
98c26f9
Add a note for `test_abiflags`
XuehaiPan Apr 3, 2025
e236bc7
Move definition of ABIFLAGS from C to Python
XuehaiPan Apr 3, 2025
0d8bcdd
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 5, 2025
278556c
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 6, 2025
5689c1f
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 7, 2025
299cec6
Update tests
XuehaiPan Apr 7, 2025
21d2e73
Split 't' flag to another test
XuehaiPan Apr 7, 2025
d265a59
Update tests
XuehaiPan Apr 8, 2025
f3b8570
Update tests
XuehaiPan Apr 8, 2025
fe4ea95
Update tests
XuehaiPan Apr 8, 2025
da2b4ce
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 8, 2025
64f0961
Simplify tests
XuehaiPan Apr 8, 2025
8b16454
Simplify tests
XuehaiPan Apr 8, 2025
1c807f0
Update test comments
XuehaiPan Apr 8, 2025
fbb86f5
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 8, 2025
b702ff9
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 9, 2025
932386c
Simplify test comment
XuehaiPan Apr 9, 2025
23b6e6c
Apply suggestions from code review
XuehaiPan Apr 9, 2025
75b6c51
Make 'd' flag test more platform specific
XuehaiPan Apr 11, 2025
3c91201
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 11, 2025
d55b3e6
Revert non-Windows test changes
XuehaiPan Apr 11, 2025
a084070
Fix Windows platform detection
XuehaiPan Apr 11, 2025
d2255e6
Merge branch 'main' into windows-add-sysconfig-abiflags
XuehaiPan Apr 11, 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
Prev Previous commit
Next Next commit
Prefer Py_DEBUG over _DEBUG
  • Loading branch information
XuehaiPan committed Mar 28, 2025
commit 93257bec96a9c07945d4d05a1ea8535d87bc97a2
2 changes: 1 addition & 1 deletion Include/internal/pycore_importdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ extern int _PyImport_RunModInitFunc(
#include <windows.h>
typedef FARPROC dl_funcptr;

#ifdef _DEBUG
#ifdef Py_DEBUG
Comment thread
XuehaiPan marked this conversation as resolved.
Outdated
# define PYD_DEBUG_SUFFIX "_d"
#else
# define PYD_DEBUG_SUFFIX ""
Expand Down
7 changes: 0 additions & 7 deletions Modules/_sysconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,7 @@ _sysconfig_config_vars_impl(PyObject *module)
"t"
# endif
# ifdef Py_DEBUG
# ifndef _DEBUG
# error "_DEBUG not defined while Py_DEBUG is defined on Windows"
# endif
"d"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think making this _d is more useful. Provided we keep the t before it, it means a free-threaded debug build has ABIFLAGS of t_d, which means python{version}{ABIFLAGS}.exe will correctly generate python3.13t_d.exe. Without the underscore, you can't use ABIFLAGS anywhere, so it's pretty pointless.

@XuehaiPan XuehaiPan Mar 31, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Without the underscore, you can't use ABIFLAGS anywhere, so it's pretty pointless.

Can't we use something like this?

def add_underscore_d(x):
    if os.name == 'nt':
        return x.replace('d', '_d')
    return x

executable = f'python{version}{add_underscore_d(ABIFLAGS)}.exe'

Explicit is better than implicit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It isn't "we" - it's "every single user ever for the rest of time". Our job as core maintainers is to do more work and make less obvious decisions so that every single user doesn't have to.

Don't bother quoting the zen at me either. "Special cases aren't special enough" applies just as well here, as does "one obvious way" (which is to use sysconfig variables to construct system configuration values).

If you want to run with the "explicit > implicit" argument, here's a more explicit version:

executable = f"python{version}{'t' if 'freethreaded' in sys.abi_features else ''}{'_d' if 'debug' in sys.abi_features else ''}.exe"

Inserting an underscore is neither explicit, nor obvious, and is definitely a special case that isn't special enough to not just use a sysconfig variable directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I added the underscore prefix in the Python code so that developers can introspect the source more easily.

@XuehaiPan XuehaiPan Mar 31, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

A constraint of the _ prefix is the d flag should always be the last flag (test added). And users cannot use ABIFLAGS.split() to get the components because _ is not a valid flag.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

users cannot use ABIFLAGS.split() to get the components because _ is not a valid flag.

Users can't split up the value anyway, that's not what it's for. You can parse it specifically, which basically amounts to an in test for a single character (and will be replaced by sys.abi_features), or insert it into certain places without modification.

@FFY00 FFY00 Apr 3, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I still don't understand why this definition needs to be in the native module, instead of generating it in the Python code.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ideally, as you say, all these variables should be defined in pyconfig.h. Let's call that tier 1.1

On Windows, we don't parse pyconfig.h to fill out sysconfig, so instead we set the variables we want in _sysconfig. So that's tier 2, and is closer to the ideal (tier 1). If we had an actual build-time ABIFLAGS then we'd have to put it in _sysconfig. And I'm not opposed to constructing an AbiFlags property in python.props and passing that through to _sysconfig at build-time, but it'd only change the current implementation by a couple of lines.

If not set in _sysconfig, then we are constructing an arbitrary variable purely for cross-platform compatibility reasons, and so we can do that in sysconfig (tier 3), but so can anyone who needs it. By definition, if we can construct it in Python code, then so can they, and if they do it then they can backport further than we can (basically the same as the argument for removing distutils). It's more flexible for libraries that need it to figure it out themselves from first principles, and in reality, I don't think most bother, because it's just not that important a variable.

So basically, tier 2 is closer to ideal than tier 3 would be, and importantly it makes it clearer that this is exposing an internally defined value, rather than trying to adhere to some kind of definition of what ABIFLAGS is meant to be (which doesn't exist). A combination of expressing our intent more clearly along with being in a better position to do it properly one day.

Footnotes

  1. They aren't because we don't/shouldn't generate pyconfig.h on Windows, and we don't rely on the prefix or include directory being duplicated for every ABI group. And we aren't smuggling in a change to that here, it's a 2-3 release deprecation first, which means a PEP describing the transition, and I don't think it's necessary.

# else
# ifdef _DEBUG
# error "_DEBUG defined while Py_DEBUG is not defined on Windows"
# endif
# endif
"")
< 0) {
Expand Down
2 changes: 1 addition & 1 deletion PC/launcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ static wchar_t * get_env(wchar_t * key)
return buf;
}

#if defined(_DEBUG)
#if defined(Py_DEBUG)
/* Do not define EXECUTABLEPATH_VALUE in debug builds as it'll
never point to the debug build. */
#if defined(_WINDOWS)
Expand Down
17 changes: 9 additions & 8 deletions PC/pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@ typedef int pid_t;
# include <stdio.h>
#endif

// _DEBUG implies Py_DEBUG
#ifdef _DEBUG
# define Py_DEBUG
#endif

/* 64 bit ints are usually spelt __int64 unless compiler has overridden */
#ifndef PY_LONG_LONG
# define PY_LONG_LONG __int64
Expand Down Expand Up @@ -319,21 +324,21 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
This is relevant when using build-system generator (e.g CMake) where
the linking is explicitly handled */
# if defined(Py_GIL_DISABLED)
# if defined(_DEBUG)
# if defined(Py_DEBUG)
Comment thread
XuehaiPan marked this conversation as resolved.
Outdated
# pragma comment(lib,"python314t_d.lib")
# elif defined(Py_LIMITED_API)
# pragma comment(lib,"python3t.lib")
# else
# pragma comment(lib,"python314t.lib")
# endif /* _DEBUG */
# endif /* Py_DEBUG */
# else /* Py_GIL_DISABLED */
# if defined(_DEBUG)
# if defined(Py_DEBUG)
# pragma comment(lib,"python314_d.lib")
# elif defined(Py_LIMITED_API)
# pragma comment(lib,"python3.lib")
# else
# pragma comment(lib,"python314.lib")
# endif /* _DEBUG */
# endif /* Py_DEBUG */
# endif /* Py_GIL_DISABLED */
# endif /* _MSC_VER && !Py_NO_LINK_LIB */
# endif /* Py_BUILD_CORE */
Expand Down Expand Up @@ -376,10 +381,6 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
# define ALIGNOF_MAX_ALIGN_T 8
#endif

#ifdef _DEBUG
# define Py_DEBUG
#endif


#ifdef MS_WIN32

Expand Down
4 changes: 2 additions & 2 deletions PC/python_uwp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
#include <winrt\Windows.Storage.h>

#ifdef PYTHONW
#ifdef _DEBUG
#ifdef Py_DEBUG
const wchar_t *PROGNAME = L"pythonw_d.exe";
#else
const wchar_t *PROGNAME = L"pythonw.exe";
#endif
#else
#ifdef _DEBUG
#ifdef Py_DEBUG
const wchar_t *PROGNAME = L"python_d.exe";
#else
const wchar_t *PROGNAME = L"python.exe";
Expand Down
2 changes: 1 addition & 1 deletion PC/python_ver_rc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#define MS_WINDOWS
#include "modsupport.h"
#include "patchlevel.h"
#ifdef _DEBUG
#ifdef Py_DEBUG
# define PYTHON_DEBUG_EXT "_d"
#else
# define PYTHON_DEBUG_EXT
Expand Down
2 changes: 1 addition & 1 deletion PCbuild/pyproject.props
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

<PropertyGroup>
<_DebugPreprocessorDefinition>NDEBUG;</_DebugPreprocessorDefinition>
<_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG;</_DebugPreprocessorDefinition>
<_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG;Py_DEBUG;</_DebugPreprocessorDefinition>
Comment thread
XuehaiPan marked this conversation as resolved.
Outdated
<_PyStatsPreprocessorDefinition>PyStats;</_PyStatsPreprocessorDefinition>
<_PyStatsPreprocessorDefinition Condition="$(PySTATS) != ''">Py_STATS;</_PyStatsPreprocessorDefinition>
<_PlatformPreprocessorDefinition>_WIN32;</_PlatformPreprocessorDefinition>
Expand Down
6 changes: 3 additions & 3 deletions Python/dynload_win.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ static char *GetPythonImport (HINSTANCE hModule)
char *pch;

/* Don't claim that python3.dll is a Python DLL. */
#ifdef _DEBUG
#ifdef Py_DEBUG
if (strcmp(import_name, "python3_d.dll") == 0) {
#else
if (strcmp(import_name, "python3.dll") == 0) {
Expand All @@ -120,7 +120,7 @@ static char *GetPythonImport (HINSTANCE hModule)
/* Ensure python prefix is followed only
by numbers to the end of the basename */
pch = import_name + 6;
#ifdef _DEBUG
#ifdef Py_DEBUG
while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
#else
while (*pch && *pch != '.') {
Expand Down Expand Up @@ -300,7 +300,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
char buffer[256];

PyOS_snprintf(buffer, sizeof(buffer),
#ifdef _DEBUG
#ifdef Py_DEBUG
"python%d%d_d.dll",
#else
"python%d%d.dll",
Expand Down