On Windows when you run debug version of Python (python_d.exe) it only accepts extensions that were linked against python311_d.dll and also it requires them to have _d suffix.
For example:
# Let's say we've compiled '_example.pyd`.
# Then this will work fine in usual Python, 
# but in `python_d` it will result in "_example module is not found".
# If we've compiled `_example_d.pyd`
# then it will work fine in `python_d`, but won't work in usual Python.
import _example
The question is, how to ensure cmake will add _d suffix on Debug build automatically?
DEBUG_POSTFIX comes to mind, but it has a caveat.
cmake_minimum_required(VERSION 3.10)
project(HelloInstall)
find_package(SWIG REQUIRED)
include(UseSWIG)
find_package(Python REQUIRED COMPONENTS Interpreter Development)
set_source_files_properties(example.i PROPERTIES CPLUSPLUS ON)
swig_add_library(
    example
    TYPE MODULE
    LANGUAGE python
    SOURCES example.i example.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
swig_link_libraries(example PRIVATE Python::Python)
set_target_properties(
    ${SWIG_MODULE_example_REAL_NAME} PROPERTIES
    DEBUG_POSTFIX "_d"
)
The caveat is in example.py, the wrapper file that’s used to import underlying _example_d.pyd extension. Because cmake passed target name as -interface <target_name> to swig, example.py is now using import _example_d, which is incorrect and will always fail - it suppose to be import _example, even though underlying extension is indeed has _d suffix.
if __package__ or "." in __name__:
    from . import _example_d
else:
    import _example_d
From UseCmake.cmake code it seems the only way to avoid this is to override -interface yourself. So the workaround is to add set(SWIG_MODULE_example_EXTRA_FLAGS "-interface" "_example") before swig_add_library.
Is there some best practice for this case?
Could it also be considered a bug in cmake? In theory it should drop possible _d suffix when adding target_name in -interface in Debug config on Windows.
Also, maybe it would make sense for swig_add_library to set _d as DEBUG_POSTFIX  on Windows as default in this case?