Repository: pypa/setuptools (python)

Issue:
[BUG] Wheel ABI tag is wrong when building with debug build of Python 3.13 on Windows
### setuptools version

75.1.0

### Python version

Python 3.13.0

### OS

Windows

### Additional environment information

_No response_

### Description

If I execute `python_d.exe setup.py bdist_wheel` using the debug build of Python 3.13 on Windows, then the wheel that is produced has a name that looks like `simpleext-0.0.1-cp313-cp313-win_amd64.whl`. The ABI tag is set to `cp313` instead of the expected value of `cp313d`. If I execute the same command using the debug build of Python 3.12, the ABI tag is correctly set to `cp312d`, producing a wheel filename like `simpleext-0.0.1-cp312-cp312d-win_amd64.whl`.

The cause of this problem is that Python 3.13 on Windows now sets a value for the `SOABI` configuration variable, while previous Python versions did not. Debug and release builds of Python 3.13 on Windows have the same `SOABI` value, and the following line does not take this into account.
https://github.com/pypa/setuptools/blob/66a8aee91de7ed8b0f819fb836e5543212e4b860/setuptools/command/bdist_wheel.py#L128

I propose that we modify this section to
```Python
    elif soabi and impl == "cp" and soabi.startswith("cp"):
        # Windows
        abi = soabi.split("-")[0]
        if hasattr(sys, "gettotalrefcount"):
            # using debug build; append "d" flag
            abi += "d"
```

### Expected behavior

The ABI tag is set to `cp313d`, producing a wheel filename like `simpleext-0.0.1-cp313-cp313d-win_amd64.whl`.

### How to Reproduce

Install 64-bit Python 3.13.0 on Windows with the "Download debug binaries" option enabled. Create a file `setup.py` with the following contents.

```Python
from setuptools import setup, Extension
import os

setup(
    name='simpleext',
    version='0.0.1',
    description='Simple extension module',
    zip_safe=False,
    ext_modules=[Extension(
        'simpleext', ['simpleext.c'],
    )]
)
```

In the same directory, create a file `simpleext.c` with the following contents.

```C
#define PY_SSIZE_T_CLEAN
#include <Python.h>

static PyObject *simpleext_donothing(PyObject *self, PyObject *args)
{
   Py_RETURN_NONE;
}

static PyMethodDef SimpleExtMethods[] = {
    {"donothing", simpleext_donothing, METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef simpleextmodule = {
    PyModuleDef_HEAD_INIT,
    "simpleext",
    NULL,
    -1,
    SimpleExtMethods
};

PyMODINIT_FUNC PyInit_simpleext(void)
{
    return PyModule_Create(&simpleextmodule);
}
```

Execute `python_d.exe setup.py bdist_wheel`. Note that the wheel file that is created is named `simpleext-0.0.1-cp313-cp313-win_amd64.whl`.

### Output

```console
running bdist_wheel
running build
running build_ext
building 'simpleext' extension
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD "-IC:\Program Files\Python313\include" "-IC:\Program Files\Python313\Include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\ATLMFC\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" /TcC:\Users\adang\Desktop\simpleext\simpleext.c /Fo\Users\adang\Desktop\simpleext\simpleext.obj
simpleext.c
creating C:\Users\adang\Desktop\simpleext\build\lib.win-amd64-cpython-313-pydebug
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\bin\HostX86\x64\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO "/LIBPATH:C:\Program Files\Python313\libs" "/LIBPATH:C:\Program Files\Python313" "/LIBPATH:C:\Program Files\Python313\PCbuild\amd64" "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.22621.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64" /EXPORT:PyInit_simpleext \Users\adang\Desktop\simpleext\simpleext.obj /OUT:build\lib.win-amd64-cpython-313-pydebug\simpleext_d.cp313-win_amd64.pyd /IMPLIB:\Users\adang\Desktop\simpleext\simpleext_d.cp313-win_amd64.lib
   Creating library \Users\adang\Desktop\simpleext\simpleext_d.cp313-win_amd64.lib and object \Users\adang\Desktop\simpleext\simpleext_d.cp313-win_amd64.exp
Generating code
Finished generating code
C:\Program Files\Python313\Lib\site-packages\setuptools\_distutils\cmd.py:66: SetuptoolsDeprecationWarning: setup.py install is deprecated.
!!

        ********************************************************************************
        Please avoid running ``setup.py`` directly.
        Instead, use pypa/build, pypa/installer or other
        standards-based tools.

        See https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html for details.
        ********************************************************************************

!!
  self.initialize_options()
installing to build\bdist.win-amd64\wheel
running install
running install_lib
creating build\bdist.win-amd64\wheel
copying build\lib.win-amd64-cpython-313-pydebug\simpleext_d.cp313-win_amd64.pyd -> build\bdist.win-amd64\wheel\.
running install_egg_info
running egg_info
creating simpleext.egg-info
writing simpleext.egg-info\PKG-INFO
writing dependency_links to simpleext.egg-info\dependency_links.txt
writing top-level names to simpleext.egg-info\top_level.txt
writing manifest file 'simpleext.egg-info\SOURCES.txt'
reading manifest file 'simpleext.egg-info\SOURCES.txt'
writing manifest file 'simpleext.egg-info\SOURCES.txt'
Copying simpleext.egg-info to build\bdist.win-amd64\wheel\.\simpleext-0.0.1-py3.13.egg-info
running install_scripts
creating build\bdist.win-amd64\wheel\simpleext-0.0.1.dist-info\WHEEL
creating 'dist\simpleext-0.0.1-cp313-cp313-win_amd64.whl' and adding 'build\bdist.win-amd64\wheel' to it
adding 'simpleext_d.cp313-win_amd64.pyd'
adding 'simpleext-0.0.1.dist-info/METADATA'
adding 'simpleext-0.0.1.dist-info/WHEEL'
adding 'simpleext-0.0.1.dist-info/top_level.txt'
adding 'simpleext-0.0.1.dist-info/RECORD'
removing build\bdist.win-amd64\wheel
```


Pull request:
Fix wheel ABI tag for debug Python 3.13 on Windows
<!-- First time contributors: Take a moment to review https://setuptools.pypa.io/en/latest/development/developer-guide.html! -->
<!-- Remove sections if not applicable -->

## Summary of changes

When creating a wheel using the debug version of Python 3.13 on Windows, ensure that the `"d"` flag is in the ABI tag.

Closes #4674

### Pull Request Checklist
- [x] Changes have tests
- [x] News fragment added in [`newsfragments/`].
  _(See [documentation][PR docs] for details)_


[`newsfragments/`]: https://github.com/pypa/setuptools/tree/master/newsfragments
[PR docs]:
https://setuptools.pypa.io/en/latest/development/developer-guide.html#making-a-pull-request


Patch:
diff --git a/newsfragments/4674.bugfix.rst b/newsfragments/4674.bugfix.rst
new file mode 100644
index 000000000..9a6d2454a
--- /dev/null
+++ b/newsfragments/4674.bugfix.rst
@@ -0,0 +1,1 @@
+Fix the ABI tag when building a wheel using the debug build of Python 3.13 on Windows. Previously, the ABI tag was missing the ``"d"`` flag.
diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py
index f377cd5ee..3b64d6270 100644
--- a/setuptools/command/bdist_wheel.py
+++ b/setuptools/command/bdist_wheel.py
@@ -129,6 +129,9 @@ def get_abi_tag() -> str | None:
     elif soabi and impl == "cp" and soabi.startswith("cp"):
         # Windows
         abi = soabi.split("-")[0]
+        if hasattr(sys, "gettotalrefcount"):
+            # using debug build; append "d" flag
+            abi += "d"
     elif soabi and impl == "pp":
         # we want something like pypy36-pp73
         abi = "-".join(soabi.split("-")[:2])


Test patch:
diff --git a/setuptools/tests/test_bdist_wheel.py b/setuptools/tests/test_bdist_wheel.py
index 47200d0a2..141ef716a 100644
--- a/setuptools/tests/test_bdist_wheel.py
+++ b/setuptools/tests/test_bdist_wheel.py
@@ -470,6 +470,12 @@ def test_get_abi_tag_windows(monkeypatch):
     monkeypatch.setattr(tags, "interpreter_name", lambda: "cp")
     monkeypatch.setattr(sysconfig, "get_config_var", lambda x: "cp313-win_amd64")
     assert get_abi_tag() == "cp313"
+    monkeypatch.setattr(sys, "gettotalrefcount", lambda: 1, False)
+    assert get_abi_tag() == "cp313d"
+    monkeypatch.setattr(sysconfig, "get_config_var", lambda x: "cp313t-win_amd64")
+    assert get_abi_tag() == "cp313td"
+    monkeypatch.delattr(sys, "gettotalrefcount")
+    assert get_abi_tag() == "cp313t"
 
 
 def test_get_abi_tag_pypy_old(monkeypatch):