1From fda6ecc6446980906f83b53e4c8add6d6023a5ba Mon Sep 17 00:00:00 2001 2From: luming <luming29@huawei.com> 3Date: Fri, 9 May 2025 08:45:54 +0800 4Subject: [PATCH] cpython 3.11.4 for mingw 5 6Change-Id: I7ae3759608e3fc26eb2ebef1fb200e46b3add264 7--- 8 .github/workflows/build.yml | 418 +++++++++++ 9 .gitignore | 5 +- 10 Include/bytesobject.h | 4 +- 11 Include/fileobject.h | 2 +- 12 Include/internal/pycore_condvar.h | 10 + 13 Include/iscygpty.h | 41 + 14 Include/osdefs.h | 1 - 15 Include/py_curses.h | 7 + 16 Include/pyerrors.h | 4 +- 17 Include/pylifecycle.h | 9 + 18 Include/pyport.h | 41 +- 19 Include/pythread.h | 6 + 20 Include/sysmodule.h | 4 +- 21 Lib/compileall.py | 2 + 22 Lib/ctypes/__init__.py | 4 +- 23 Lib/ctypes/util.py | 9 + 24 Lib/distutils/ccompiler.py | 4 +- 25 Lib/distutils/command/build_ext.py | 27 +- 26 Lib/distutils/command/install.py | 10 +- 27 Lib/distutils/cygwinccompiler.py | 188 ++--- 28 Lib/distutils/msvc9compiler.py | 4 +- 29 Lib/distutils/sysconfig.py | 39 +- 30 Lib/distutils/tests/test_cygwinccompiler.py | 36 +- 31 Lib/distutils/unixccompiler.py | 8 +- 32 Lib/distutils/util.py | 42 +- 33 Lib/importlib/_bootstrap_external.py | 4 + 34 Lib/ntpath.py | 108 +-- 35 Lib/pathlib.py | 2 + 36 Lib/site.py | 38 +- 37 Lib/ssl.py | 4 +- 38 Lib/sysconfig.py | 107 ++- 39 Lib/test/__main__.py | 8 + 40 Lib/test/test_bytes.py | 2 +- 41 Lib/test/test_getpath.py | 9 + 42 Lib/test/test_httpservers.py | 4 +- 43 Lib/test/test_importlib/test_windows.py | 17 + 44 Lib/test/test_sysconfig.py | 8 +- 45 Lib/venv/__init__.py | 9 +- 46 Makefile.pre.in | 88 ++- 47 Misc/NEWS.d/3.11.4.rst | 785 ++++++++++++++++++++ 48 Misc/config_mingw | 15 + 49 Misc/cross_mingw32 | 11 + 50 Misc/python-config.sh.in | 62 +- 51 Misc/python.pc.in | 2 +- 52 Modules/Setup.bootstrap.in | 11 +- 53 Modules/_ctypes/_ctypes.c | 19 + 54 Modules/_gdbmmodule.c | 2 +- 55 Modules/_io/fileio.c | 3 +- 56 Modules/_localemodule.c | 7 + 57 Modules/_multiprocessing/multiprocessing.c | 2 +- 58 Modules/_multiprocessing/multiprocessing.h | 5 +- 59 Modules/_winapi.c | 4 +- 60 Modules/_xxsubinterpretersmodule.c | 2 +- 61 Modules/getpath.c | 40 + 62 Modules/getpath.py | 81 +- 63 Modules/main.c | 3 +- 64 Modules/posixmodule.c | 45 +- 65 Modules/selectmodule.c | 6 +- 66 Modules/socketmodule.c | 8 +- 67 Modules/socketmodule.h | 2 + 68 Modules/timemodule.c | 2 +- 69 Objects/fileobject.c | 3 +- 70 PC/_testconsole.c | 4 +- 71 PC/launcher.c | 33 +- 72 PC/msvcrtmodule.c | 2 + 73 PC/pylauncher.rc | 20 +- 74 PC/python3dll.c | 8 + 75 PC/python_exe.rc | 2 +- 76 PC/pythonw_exe.rc | 2 +- 77 PC/winreg.c | 20 + 78 Python/bltinmodule.c | 5 +- 79 Python/dynamic_annotations.c | 2 +- 80 Python/dynload_win.c | 24 +- 81 Python/fileutils.c | 70 +- 82 Python/frozenmain.c | 3 +- 83 Python/getcompiler.c | 34 +- 84 Python/initconfig.c | 2 +- 85 Python/iscygpty.c | 185 +++++ 86 Python/pathconfig.c | 157 +++- 87 Python/pylifecycle.c | 5 +- 88 Python/sysmodule.c | 4 +- 89 Python/thread_nt.h | 3 +- 90 Python/traceback.c | 2 +- 91 configure.ac | 545 +++++++++++++- 92 mingw_ignorefile.txt | 42 ++ 93 mingw_smoketests.py | 358 +++++++++ 94 pyconfig.h.in | 7 +- 95 setup.py | 112 ++- 96 88 files changed, 3606 insertions(+), 498 deletions(-) 97 create mode 100644 .github/workflows/build.yml 98 create mode 100644 Include/iscygpty.h 99 create mode 100644 Misc/NEWS.d/3.11.4.rst 100 create mode 100644 Misc/config_mingw 101 create mode 100644 Misc/cross_mingw32 102 create mode 100644 Python/iscygpty.c 103 create mode 100644 mingw_ignorefile.txt 104 create mode 100644 mingw_smoketests.py 105 106diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml 107new file mode 100644 108index 0000000..c2293cb 109--- /dev/null 110+++ b/.github/workflows/build.yml 111@@ -0,0 +1,418 @@ 112+name: Tests 113+ 114+# gh-84728: "paths-ignore" is not used to skip documentation-only PRs, because 115+# it prevents to mark a job as mandatory. A PR cannot be merged if a job is 116+# mandatory but not scheduled because of "paths-ignore". 117+on: 118+ workflow_dispatch: 119+ push: 120+ branches: 121+ - 'main' 122+ - '3.11' 123+ - '3.10' 124+ - '3.9' 125+ - '3.8' 126+ - '3.7' 127+ pull_request: 128+ branches: 129+ - 'main' 130+ - '3.11' 131+ - '3.10' 132+ - '3.9' 133+ - '3.8' 134+ - '3.7' 135+ 136+permissions: 137+ contents: read 138+ 139+concurrency: 140+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 141+ cancel-in-progress: true 142+ 143+jobs: 144+ check_source: 145+ name: 'Check for source changes' 146+ runs-on: ubuntu-latest 147+ timeout-minutes: 10 148+ outputs: 149+ run_tests: ${{ steps.check.outputs.run_tests }} 150+ run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }} 151+ config_hash: ${{ steps.config_hash.outputs.hash }} 152+ steps: 153+ - uses: actions/checkout@v3 154+ - name: Check for source changes 155+ id: check 156+ run: | 157+ if [ -z "$GITHUB_BASE_REF" ]; then 158+ echo "run_tests=true" >> $GITHUB_OUTPUT 159+ echo "run_ssl_tests=true" >> $GITHUB_OUTPUT 160+ else 161+ git fetch origin $GITHUB_BASE_REF --depth=1 162+ # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more 163+ # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots), 164+ # but it requires to download more commits (this job uses 165+ # "git fetch --depth=1"). 166+ # 167+ # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git 168+ # 2.26, but Git 2.28 is stricter and fails with "no merge base". 169+ # 170+ # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on 171+ # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF 172+ # into the PR branch anyway. 173+ # 174+ # https://github.com/python/core-workflow/issues/373 175+ git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true 176+ git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo "run_ssl_tests=true" >> $GITHUB_OUTPUT || true 177+ fi 178+ - name: Compute hash for config cache key 179+ id: config_hash 180+ run: | 181+ echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT 182+ 183+ check_abi: 184+ name: 'Check if the ABI has changed' 185+ runs-on: ubuntu-20.04 186+ needs: check_source 187+ if: needs.check_source.outputs.run_tests == 'true' 188+ steps: 189+ - uses: actions/checkout@v2 190+ - uses: actions/setup-python@v2 191+ - name: Install Dependencies 192+ run: | 193+ sudo ./.github/workflows/posix-deps-apt.sh 194+ sudo apt-get install -yq abigail-tools 195+ - name: Build CPython 196+ env: 197+ CFLAGS: -g3 -O0 198+ run: | 199+ # Build Python with the libpython dynamic library 200+ ./configure --enable-shared 201+ make -j4 202+ - name: Check for changes in the ABI 203+ id: check 204+ run: | 205+ if ! make check-abidump; then 206+ echo "Generated ABI file is not up to date." 207+ echo "Please, add the release manager of this branch as a reviewer of this PR." 208+ echo "" 209+ echo "The up to date ABI file should be attached to this build as an artifact." 210+ echo "" 211+ echo "To learn more about this check: https://devguide.python.org/setup/#regenerate-the-abi-dump" 212+ echo "" 213+ exit 1 214+ fi 215+ - name: Generate updated ABI files 216+ if: ${{ failure() && steps.check.conclusion == 'failure' }} 217+ run: | 218+ make regen-abidump 219+ - uses: actions/upload-artifact@v3 220+ name: Publish updated ABI files 221+ if: ${{ failure() && steps.check.conclusion == 'failure' }} 222+ with: 223+ name: abi-data 224+ path: ./Doc/data/*.abi 225+ 226+ check_generated_files: 227+ name: 'Check if generated files are up to date' 228+ runs-on: ubuntu-latest 229+ timeout-minutes: 60 230+ needs: check_source 231+ if: needs.check_source.outputs.run_tests == 'true' 232+ steps: 233+ - uses: actions/checkout@v3 234+ - name: Restore config.cache 235+ uses: actions/cache@v3 236+ with: 237+ path: config.cache 238+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} 239+ - uses: actions/setup-python@v3 240+ - name: Install Dependencies 241+ run: sudo ./.github/workflows/posix-deps-apt.sh 242+ - name: Add ccache to PATH 243+ run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV 244+ - name: Configure ccache action 245+ uses: hendrikmuhs/ccache-action@v1.2 246+ - name: Check Autoconf version 2.69 and aclocal 1.16.3 247+ run: | 248+ grep "Generated by GNU Autoconf 2.69" configure 249+ grep "aclocal 1.16.3" aclocal.m4 250+ grep -q "runstatedir" configure 251+ grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 252+ - name: Configure CPython 253+ run: | 254+ # Build Python with the libpython dynamic library 255+ ./configure --config-cache --with-pydebug --enable-shared 256+ - name: Regenerate autoconf files with container image 257+ run: make regen-configure 258+ - name: Build CPython 259+ run: | 260+ # Deepfreeze will usually cause global objects to be added or removed, 261+ # so we run it before regen-global-objects gets rum (in regen-all). 262+ make regen-deepfreeze 263+ make -j4 regen-all 264+ make regen-stdlib-module-names 265+ - name: Check for changes 266+ run: | 267+ git add -u 268+ changes=$(git status --porcelain) 269+ # Check for changes in regenerated files 270+ if test -n "$changes"; then 271+ echo "Generated files not up to date." 272+ echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)" 273+ echo "configure files must be regenerated with a specific version of autoconf." 274+ echo "$changes" 275+ echo "" 276+ git diff --staged || true 277+ exit 1 278+ fi 279+ - name: Check exported libpython symbols 280+ run: make smelly 281+ - name: Check limited ABI symbols 282+ run: make check-limited-abi 283+ 284+ build_win32: 285+ name: 'Windows (x86)' 286+ runs-on: windows-latest 287+ timeout-minutes: 60 288+ needs: check_source 289+ if: needs.check_source.outputs.run_tests == 'true' 290+ env: 291+ IncludeUwp: 'true' 292+ steps: 293+ - uses: actions/checkout@v3 294+ - name: Build CPython 295+ run: .\PCbuild\build.bat -e -d -p Win32 296+ - name: Display build info 297+ run: .\python.bat -m test.pythoninfo 298+ - name: Tests 299+ run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 300+ 301+ build_win_amd64: 302+ name: 'Windows (x64)' 303+ runs-on: windows-latest 304+ timeout-minutes: 60 305+ needs: check_source 306+ if: needs.check_source.outputs.run_tests == 'true' 307+ env: 308+ IncludeUwp: 'true' 309+ steps: 310+ - uses: actions/checkout@v3 311+ - name: Register MSVC problem matcher 312+ run: echo "::add-matcher::.github/problem-matchers/msvc.json" 313+ - name: Build CPython 314+ run: .\PCbuild\build.bat -e -d -p x64 315+ - name: Display build info 316+ run: .\python.bat -m test.pythoninfo 317+ - name: Tests 318+ run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 319+ 320+ build_macos: 321+ name: 'macOS' 322+ runs-on: macos-latest 323+ timeout-minutes: 60 324+ needs: check_source 325+ if: needs.check_source.outputs.run_tests == 'true' 326+ env: 327+ HOMEBREW_NO_ANALYTICS: 1 328+ HOMEBREW_NO_AUTO_UPDATE: 1 329+ HOMEBREW_NO_INSTALL_CLEANUP: 1 330+ PYTHONSTRICTEXTENSIONBUILD: 1 331+ steps: 332+ - uses: actions/checkout@v3 333+ - name: Restore config.cache 334+ uses: actions/cache@v3 335+ with: 336+ path: config.cache 337+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} 338+ - name: Install Homebrew dependencies 339+ run: brew install pkg-config openssl@1.1 xz gdbm tcl-tk 340+ - name: Configure CPython 341+ run: | 342+ CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ 343+ LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \ 344+ PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \ 345+ ./configure \ 346+ --config-cache \ 347+ --with-pydebug \ 348+ --prefix=/opt/python-dev \ 349+ --with-openssl="$(brew --prefix openssl@1.1)" 350+ - name: Build CPython 351+ run: make -j4 352+ - name: Display build info 353+ run: make pythoninfo 354+ - name: Tests 355+ run: make buildbottest TESTOPTS="-j4 -uall,-cpu" 356+ 357+ build_ubuntu: 358+ name: 'Ubuntu' 359+ runs-on: ubuntu-20.04 360+ timeout-minutes: 60 361+ needs: check_source 362+ if: needs.check_source.outputs.run_tests == 'true' 363+ env: 364+ OPENSSL_VER: 1.1.1u 365+ PYTHONSTRICTEXTENSIONBUILD: 1 366+ steps: 367+ - uses: actions/checkout@v3 368+ - name: Register gcc problem matcher 369+ run: echo "::add-matcher::.github/problem-matchers/gcc.json" 370+ - name: Install Dependencies 371+ run: sudo ./.github/workflows/posix-deps-apt.sh 372+ - name: Configure OpenSSL env vars 373+ run: | 374+ echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV 375+ echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV 376+ echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV 377+ - name: 'Restore OpenSSL build' 378+ id: cache-openssl 379+ uses: actions/cache@v3 380+ with: 381+ path: ./multissl/openssl/${{ env.OPENSSL_VER }} 382+ key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} 383+ - name: Install OpenSSL 384+ if: steps.cache-openssl.outputs.cache-hit != 'true' 385+ run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux 386+ - name: Add ccache to PATH 387+ run: | 388+ echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV 389+ - name: Configure ccache action 390+ uses: hendrikmuhs/ccache-action@v1.2 391+ - name: Setup directory envs for out-of-tree builds 392+ run: | 393+ echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV 394+ echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV 395+ - name: Create directories for read-only out-of-tree builds 396+ run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR 397+ - name: Bind mount sources read-only 398+ run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR 399+ - name: Restore config.cache 400+ uses: actions/cache@v3 401+ with: 402+ path: ${{ env.CPYTHON_BUILDDIR }}/config.cache 403+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} 404+ - name: Configure CPython out-of-tree 405+ working-directory: ${{ env.CPYTHON_BUILDDIR }} 406+ run: | 407+ ../cpython-ro-srcdir/configure \ 408+ --config-cache \ 409+ --with-pydebug \ 410+ --with-openssl=$OPENSSL_DIR 411+ - name: Build CPython out-of-tree 412+ working-directory: ${{ env.CPYTHON_BUILDDIR }} 413+ run: make -j4 414+ - name: Display build info 415+ working-directory: ${{ env.CPYTHON_BUILDDIR }} 416+ run: make pythoninfo 417+ - name: Remount sources writable for tests 418+ # some tests write to srcdir, lack of pyc files slows down testing 419+ run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw 420+ - name: Tests 421+ working-directory: ${{ env.CPYTHON_BUILDDIR }} 422+ run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" 423+ 424+ build_ubuntu_ssltests: 425+ name: 'Ubuntu SSL tests with OpenSSL' 426+ runs-on: ubuntu-20.04 427+ timeout-minutes: 60 428+ needs: check_source 429+ if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_ssl_tests == 'true' 430+ strategy: 431+ fail-fast: false 432+ matrix: 433+ openssl_ver: [1.1.1u, 3.0.9, 3.1.1] 434+ env: 435+ OPENSSL_VER: ${{ matrix.openssl_ver }} 436+ MULTISSL_DIR: ${{ github.workspace }}/multissl 437+ OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }} 438+ LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib 439+ steps: 440+ - uses: actions/checkout@v3 441+ - name: Restore config.cache 442+ uses: actions/cache@v3 443+ with: 444+ path: config.cache 445+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} 446+ - name: Register gcc problem matcher 447+ run: echo "::add-matcher::.github/problem-matchers/gcc.json" 448+ - name: Install Dependencies 449+ run: sudo ./.github/workflows/posix-deps-apt.sh 450+ - name: Configure OpenSSL env vars 451+ run: | 452+ echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV 453+ echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV 454+ echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV 455+ - name: 'Restore OpenSSL build' 456+ id: cache-openssl 457+ uses: actions/cache@v3 458+ with: 459+ path: ./multissl/openssl/${{ env.OPENSSL_VER }} 460+ key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} 461+ - name: Install OpenSSL 462+ if: steps.cache-openssl.outputs.cache-hit != 'true' 463+ run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux 464+ - name: Add ccache to PATH 465+ run: | 466+ echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV 467+ - name: Configure ccache action 468+ uses: hendrikmuhs/ccache-action@v1.2 469+ - name: Configure CPython 470+ run: ./configure --config-cache --with-pydebug --with-openssl=$OPENSSL_DIR 471+ - name: Build CPython 472+ run: make -j4 473+ - name: Display build info 474+ run: make pythoninfo 475+ - name: SSL tests 476+ run: ./python Lib/test/ssltests.py 477+ 478+ build_asan: 479+ name: 'Address sanitizer' 480+ runs-on: ubuntu-20.04 481+ timeout-minutes: 60 482+ needs: check_source 483+ if: needs.check_source.outputs.run_tests == 'true' 484+ env: 485+ OPENSSL_VER: 1.1.1u 486+ PYTHONSTRICTEXTENSIONBUILD: 1 487+ ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 488+ steps: 489+ - uses: actions/checkout@v3 490+ - name: Restore config.cache 491+ uses: actions/cache@v3 492+ with: 493+ path: config.cache 494+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} 495+ - name: Register gcc problem matcher 496+ run: echo "::add-matcher::.github/problem-matchers/gcc.json" 497+ - name: Install Dependencies 498+ run: sudo ./.github/workflows/posix-deps-apt.sh 499+ - name: Set up GCC-10 for ASAN 500+ uses: egor-tensin/setup-gcc@v1 501+ with: 502+ version: 10 503+ - name: Configure OpenSSL env vars 504+ run: | 505+ echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV 506+ echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV 507+ echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV 508+ - name: 'Restore OpenSSL build' 509+ id: cache-openssl 510+ uses: actions/cache@v3 511+ with: 512+ path: ./multissl/openssl/${{ env.OPENSSL_VER }} 513+ key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} 514+ - name: Install OpenSSL 515+ if: steps.cache-openssl.outputs.cache-hit != 'true' 516+ run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux 517+ - name: Add ccache to PATH 518+ run: | 519+ echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV 520+ - name: Configure ccache action 521+ uses: hendrikmuhs/ccache-action@v1.2 522+ - name: Configure CPython 523+ run: ./configure --config-cache --with-address-sanitizer --without-pymalloc 524+ - name: Build CPython 525+ run: make -j4 526+ - name: Display build info 527+ run: make pythoninfo 528+ - name: Tests 529+ run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" 530diff --git a/.gitignore b/.gitignore 531index 0ddfd71..ea6e3a8 100644 532--- a/.gitignore 533+++ b/.gitignore 534@@ -114,6 +114,7 @@ PCbuild/win32/ 535 Tools/unicode/data/ 536 /autom4te.cache 537 /build/ 538+/builddir/ 539 /config.cache 540 /config.log 541 /config.status 542@@ -150,6 +151,4 @@ Python/frozen_modules/MANIFEST 543 # Ignore ./python binary on Unix but still look into ./Python/ directory. 544 /python 545 !/Python/ 546- 547-# main branch only: ABI files are not checked/maintained 548-Doc/data/python*.abi 549+.cid/* 550diff --git a/Include/bytesobject.h b/Include/bytesobject.h 551index 4c4dc40..cd88bed 100644 552--- a/Include/bytesobject.h 553+++ b/Include/bytesobject.h 554@@ -35,9 +35,9 @@ PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); 555 PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); 556 PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *); 557 PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list) 558- Py_GCC_ATTRIBUTE((format(printf, 1, 0))); 559+ Py_PRINTF(1, 0); 560 PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...) 561- Py_GCC_ATTRIBUTE((format(printf, 1, 2))); 562+ Py_PRINTF(1, 2); 563 PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *); 564 PyAPI_FUNC(char *) PyBytes_AsString(PyObject *); 565 PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int); 566diff --git a/Include/fileobject.h b/Include/fileobject.h 567index 4c983e7..260e4c1 100644 568--- a/Include/fileobject.h 569+++ b/Include/fileobject.h 570@@ -30,7 +30,7 @@ PyAPI_DATA(int) Py_UTF8Mode; 571 #endif 572 573 /* A routine to check if a file descriptor can be select()-ed. */ 574-#ifdef _MSC_VER 575+#ifdef MS_WINDOWS 576 /* On Windows, any socket fd can be select()-ed, no matter how high */ 577 #define _PyIsSelectable_fd(FD) (1) 578 #else 579diff --git a/Include/internal/pycore_condvar.h b/Include/internal/pycore_condvar.h 580index 981c962..ed9e6a7 100644 581--- a/Include/internal/pycore_condvar.h 582+++ b/Include/internal/pycore_condvar.h 583@@ -5,6 +5,12 @@ 584 # error "this header requires Py_BUILD_CORE define" 585 #endif 586 587+#ifdef __MINGW32__ 588+# if !defined(HAVE_PTHREAD_H) || defined(NT_THREADS) 589+# undef _POSIX_THREADS 590+# endif 591+#endif 592+ 593 #ifndef _POSIX_THREADS 594 /* This means pthreads are not implemented in libc headers, hence the macro 595 not present in unistd.h. But they still can be implemented as an external 596@@ -39,6 +45,10 @@ 597 /* include windows if it hasn't been done before */ 598 #define WIN32_LEAN_AND_MEAN 599 #include <windows.h> 600+/* winpthreads are involved via windows header, so need undef _POSIX_THREADS after header include */ 601+#if defined(_POSIX_THREADS) 602+#undef _POSIX_THREADS 603+#endif 604 605 /* options */ 606 /* non-emulated condition variables are provided for those that want 607diff --git a/Include/iscygpty.h b/Include/iscygpty.h 608new file mode 100644 609index 0000000..82fd0af 610--- /dev/null 611+++ b/Include/iscygpty.h 612@@ -0,0 +1,41 @@ 613+/* 614+ * iscygpty.h -- part of ptycheck 615+ * https://github.com/k-takata/ptycheck 616+ * 617+ * Copyright (c) 2015-2017 K.Takata 618+ * 619+ * You can redistribute it and/or modify it under the terms of either 620+ * the MIT license (as described below) or the Vim license. 621+ * 622+ * Permission is hereby granted, free of charge, to any person obtaining 623+ * a copy of this software and associated documentation files (the 624+ * "Software"), to deal in the Software without restriction, including 625+ * without limitation the rights to use, copy, modify, merge, publish, 626+ * distribute, sublicense, and/or sell copies of the Software, and to 627+ * permit persons to whom the Software is furnished to do so, subject to 628+ * the following conditions: 629+ * 630+ * The above copyright notice and this permission notice shall be 631+ * included in all copies or substantial portions of the Software. 632+ * 633+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 634+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 635+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 636+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 637+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 638+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 639+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 640+ */ 641+ 642+#ifndef _ISCYGPTY_H 643+#define _ISCYGPTY_H 644+ 645+#ifdef _WIN32 646+int is_cygpty(int fd); 647+int is_cygpty_used(void); 648+#else 649+#define is_cygpty(fd) 0 650+#define is_cygpty_used() 0 651+#endif 652+ 653+#endif /* _ISCYGPTY_H */ 654diff --git a/Include/osdefs.h b/Include/osdefs.h 655index 3243944..99d4977 100644 656--- a/Include/osdefs.h 657+++ b/Include/osdefs.h 658@@ -10,7 +10,6 @@ extern "C" { 659 #ifdef MS_WINDOWS 660 #define SEP L'\\' 661 #define ALTSEP L'/' 662-#define MAXPATHLEN 256 663 #define DELIM L';' 664 #endif 665 666diff --git a/Include/py_curses.h b/Include/py_curses.h 667index b2c7f1b..e6fc813 100644 668--- a/Include/py_curses.h 669+++ b/Include/py_curses.h 670@@ -36,6 +36,13 @@ 671 #include <curses.h> 672 #endif 673 674+#if defined(__MINGW32__) 675+#include <windows.h> 676+#if !defined(_ISPAD) 677+#define _ISPAD 0x10 678+#endif 679+#endif 680+ 681 #ifdef HAVE_NCURSES_H 682 /* configure was checking <curses.h>, but we will 683 use <ncurses.h>, which has some or all these features. */ 684diff --git a/Include/pyerrors.h b/Include/pyerrors.h 685index 34e3de3..fb71fde 100644 686--- a/Include/pyerrors.h 687+++ b/Include/pyerrors.h 688@@ -315,9 +315,9 @@ PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason( 689 ); 690 691 PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...) 692- Py_GCC_ATTRIBUTE((format(printf, 3, 4))); 693+ Py_PRINTF(3, 4); 694 PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) 695- Py_GCC_ATTRIBUTE((format(printf, 3, 0))); 696+ Py_PRINTF(3, 0); 697 698 #ifndef Py_LIMITED_API 699 # define Py_CPYTHON_ERRORS_H 700diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h 701index e4c3b09..21346ba 100644 702--- a/Include/pylifecycle.h 703+++ b/Include/pylifecycle.h 704@@ -21,6 +21,15 @@ PyAPI_FUNC(int) Py_IsInitialized(void); 705 PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); 706 PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); 707 708+PyAPI_FUNC(wchar_t) Py_GetAltSepW(const wchar_t *); 709+PyAPI_FUNC(wchar_t) Py_GetSepW(const wchar_t *); 710+PyAPI_FUNC(char) Py_GetSepA(const char *); 711+ 712+PyAPI_FUNC(void) Py_NormalizeSepsW(wchar_t *); 713+PyAPI_FUNC(void) Py_NormalizeSepsA(char *); 714+ 715+PyAPI_FUNC(void) Py_NormalizeSepsPathcchW(wchar_t *); 716+ 717 718 /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level 719 * exit functions. 720diff --git a/Include/pyport.h b/Include/pyport.h 721index 93250f4..b816c90 100644 722--- a/Include/pyport.h 723+++ b/Include/pyport.h 724@@ -53,6 +53,21 @@ 725 #endif 726 727 728+#ifdef __MINGW32__ 729+/* Translate GCC[mingw*] platform specific defines to those 730+ * used in python code. 731+ */ 732+#if !defined(MS_WIN64) && defined(_WIN64) 733+# define MS_WIN64 734+#endif 735+#if !defined(MS_WIN32) && defined(_WIN32) 736+# define MS_WIN32 737+#endif 738+#if !defined(MS_WINDOWS) && defined(MS_WIN32) 739+# define MS_WINDOWS 740+#endif 741+#endif /* __MINGW32__*/ 742+ 743 /************************************************************************** 744 Symbols and macros to supply platform-independent interfaces to basic 745 C language & library operations whose spellings vary across platforms. 746@@ -509,12 +524,12 @@ extern char * _getpty(int *, int, mode_t, int); 747 */ 748 749 /* 750- All windows ports, except cygwin, are handled in PC/pyconfig.h. 751+ Only MSVC windows ports is handled in PC/pyconfig.h. 752 753- Cygwin is the only other autoconf platform requiring special 754+ Cygwin and Mingw is the only other autoconf platform requiring special 755 linkage handling and it uses __declspec(). 756 */ 757-#if defined(__CYGWIN__) 758+#if defined(__CYGWIN__) || defined(__MINGW32__) 759 # define HAVE_DECLSPEC_DLL 760 #endif 761 762@@ -527,21 +542,23 @@ extern char * _getpty(int *, int, mode_t, int); 763 # define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE 764 # define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE 765 /* module init functions inside the core need no external linkage */ 766- /* except for Cygwin to handle embedding */ 767-# if defined(__CYGWIN__) 768+ /* except for Cygwin/Mingw to handle embedding */ 769+# if defined(__CYGWIN__) || defined(__MINGW32__) 770 # define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject* 771-# else /* __CYGWIN__ */ 772+# else /* __CYGWIN__ || __MINGW32__*/ 773 # define PyMODINIT_FUNC PyObject* 774-# endif /* __CYGWIN__ */ 775+# endif /* __CYGWIN__ || __MINGW32__*/ 776 # else /* Py_BUILD_CORE */ 777 /* Building an extension module, or an embedded situation */ 778 /* public Python functions and data are imported */ 779 /* Under Cygwin, auto-import functions to prevent compilation */ 780 /* failures similar to those described at the bottom of 4.1: */ 781 /* http://docs.python.org/extending/windows.html#a-cookbook-approach */ 782-# if !defined(__CYGWIN__) 783+# if defined(__CYGWIN__) || defined(__MINGW32__) 784+# define PyAPI_FUNC(RTYPE) RTYPE 785+# else 786 # define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE 787-# endif /* !__CYGWIN__ */ 788+# endif /* __CYGWIN__ || __MINGW32__*/ 789 # define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE 790 /* module init functions outside the core must be exported */ 791 # if defined(__cplusplus) 792@@ -641,6 +658,12 @@ extern char * _getpty(int *, int, mode_t, int); 793 794 #define Py_VA_COPY va_copy 795 796+#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__>= 4) || __GNUC__ > 4) 797+# define Py_PRINTF(X,Y) Py_GCC_ATTRIBUTE((format(gnu_printf,X,Y))) 798+#else 799+# define Py_PRINTF(X,Y) Py_GCC_ATTRIBUTE((format(printf,X,Y))) 800+#endif 801+ 802 /* 803 * Convenient macros to deal with endianness of the platform. WORDS_BIGENDIAN is 804 * detected by configure and defined in pyconfig.h. The code in pyconfig.h 805diff --git a/Include/pythread.h b/Include/pythread.h 806index a483290..9bf8bd6 100644 807--- a/Include/pythread.h 808+++ b/Include/pythread.h 809@@ -7,6 +7,12 @@ typedef void *PyThread_type_lock; 810 extern "C" { 811 #endif 812 813+#ifdef __MINGW32__ 814+# if !defined(HAVE_PTHREAD_H) || defined(NT_THREADS) 815+# undef _POSIX_THREADS 816+# endif 817+#endif 818+ 819 /* Return status codes for Python lock acquisition. Chosen for maximum 820 * backwards compatibility, ie failure -> 0, success -> 1. */ 821 typedef enum PyLockStatus { 822diff --git a/Include/sysmodule.h b/Include/sysmodule.h 823index b508711..d6767dc 100644 824--- a/Include/sysmodule.h 825+++ b/Include/sysmodule.h 826@@ -15,9 +15,9 @@ Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); 827 Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetPath(const wchar_t *); 828 829 PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) 830- Py_GCC_ATTRIBUTE((format(printf, 1, 2))); 831+ Py_PRINTF(1, 2); 832 PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) 833- Py_GCC_ATTRIBUTE((format(printf, 1, 2))); 834+ Py_PRINTF(1, 2); 835 PyAPI_FUNC(void) PySys_FormatStdout(const char *format, ...); 836 PyAPI_FUNC(void) PySys_FormatStderr(const char *format, ...); 837 838diff --git a/Lib/compileall.py b/Lib/compileall.py 839index a388931..069ea2b 100644 840--- a/Lib/compileall.py 841+++ b/Lib/compileall.py 842@@ -38,6 +38,8 @@ def _walk_dir(dir, maxlevels, quiet=0): 843 if name == '__pycache__': 844 continue 845 fullname = os.path.join(dir, name) 846+ if sys.platform == "win32" and sys.version.find("GCC") >= 0: 847+ fullname = fullname.replace('\\','/') 848 if not os.path.isdir(fullname): 849 yield fullname 850 elif (maxlevels > 0 and name != os.curdir and name != os.pardir and 851diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py 852index 26135ad..76d583b 100644 853--- a/Lib/ctypes/__init__.py 854+++ b/Lib/ctypes/__init__.py 855@@ -458,7 +458,9 @@ def LoadLibrary(self, name): 856 cdll = LibraryLoader(CDLL) 857 pydll = LibraryLoader(PyDLL) 858 859-if _os.name == "nt": 860+if _os.name == "nt" and _sys.version.find('GCC') >= 0: 861+ pythonapi = PyDLL("libpython%d.%d%s.dll" % (_sys.version_info[:2] + (_sys.abiflags,)), None) 862+elif _os.name == "nt": 863 pythonapi = PyDLL("python dll", None, _sys.dllhandle) 864 elif _sys.platform == "cygwin": 865 pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) 866diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py 867index 0c2510e..48ddb3b 100644 868--- a/Lib/ctypes/util.py 869+++ b/Lib/ctypes/util.py 870@@ -31,6 +31,12 @@ def _get_build_version(): 871 # else we don't know what version of the compiler this is 872 return None 873 874+ def find_msvcrt_mingw(): 875+ is_ucrt = 'clang' in sys.version.lower() or 'ucrt' in sys.version.lower() 876+ if is_ucrt: 877+ return None 878+ return 'msvcrt.dll' 879+ 880 def find_msvcrt(): 881 """Return the name of the VC runtime dll""" 882 version = _get_build_version() 883@@ -54,6 +60,9 @@ def find_msvcrt(): 884 885 def find_library(name): 886 if name in ('c', 'm'): 887+ import sysconfig 888+ if sysconfig.get_platform().startswith('mingw'): 889+ return find_msvcrt_mingw() 890 return find_msvcrt() 891 # See MSDN for the REAL search order. 892 for directory in os.environ['PATH'].split(os.pathsep): 893diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py 894index 4c47f2e..ab61a86 100644 895--- a/Lib/distutils/ccompiler.py 896+++ b/Lib/distutils/ccompiler.py 897@@ -9,7 +9,7 @@ 898 from distutils.file_util import move_file 899 from distutils.dir_util import mkpath 900 from distutils.dep_util import newer_group 901-from distutils.util import split_quoted, execute 902+from distutils.util import split_quoted, execute, get_platform 903 from distutils import log 904 905 class CCompiler: 906@@ -948,6 +948,8 @@ def get_default_compiler(osname=None, platform=None): 907 osname = os.name 908 if platform is None: 909 platform = sys.platform 910+ if get_platform().startswith('mingw'): 911+ return 'mingw32' 912 for pattern, compiler in _default_compilers: 913 if re.match(pattern, platform) is not None or \ 914 re.match(pattern, osname) is not None: 915diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py 916index f287b34..e87e3ad 100644 917--- a/Lib/distutils/command/build_ext.py 918+++ b/Lib/distutils/command/build_ext.py 919@@ -186,7 +186,7 @@ def finalize_options(self): 920 # for extensions under windows use different directories 921 # for Release and Debug builds. 922 # also Python's library directory must be appended to library_dirs 923- if os.name == 'nt': 924+ if os.name == 'nt' and not self.plat_name.startswith(('mingw')): 925 # the 'libs' directory is for binary installs - we assume that 926 # must be the *native* platform. But we don't really support 927 # cross-compiling via a binary install anyway, so we let it go. 928@@ -218,15 +218,16 @@ def finalize_options(self): 929 930 # For extensions under Cygwin, Python's library directory must be 931 # appended to library_dirs 932- if sys.platform[:6] == 'cygwin': 933- if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): 934+ if sys.platform[:6] == 'cygwin' or self.plat_name.startswith(('mingw')): 935+ if not sysconfig.python_build: 936 # building third party extensions 937+ config_dir_name = os.path.basename(sysconfig.get_config_var('LIBPL')) 938 self.library_dirs.append(os.path.join(sys.prefix, "lib", 939 "python" + get_python_version(), 940- "config")) 941+ config_dir_name)) 942 else: 943 # building python standard extensions 944- self.library_dirs.append('.') 945+ self.library_dirs.append(sysconfig.project_base) 946 947 # For building extensions with a shared Python library, 948 # Python's library directory must be appended to library_dirs 949@@ -237,7 +238,7 @@ def finalize_options(self): 950 self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) 951 else: 952 # building python standard extensions 953- self.library_dirs.append('.') 954+ self.library_dirs.append(sysconfig.project_base) 955 956 # The argument parsing will result in self.define being a string, but 957 # it has to be a list of 2-tuples. All the preprocessor symbols 958@@ -712,6 +713,20 @@ def get_libraries(self, ext): 959 # pyconfig.h that MSVC groks. The other Windows compilers all seem 960 # to need it mentioned explicitly, though, so that's what we do. 961 # Append '_d' to the python import library on debug builds. 962+ 963+ # Use self.plat_name as it works even in case of 964+ # cross-compilation (at least for mingw build). 965+ if self.plat_name.startswith('mingw'): 966+ from distutils import sysconfig 967+ extra = [] 968+ for lib in ( 969+ sysconfig.get_config_var('BLDLIBRARY').split() 970+ + sysconfig.get_config_var('SHLIBS').split() 971+ ): 972+ if lib.startswith('-l'): 973+ extra.append(lib[2:]) 974+ return ext.libraries + extra 975+ 976 if sys.platform == "win32": 977 from distutils._msvccompiler import MSVCCompiler 978 if not isinstance(self.compiler, MSVCCompiler): 979diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py 980index 01d5331..25eb3d8 100644 981--- a/Lib/distutils/command/install.py 982+++ b/Lib/distutils/command/install.py 983@@ -72,8 +72,8 @@ 984 INSTALL_SCHEMES['nt_user'] = { 985 'purelib': '$usersite', 986 'platlib': '$usersite', 987- 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', 988- 'scripts': '$userbase/Python$py_version_nodot/Scripts', 989+ 'headers': '$userbase/include/python$py_version_short_plat$abiflags/$dist_name', 990+ 'scripts': '$userbase/bin', 991 'data' : '$userbase', 992 } 993 994@@ -81,7 +81,7 @@ 995 'purelib': '$usersite', 996 'platlib': '$usersite', 997 'headers': 998- '$userbase/include/python$py_version_short$abiflags/$dist_name', 999+ '$userbase/include/python$py_version_short_plat$abiflags/$dist_name', 1000 'scripts': '$userbase/bin', 1001 'data' : '$userbase', 1002 } 1003@@ -311,6 +311,7 @@ def finalize_options(self): 1004 'py_version': py_version, 1005 'py_version_short': '%d.%d' % sys.version_info[:2], 1006 'py_version_nodot': '%d%d' % sys.version_info[:2], 1007+ 'py_version_short_plat': f'{sys.version_info[0]}.{sys.version_info[1]}-{get_platform()}' if os.name == 'nt' and 'gcc' in sys.version.lower() else f'{sys.version_info[0]}.{sys.version_info[1]}', 1008 'sys_prefix': prefix, 1009 'prefix': prefix, 1010 'sys_exec_prefix': exec_prefix, 1011@@ -363,7 +364,8 @@ def finalize_options(self): 1012 1013 # Convert directories from Unix /-separated syntax to the local 1014 # convention. 1015- self.convert_paths('lib', 'purelib', 'platlib', 1016+ self.convert_paths('base', 'platbase', 1017+ 'lib', 'purelib', 'platlib', 1018 'scripts', 'data', 'headers') 1019 if HAS_USER_SITE: 1020 self.convert_paths('userbase', 'usersite') 1021diff --git a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py 1022index 66c12dd..d8c8428 100644 1023--- a/Lib/distutils/cygwinccompiler.py 1024+++ b/Lib/distutils/cygwinccompiler.py 1025@@ -44,12 +44,13 @@ 1026 # (ld supports -shared) 1027 # * mingw gcc 3.2/ld 2.13 works 1028 # (ld supports -shared) 1029+# * llvm-mingw with Clang 11 works 1030+# (lld supports -shared) 1031 1032 import os 1033 import sys 1034 import copy 1035-from subprocess import Popen, PIPE, check_output 1036-import re 1037+import shlex 1038 1039 from distutils.unixccompiler import UnixCCompiler 1040 from distutils.file_util import write_file 1041@@ -57,6 +58,7 @@ 1042 CompileError, UnknownFileError) 1043 from distutils.version import LooseVersion 1044 from distutils.spawn import find_executable 1045+from subprocess import Popen, check_output 1046 1047 def get_msvcr(): 1048 """Include the appropriate MSVC runtime library if Python was built 1049@@ -91,6 +93,7 @@ class CygwinCCompiler(UnixCCompiler): 1050 obj_extension = ".o" 1051 static_lib_extension = ".a" 1052 shared_lib_extension = ".dll" 1053+ dylib_lib_extension = ".dll.a" 1054 static_lib_format = "lib%s%s" 1055 shared_lib_format = "%s%s" 1056 exe_extension = ".exe" 1057@@ -109,50 +112,28 @@ def __init__(self, verbose=0, dry_run=0, force=0): 1058 "Compiling may fail because of undefined preprocessor macros." 1059 % details) 1060 1061- self.gcc_version, self.ld_version, self.dllwrap_version = \ 1062- get_versions() 1063- self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" % 1064- (self.gcc_version, 1065- self.ld_version, 1066- self.dllwrap_version) ) 1067- 1068- # ld_version >= "2.10.90" and < "2.13" should also be able to use 1069- # gcc -mdll instead of dllwrap 1070- # Older dllwraps had own version numbers, newer ones use the 1071- # same as the rest of binutils ( also ld ) 1072- # dllwrap 2.10.90 is buggy 1073- if self.ld_version >= "2.10.90": 1074- self.linker_dll = "gcc" 1075- else: 1076- self.linker_dll = "dllwrap" 1077+ self.cc = os.environ.get('CC', 'gcc') 1078+ self.cxx = os.environ.get('CXX', 'g++') 1079 1080- # ld_version >= "2.13" support -shared so use it instead of 1081- # -mdll -static 1082- if self.ld_version >= "2.13": 1083- shared_option = "-shared" 1084- else: 1085- shared_option = "-mdll -static" 1086- 1087- # Hard-code GCC because that's what this is all about. 1088- # XXX optimization, warnings etc. should be customizable. 1089- self.set_executables(compiler='gcc -mcygwin -O -Wall', 1090- compiler_so='gcc -mcygwin -mdll -O -Wall', 1091- compiler_cxx='g++ -mcygwin -O -Wall', 1092- linker_exe='gcc -mcygwin', 1093+ # Older numpy dependend on this existing to check for ancient 1094+ # gcc versions. This doesn't make much sense with clang etc so 1095+ # just hardcode to something recent. 1096+ # https://github.com/numpy/numpy/pull/20333 1097+ self.gcc_version = LooseVersion("11.2.0") 1098+ 1099+ self.linker_dll = self.cc 1100+ shared_option = "-shared" 1101+ 1102+ self.set_executables(compiler='%s -mcygwin -O -Wall' % self.cc, 1103+ compiler_so='%s -mcygwin -mdll -O -Wall' % self.cc, 1104+ compiler_cxx='%s -mcygwin -O -Wall' % self.cxx, 1105+ linker_exe='%s -mcygwin' % self.cc, 1106 linker_so=('%s -mcygwin %s' % 1107 (self.linker_dll, shared_option))) 1108 1109- # cygwin and mingw32 need different sets of libraries 1110- if self.gcc_version == "2.91.57": 1111- # cygwin shouldn't need msvcrt, but without the dlls will crash 1112- # (gcc version 2.91.57) -- perhaps something about initialization 1113- self.dll_libraries=["msvcrt"] 1114- self.warn( 1115- "Consider upgrading to a newer version of gcc") 1116- else: 1117- # Include the appropriate MSVC runtime library if Python was built 1118- # with MSVC 7.0 or later. 1119- self.dll_libraries = get_msvcr() 1120+ # Include the appropriate MSVC runtime library if Python was built 1121+ # with MSVC 7.0 or later. 1122+ self.dll_libraries = get_msvcr() 1123 1124 def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): 1125 """Compiles the source by spawning GCC and windres if needed.""" 1126@@ -162,6 +143,28 @@ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): 1127 self.spawn(["windres", "-i", src, "-o", obj]) 1128 except DistutilsExecError as msg: 1129 raise CompileError(msg) 1130+ elif ext == '.mc': 1131+ # Adapted from msvc9compiler: 1132+ # 1133+ # Compile .MC to .RC file to .RES file. 1134+ # * '-h dir' specifies the directory for the generated include file 1135+ # * '-r dir' specifies the target directory of the generated RC file and the binary message resource it includes 1136+ # 1137+ # For now (since there are no options to change this), 1138+ # we use the source-directory for the include file and 1139+ # the build directory for the RC file and message 1140+ # resources. This works at least for win32all. 1141+ h_dir = os.path.dirname(src) 1142+ rc_dir = os.path.dirname(obj) 1143+ try: 1144+ # first compile .MC to .RC and .H file 1145+ self.spawn(['windmc'] + ['-h', h_dir, '-r', rc_dir] + [src]) 1146+ base, _ = os.path.splitext(os.path.basename(src)) 1147+ rc_file = os.path.join(rc_dir, base + '.rc') 1148+ # then compile .RC to .RES file 1149+ self.spawn(['windres', '-i', rc_file, '-o', obj]) 1150+ except DistutilsExecError as msg: 1151+ raise CompileError(msg) 1152 else: # for other files use the C-compiler 1153 try: 1154 self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + 1155@@ -214,28 +217,21 @@ def link(self, target_desc, objects, output_filename, output_dir=None, 1156 1157 # next add options for def-file and to creating import libraries 1158 1159- # dllwrap uses different options than gcc/ld 1160- if self.linker_dll == "dllwrap": 1161- extra_preargs.extend(["--output-lib", lib_file]) 1162- # for dllwrap we have to use a special option 1163- extra_preargs.extend(["--def", def_file]) 1164- # we use gcc/ld here and can be sure ld is >= 2.9.10 1165- else: 1166- # doesn't work: bfd_close build\...\libfoo.a: Invalid operation 1167- #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file]) 1168- # for gcc/ld the def-file is specified as any object files 1169- objects.append(def_file) 1170+ # doesn't work: bfd_close build\...\libfoo.a: Invalid operation 1171+ #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file]) 1172+ # for gcc/ld the def-file is specified as any object files 1173+ objects.append(def_file) 1174 1175 #end: if ((export_symbols is not None) and 1176 # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): 1177 1178 # who wants symbols and a many times larger output file 1179 # should explicitly switch the debug mode on 1180- # otherwise we let dllwrap/ld strip the output file 1181+ # otherwise we let ld strip the output file 1182 # (On my machine: 10KiB < stripped_file < ??100KiB 1183 # unstripped_file = stripped_file + XXX KiB 1184 # ( XXX=254 for a typical python extension)) 1185- if not debug: 1186+ if not debug and not hasattr(sys, 'gettotalrefcount'): 1187 extra_preargs.append("-s") 1188 1189 UnixCCompiler.link(self, target_desc, objects, output_filename, 1190@@ -253,11 +249,16 @@ def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): 1191 output_dir = '' 1192 obj_names = [] 1193 for src_name in source_filenames: 1194- # use normcase to make sure '.rc' is really '.rc' and not '.RC' 1195- base, ext = os.path.splitext(os.path.normcase(src_name)) 1196- if ext not in (self.src_extensions + ['.rc','.res']): 1197+ base, ext = os.path.splitext(src_name) 1198+ # use 'normcase' only for resource suffixes 1199+ ext_normcase = os.path.normcase(ext) 1200+ if ext_normcase in ['.rc', '.res', '.mc']: 1201+ ext = ext_normcase 1202+ if ext not in (self.src_extensions + ['.rc', '.res', '.mc']): 1203 raise UnknownFileError("unknown file type '%s' (from '%s')" % \ 1204 (ext, src_name)) 1205+ base = os.path.splitdrive(base)[1] # Chop off the drive 1206+ base = base[os.path.isabs(base):] # If abs, chop off leading / 1207 if strip_dir: 1208 base = os.path.basename (base) 1209 if ext in ('.res', '.rc'): 1210@@ -279,31 +280,18 @@ def __init__(self, verbose=0, dry_run=0, force=0): 1211 1212 CygwinCCompiler.__init__ (self, verbose, dry_run, force) 1213 1214- # ld_version >= "2.13" support -shared so use it instead of 1215- # -mdll -static 1216- if self.ld_version >= "2.13": 1217- shared_option = "-shared" 1218- else: 1219- shared_option = "-mdll -static" 1220- 1221- # A real mingw32 doesn't need to specify a different entry point, 1222- # but cygwin 2.91.57 in no-cygwin-mode needs it. 1223- if self.gcc_version <= "2.91.57": 1224- entry_point = '--entry _DllMain@12' 1225- else: 1226- entry_point = '' 1227+ shared_option = "-shared" 1228 1229- if is_cygwingcc(): 1230+ if is_cygwincc(self.cc): 1231 raise CCompilerError( 1232 'Cygwin gcc cannot be used with --compiler=mingw32') 1233 1234- self.set_executables(compiler='gcc -O -Wall', 1235- compiler_so='gcc -mdll -O -Wall', 1236- compiler_cxx='g++ -O -Wall', 1237- linker_exe='gcc', 1238- linker_so='%s %s %s' 1239- % (self.linker_dll, shared_option, 1240- entry_point)) 1241+ self.set_executables(compiler='%s -O2 -Wall' % self.cc, 1242+ compiler_so='%s -mdll -O2 -Wall' % self.cc, 1243+ compiler_cxx='%s -O2 -Wall' % self.cxx, 1244+ linker_exe='%s' % self.cc, 1245+ linker_so='%s %s' 1246+ % (self.linker_dll, shared_option)) 1247 # Maybe we should also append -mthreads, but then the finished 1248 # dlls need another dll (mingwm10.dll see Mingw32 docs) 1249 # (-mthreads: Support thread-safe exception handling on `Mingw32') 1250@@ -313,7 +301,7 @@ def __init__(self, verbose=0, dry_run=0, force=0): 1251 1252 # Include the appropriate MSVC runtime library if Python was built 1253 # with MSVC 7.0 or later. 1254- self.dll_libraries = get_msvcr() 1255+ self.dll_libraries = get_msvcr() or [] 1256 1257 # Because these compilers aren't configured in Python's pyconfig.h file by 1258 # default, we should at least warn the user if he is using an unmodified 1259@@ -351,6 +339,10 @@ def check_config_h(): 1260 if "GCC" in sys.version: 1261 return CONFIG_H_OK, "sys.version mentions 'GCC'" 1262 1263+ # Clang would also work 1264+ if "Clang" in sys.version: 1265+ return CONFIG_H_OK, "sys.version mentions 'Clang'" 1266+ 1267 # let's see if __GNUC__ is mentioned in python.h 1268 fn = sysconfig.get_config_h_filename() 1269 try: 1270@@ -366,38 +358,8 @@ def check_config_h(): 1271 return (CONFIG_H_UNCERTAIN, 1272 "couldn't read '%s': %s" % (fn, exc.strerror)) 1273 1274-RE_VERSION = re.compile(br'(\d+\.\d+(\.\d+)*)') 1275- 1276-def _find_exe_version(cmd): 1277- """Find the version of an executable by running `cmd` in the shell. 1278- 1279- If the command is not found, or the output does not match 1280- `RE_VERSION`, returns None. 1281- """ 1282- executable = cmd.split()[0] 1283- if find_executable(executable) is None: 1284- return None 1285- out = Popen(cmd, shell=True, stdout=PIPE).stdout 1286- try: 1287- out_string = out.read() 1288- finally: 1289- out.close() 1290- result = RE_VERSION.search(out_string) 1291- if result is None: 1292- return None 1293- # LooseVersion works with strings 1294- # so we need to decode our bytes 1295- return LooseVersion(result.group(1).decode()) 1296- 1297-def get_versions(): 1298- """ Try to find out the versions of gcc, ld and dllwrap. 1299- 1300- If not possible it returns None for it. 1301- """ 1302- commands = ['gcc -dumpversion', 'ld -v', 'dllwrap --version'] 1303- return tuple([_find_exe_version(cmd) for cmd in commands]) 1304 1305-def is_cygwingcc(): 1306- '''Try to determine if the gcc that would be used is from cygwin.''' 1307- out_string = check_output(['gcc', '-dumpmachine']) 1308+def is_cygwincc(cc): 1309+ '''Try to determine if the compiler that would be used is from cygwin.''' 1310+ out_string = check_output(shlex.split(cc) + ['-dumpmachine']) 1311 return out_string.strip().endswith(b'cygwin') 1312diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py 1313index a7976fb..c341679 100644 1314--- a/Lib/distutils/msvc9compiler.py 1315+++ b/Lib/distutils/msvc9compiler.py 1316@@ -291,8 +291,6 @@ def query_vcvarsall(version, arch="x86"): 1317 1318 # More globals 1319 VERSION = get_build_version() 1320-if VERSION < 8.0: 1321- raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION) 1322 # MACROS = MacroExpander(VERSION) 1323 1324 class MSVCCompiler(CCompiler) : 1325@@ -327,6 +325,8 @@ class MSVCCompiler(CCompiler) : 1326 1327 def __init__(self, verbose=0, dry_run=0, force=0): 1328 CCompiler.__init__ (self, verbose, dry_run, force) 1329+ if VERSION < 8.0: 1330+ raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION) 1331 self.__version = VERSION 1332 self.__root = r"Software\Microsoft\VisualStudio" 1333 # self.__macros = MACROS 1334diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py 1335index 03b8558..024c15c 100644 1336--- a/Lib/distutils/sysconfig.py 1337+++ b/Lib/distutils/sysconfig.py 1338@@ -64,8 +64,23 @@ def parse_config_h(fp, g=None): 1339 1340 _python_build = partial(is_python_build, check_home=True) 1341 _init_posix = partial(sysconfig_init_posix, _config_vars) 1342-_init_nt = partial(_init_non_posix, _config_vars) 1343 1344+def _posix_build(): 1345+ # GCC[mingw*] use posix build system 1346+ # Check for cross builds explicitly 1347+ host_platform = os.environ.get("_PYTHON_HOST_PLATFORM") 1348+ if host_platform: 1349+ if host_platform.startswith('mingw'): 1350+ return True 1351+ return os.name == 'posix' or \ 1352+ (os.name == "nt" and 'GCC' in sys.version) 1353+posix_build = _posix_build() 1354+ 1355+ 1356+def _init_nt(): 1357+ if posix_build: 1358+ return _init_posix(_config_vars) 1359+ return _init_non_posix(_config_vars) 1360 1361 # Similar function is also implemented in sysconfig as _parse_makefile 1362 # but without the parsing capabilities of distutils.text_file.TextFile. 1363@@ -196,7 +211,23 @@ def customize_compiler(compiler): 1364 Mainly needed on Unix, so we can plug in the information that 1365 varies across Unices and is stored in Python's Makefile. 1366 """ 1367- if compiler.compiler_type == "unix": 1368+ global _config_vars 1369+ if compiler.compiler_type in ["cygwin", "mingw32"]: 1370+ # Note that cygwin use posix build and 'unix' compiler. 1371+ # If build is not based on posix then we must predefine 1372+ # some environment variables corresponding to posix 1373+ # build rules and defaults. 1374+ if not 'GCC' in sys.version: 1375+ _config_vars['CC'] = "gcc" 1376+ _config_vars['CXX'] = "g++" 1377+ _config_vars['OPT'] = "-fwrapv -O3 -Wall -Wstrict-prototypes" 1378+ _config_vars['CFLAGS'] = "" 1379+ _config_vars['CCSHARED'] = "" 1380+ _config_vars['LDSHARED'] = "gcc -shared -Wl,--enable-auto-image-base" 1381+ _config_vars['AR'] = "ar" 1382+ _config_vars['ARFLAGS'] = "rc" 1383+ 1384+ if compiler.compiler_type in ["unix", "cygwin", "mingw32"]: 1385 if sys.platform == "darwin": 1386 # Perform first-time customization of compiler-related 1387 # config vars on OS X now that we know we need a compiler. 1388@@ -274,7 +305,7 @@ def get_python_inc(plat_specific=0, prefix=None): 1389 """ 1390 if prefix is None: 1391 prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX 1392- if os.name == "posix": 1393+ if posix_build: 1394 if python_build: 1395 # Assume the executable is in the build directory. The 1396 # pyconfig.h file should be in the same directory. Since 1397@@ -321,7 +352,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): 1398 else: 1399 prefix = plat_specific and EXEC_PREFIX or PREFIX 1400 1401- if os.name == "posix": 1402+ if posix_build: 1403 if plat_specific or standard_lib: 1404 # Platform-specific modules (any module from a non-pure-Python 1405 # module distribution) or standard Python library modules. 1406diff --git a/Lib/distutils/tests/test_cygwinccompiler.py b/Lib/distutils/tests/test_cygwinccompiler.py 1407index 0912ffd..a93c174 100644 1408--- a/Lib/distutils/tests/test_cygwinccompiler.py 1409+++ b/Lib/distutils/tests/test_cygwinccompiler.py 1410@@ -8,7 +8,7 @@ 1411 from distutils import cygwinccompiler 1412 from distutils.cygwinccompiler import (check_config_h, 1413 CONFIG_H_OK, CONFIG_H_NOTOK, 1414- CONFIG_H_UNCERTAIN, get_versions, 1415+ CONFIG_H_UNCERTAIN, 1416 get_msvcr) 1417 from distutils.tests import support 1418 1419@@ -81,40 +81,6 @@ def test_check_config_h(self): 1420 self.write_file(self.python_h, 'xxx __GNUC__ xxx') 1421 self.assertEqual(check_config_h()[0], CONFIG_H_OK) 1422 1423- def test_get_versions(self): 1424- 1425- # get_versions calls distutils.spawn.find_executable on 1426- # 'gcc', 'ld' and 'dllwrap' 1427- self.assertEqual(get_versions(), (None, None, None)) 1428- 1429- # Let's fake we have 'gcc' and it returns '3.4.5' 1430- self._exes['gcc'] = b'gcc (GCC) 3.4.5 (mingw special)\nFSF' 1431- res = get_versions() 1432- self.assertEqual(str(res[0]), '3.4.5') 1433- 1434- # and let's see what happens when the version 1435- # doesn't match the regular expression 1436- # (\d+\.\d+(\.\d+)*) 1437- self._exes['gcc'] = b'very strange output' 1438- res = get_versions() 1439- self.assertEqual(res[0], None) 1440- 1441- # same thing for ld 1442- self._exes['ld'] = b'GNU ld version 2.17.50 20060824' 1443- res = get_versions() 1444- self.assertEqual(str(res[1]), '2.17.50') 1445- self._exes['ld'] = b'@(#)PROGRAM:ld PROJECT:ld64-77' 1446- res = get_versions() 1447- self.assertEqual(res[1], None) 1448- 1449- # and dllwrap 1450- self._exes['dllwrap'] = b'GNU dllwrap 2.17.50 20060824\nFSF' 1451- res = get_versions() 1452- self.assertEqual(str(res[2]), '2.17.50') 1453- self._exes['dllwrap'] = b'Cheese Wrap' 1454- res = get_versions() 1455- self.assertEqual(res[2], None) 1456- 1457 def test_get_msvcr(self): 1458 1459 # none 1460diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py 1461index d00c489..76a7d82 100644 1462--- a/Lib/distutils/unixccompiler.py 1463+++ b/Lib/distutils/unixccompiler.py 1464@@ -249,9 +249,13 @@ def runtime_library_dir_option(self, dir): 1465 # -Wl whenever gcc was used in the past it is probably 1466 # safest to keep doing so. 1467 if sysconfig.get_config_var("GNULD") == "yes": 1468- # GNU ld needs an extra option to get a RUNPATH 1469+ # GNU ELF ld needs an extra option to get a RUNPATH 1470 # instead of just an RPATH. 1471- return "-Wl,--enable-new-dtags,-R" + dir 1472+ if sys.platform in ["win32", "cygwin"] or \ 1473+ "mingw" in compiler: 1474+ return [] 1475+ else: 1476+ return "-Wl,--enable-new-dtags,-R" + dir 1477 else: 1478 return "-Wl,-R" + dir 1479 else: 1480diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py 1481index 2ce5c5b..81626b3 100644 1482--- a/Lib/distutils/util.py 1483+++ b/Lib/distutils/util.py 1484@@ -37,6 +37,22 @@ def get_host_platform(): 1485 1486 """ 1487 if os.name == 'nt': 1488+ if 'gcc' in sys.version.lower(): 1489+ if 'ucrt' in sys.version.lower(): 1490+ if 'amd64' in sys.version.lower(): 1491+ return 'mingw_x86_64_ucrt' 1492+ return 'mingw_i686_ucrt' 1493+ if 'clang' in sys.version.lower(): 1494+ if 'amd64' in sys.version.lower(): 1495+ return 'mingw_x86_64_clang' 1496+ if 'arm64' in sys.version.lower(): 1497+ return 'mingw_aarch64' 1498+ if 'arm' in sys.version.lower(): 1499+ return 'mingw_armv7' 1500+ return 'mingw_i686_clang' 1501+ if 'amd64' in sys.version.lower(): 1502+ return 'mingw_x86_64' 1503+ return 'mingw_i686' 1504 if 'amd64' in sys.version.lower(): 1505 return 'win-amd64' 1506 if '(arm)' in sys.version.lower(): 1507@@ -130,6 +146,13 @@ def convert_path (pathname): 1508 paths.remove('.') 1509 if not paths: 1510 return os.curdir 1511+ # On Windows, if paths is ['C:','folder','subfolder'] then 1512+ # os.path.join(*paths) will return 'C:folder\subfolder' which 1513+ # is thus relative to the CWD on that drive. So we work around 1514+ # this by adding a \ to path[0] 1515+ if (len(paths) > 0 and paths[0].endswith(':') and 1516+ sys.platform == "win32" and sys.version.find("GCC") >= 0): 1517+ paths[0] += '\\' 1518 return os.path.join(*paths) 1519 1520 # convert_path () 1521@@ -140,6 +163,10 @@ def change_root (new_root, pathname): 1522 relative, this is equivalent to "os.path.join(new_root,pathname)". 1523 Otherwise, it requires making 'pathname' relative and then joining the 1524 two, which is tricky on DOS/Windows and Mac OS. 1525+ 1526+ If on Windows or OS/2 and both new_root and pathname are on different 1527+ drives, raises DistutilsChangeRootError as this is nonsensical, 1528+ otherwise use drive which can be in either of new_root or pathname. 1529 """ 1530 if os.name == 'posix': 1531 if not os.path.isabs(pathname): 1532@@ -149,9 +176,20 @@ def change_root (new_root, pathname): 1533 1534 elif os.name == 'nt': 1535 (drive, path) = os.path.splitdrive(pathname) 1536- if path[0] == '\\': 1537+ if path[0] == os.sep: 1538 path = path[1:] 1539- return os.path.join(new_root, path) 1540+ (drive_r, path_r) = os.path.splitdrive(new_root) 1541+ if path_r and path_r[0] == os.sep: 1542+ path_r = path_r[1:] 1543+ drive_used = '' 1544+ if len(drive) == 2 and len(drive_r) == 2 and drive != drive_r: 1545+ raise DistutilsChangeRootError("root and pathname not on same drive (%s, %s)" 1546+ % (drive_r,drive)) 1547+ elif len(drive_r) == 2: 1548+ drive_used = drive_r+os.sep 1549+ elif len(drive) == 2: 1550+ drive_used = drive+os.sep 1551+ return os.path.join(drive_used+path_r, path) 1552 1553 else: 1554 raise DistutilsPlatformError("nothing known about platform '%s'" % os.name) 1555diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py 1556index f603a89..7693d05 100644 1557--- a/Lib/importlib/_bootstrap_external.py 1558+++ b/Lib/importlib/_bootstrap_external.py 1559@@ -42,6 +42,10 @@ 1560 path_separators = ['\\', '/'] 1561 else: 1562 path_separators = ['/'] 1563+ 1564+if _os.environ.get('MSYSTEM', ''): 1565+ path_separators = path_separators[::-1] 1566+ 1567 # Assumption made in _path_join() 1568 assert all(len(sep) == 1 for sep in path_separators) 1569 path_sep = path_separators[0] 1570diff --git a/Lib/ntpath.py b/Lib/ntpath.py 1571index 0246419..7d5c3a5 100644 1572--- a/Lib/ntpath.py 1573+++ b/Lib/ntpath.py 1574@@ -11,9 +11,7 @@ 1575 curdir = '.' 1576 pardir = '..' 1577 extsep = '.' 1578-sep = '\\' 1579 pathsep = ';' 1580-altsep = '/' 1581 defpath = '.;C:\\bin' 1582 devnull = 'nul' 1583 1584@@ -23,6 +21,14 @@ 1585 import genericpath 1586 from genericpath import * 1587 1588+if sys.platform == "win32" and os.environ.get("MSYSTEM", ""): 1589+ sep = '/' 1590+ altsep = '\\' 1591+else: 1592+ sep = '\\' 1593+ altsep = '/' 1594+bsep = str.encode(sep) 1595+baltsep = str.encode(altsep) 1596 1597 __all__ = ["normcase","isabs","join","splitdrive","split","splitext", 1598 "basename","dirname","commonprefix","getsize","getmtime", 1599@@ -34,9 +40,33 @@ 1600 1601 def _get_bothseps(path): 1602 if isinstance(path, bytes): 1603- return b'\\/' 1604+ return bsep+baltsep 1605+ else: 1606+ return sep+altsep 1607+ 1608+def _get_sep(path): 1609+ if isinstance(path, bytes): 1610+ return bsep 1611+ else: 1612+ return sep 1613+ 1614+def _get_altsep(path): 1615+ if isinstance(path, bytes): 1616+ return baltsep 1617+ else: 1618+ return altsep 1619+ 1620+def _get_colon(path): 1621+ if isinstance(path, bytes): 1622+ return b':' 1623+ else: 1624+ return ':' 1625+ 1626+def _get_unc_prefix(path): 1627+ if isinstance(path, bytes): 1628+ return b'\\\\?\\UNC\\' 1629 else: 1630- return '\\/' 1631+ return '\\\\?\\UNC\\' 1632 1633 # Normalize the case of a pathname and map slashes to backslashes. 1634 # Other normalizations (such as optimizing '../' away) are not done 1635@@ -58,14 +88,14 @@ def normcase(s): 1636 return s 1637 if isinstance(s, bytes): 1638 encoding = sys.getfilesystemencoding() 1639- s = s.decode(encoding, 'surrogateescape').replace('/', '\\') 1640+ s = s.decode(encoding, 'surrogateescape').replace(altsep, sep) 1641 s = _LCMapStringEx(_LOCALE_NAME_INVARIANT, 1642 _LCMAP_LOWERCASE, s) 1643 return s.encode(encoding, 'surrogateescape') 1644 else: 1645 return _LCMapStringEx(_LOCALE_NAME_INVARIANT, 1646 _LCMAP_LOWERCASE, 1647- s.replace('/', '\\')) 1648+ s.replace(altsep, sep)) 1649 except ImportError: 1650 def normcase(s): 1651 """Normalize case of pathname. 1652@@ -74,8 +104,8 @@ def normcase(s): 1653 """ 1654 s = os.fspath(s) 1655 if isinstance(s, bytes): 1656- return os.fsencode(os.fsdecode(s).replace('/', '\\').lower()) 1657- return s.replace('/', '\\').lower() 1658+ return os.fsencode(os.fsdecode(s).replace(altsep, sep).lower()) 1659+ return s.replace(altsep, sep).lower() 1660 1661 1662 # Return whether a path is absolute. 1663@@ -87,14 +117,9 @@ def normcase(s): 1664 def isabs(s): 1665 """Test whether a path is absolute""" 1666 s = os.fspath(s) 1667- if isinstance(s, bytes): 1668- sep = b'\\' 1669- altsep = b'/' 1670- colon_sep = b':\\' 1671- else: 1672- sep = '\\' 1673- altsep = '/' 1674- colon_sep = ':\\' 1675+ sep = _get_sep(s) 1676+ altsep = _get_altsep(s) 1677+ colon_sep = _get_colon(s) + sep 1678 s = s[:3].replace(altsep, sep) 1679 # Absolute: UNC, device, and paths with a drive and root. 1680 # LEGACY BUG: isabs("/x") should be false since the path has no drive. 1681@@ -106,14 +131,9 @@ def isabs(s): 1682 # Join two (or more) paths. 1683 def join(path, *paths): 1684 path = os.fspath(path) 1685- if isinstance(path, bytes): 1686- sep = b'\\' 1687- seps = b'\\/' 1688- colon = b':' 1689- else: 1690- sep = '\\' 1691- seps = '\\/' 1692- colon = ':' 1693+ sep = _get_sep(path) 1694+ seps = _get_bothseps(path) 1695+ colon = _get_colon(path) 1696 try: 1697 if not paths: 1698 path[:0] + sep #23780: Ensure compatible data type even if p is null. 1699@@ -172,16 +192,10 @@ def splitdrive(p): 1700 """ 1701 p = os.fspath(p) 1702 if len(p) >= 2: 1703- if isinstance(p, bytes): 1704- sep = b'\\' 1705- altsep = b'/' 1706- colon = b':' 1707- unc_prefix = b'\\\\?\\UNC\\' 1708- else: 1709- sep = '\\' 1710- altsep = '/' 1711- colon = ':' 1712- unc_prefix = '\\\\?\\UNC\\' 1713+ sep = _get_sep(p) 1714+ altsep = _get_altsep(p) 1715+ colon = _get_colon(p) 1716+ unc_prefix = _get_unc_prefix(p) 1717 normp = p.replace(altsep, sep) 1718 if normp[0:2] == sep * 2: 1719 # UNC drives, e.g. \\server\share or \\?\UNC\server\share 1720@@ -231,9 +245,9 @@ def split(p): 1721 def splitext(p): 1722 p = os.fspath(p) 1723 if isinstance(p, bytes): 1724- return genericpath._splitext(p, b'\\', b'/', b'.') 1725+ return genericpath._splitext(p, bsep, baltsep, b'.') 1726 else: 1727- return genericpath._splitext(p, '\\', '/', '.') 1728+ return genericpath._splitext(p, sep, altsep, '.') 1729 splitext.__doc__ = genericpath._splitext.__doc__ 1730 1731 1732@@ -334,7 +348,7 @@ def expanduser(path): 1733 if 'USERPROFILE' in os.environ: 1734 userhome = os.environ['USERPROFILE'] 1735 elif not 'HOMEPATH' in os.environ: 1736- return path 1737+ return os.path.normpath(path) 1738 else: 1739 try: 1740 drive = os.environ['HOMEDRIVE'] 1741@@ -361,7 +375,7 @@ def expanduser(path): 1742 if isinstance(path, bytes): 1743 userhome = os.fsencode(userhome) 1744 1745- return userhome + path[i:] 1746+ return os.path.normpath(userhome) + path[i:] 1747 1748 1749 # Expand paths containing shell variable substitutions. 1750@@ -496,14 +510,12 @@ def expandvars(path): 1751 def normpath(path): 1752 """Normalize path, eliminating double slashes, etc.""" 1753 path = os.fspath(path) 1754+ sep = _get_sep(path) 1755+ altsep = _get_altsep(path) 1756 if isinstance(path, bytes): 1757- sep = b'\\' 1758- altsep = b'/' 1759 curdir = b'.' 1760 pardir = b'..' 1761 else: 1762- sep = '\\' 1763- altsep = '/' 1764 curdir = '.' 1765 pardir = '..' 1766 path = path.replace(altsep, sep) 1767@@ -570,7 +582,7 @@ def _abspath_fallback(path): 1768 def abspath(path): 1769 """Return the absolute version of a path.""" 1770 try: 1771- return _getfullpathname(normpath(path)) 1772+ return normpath(_getfullpathname(normpath(path))) 1773 except (OSError, ValueError): 1774 return _abspath_fallback(path) 1775 1776@@ -731,6 +743,7 @@ def realpath(path, *, strict=False): 1777 # strip the prefix anyway. 1778 if ex.winerror == initial_winerror: 1779 path = spath 1780+ path = normpath(path) 1781 return path 1782 1783 1784@@ -741,12 +754,11 @@ def realpath(path, *, strict=False): 1785 def relpath(path, start=None): 1786 """Return a relative version of a path""" 1787 path = os.fspath(path) 1788+ sep = _get_sep(path) 1789 if isinstance(path, bytes): 1790- sep = b'\\' 1791 curdir = b'.' 1792 pardir = b'..' 1793 else: 1794- sep = '\\' 1795 curdir = '.' 1796 pardir = '..' 1797 1798@@ -801,13 +813,11 @@ def commonpath(paths): 1799 raise ValueError('commonpath() arg is an empty sequence') 1800 1801 paths = tuple(map(os.fspath, paths)) 1802+ sep = _get_sep(paths[0]) 1803+ altsep = _get_altsep(paths[0]) 1804 if isinstance(paths[0], bytes): 1805- sep = b'\\' 1806- altsep = b'/' 1807 curdir = b'.' 1808 else: 1809- sep = '\\' 1810- altsep = '/' 1811 curdir = '.' 1812 1813 try: 1814diff --git a/Lib/pathlib.py b/Lib/pathlib.py 1815index ecb1e8a..eec8a9e 100644 1816--- a/Lib/pathlib.py 1817+++ b/Lib/pathlib.py 1818@@ -115,6 +115,8 @@ class _WindowsFlavour(_Flavour): 1819 1820 sep = '\\' 1821 altsep = '/' 1822+ if os.environ.get('MSYSTEM', ''): 1823+ sep, altsep = altsep, sep 1824 has_drv = True 1825 pathmod = ntpath 1826 1827diff --git a/Lib/site.py b/Lib/site.py 1828index 69670d9..41b9cf1 100644 1829--- a/Lib/site.py 1830+++ b/Lib/site.py 1831@@ -88,6 +88,12 @@ 1832 USER_BASE = None 1833 1834 1835+# Same as defined in Lib/sysconfig.py 1836+# redeclared since sysconfig is large for site. 1837+# GCC[mingw*] use posix build system 1838+_POSIX_BUILD = os.name == 'posix' or \ 1839+ (os.name == "nt" and 'GCC' in sys.version) 1840+ 1841 def _trace(message): 1842 if sys.flags.verbose: 1843 print(message, file=sys.stderr) 1844@@ -273,7 +279,7 @@ def _getuserbase(): 1845 def joinuser(*args): 1846 return os.path.expanduser(os.path.join(*args)) 1847 1848- if os.name == "nt": 1849+ if os.name == "nt" and not _POSIX_BUILD: 1850 base = os.environ.get("APPDATA") or "~" 1851 return joinuser(base, "Python") 1852 1853@@ -283,14 +289,36 @@ def joinuser(*args): 1854 1855 return joinuser("~", ".local") 1856 1857+# Copy of sysconfig.get_platform() but only for MinGW 1858+def _get_platform(): 1859+ if os.name == 'nt': 1860+ if 'gcc' in sys.version.lower(): 1861+ if 'ucrt' in sys.version.lower(): 1862+ if 'amd64' in sys.version.lower(): 1863+ return 'mingw_x86_64_ucrt' 1864+ return 'mingw_i686_ucrt' 1865+ if 'clang' in sys.version.lower(): 1866+ if 'amd64' in sys.version.lower(): 1867+ return 'mingw_x86_64_clang' 1868+ if 'arm64' in sys.version.lower(): 1869+ return 'mingw_aarch64' 1870+ if 'arm' in sys.version.lower(): 1871+ return 'mingw_armv7' 1872+ return 'mingw_i686_clang' 1873+ if 'amd64' in sys.version.lower(): 1874+ return 'mingw_x86_64' 1875+ return 'mingw_i686' 1876+ return sys.platform 1877 1878 # Same to sysconfig.get_path('purelib', os.name+'_user') 1879 def _get_path(userbase): 1880 version = sys.version_info 1881 1882 if os.name == 'nt': 1883- ver_nodot = sys.winver.replace('.', '') 1884- return f'{userbase}\\Python{ver_nodot}\\site-packages' 1885+ if not _POSIX_BUILD: 1886+ ver_nodot = sys.winver.replace('.', '') 1887+ return f'{userbase}\\Python{ver_nodot}\\site-packages' 1888+ return f'{userbase}/lib/python{version[0]}.{version[1]}-{_get_platform()}/site-packages' 1889 1890 if sys.platform == 'darwin' and sys._framework: 1891 return f'{userbase}/lib/python/site-packages' 1892@@ -361,7 +389,7 @@ def getsitepackages(prefixes=None): 1893 continue 1894 seen.add(prefix) 1895 1896- if os.sep == '/': 1897+ if _POSIX_BUILD: 1898 libdirs = [sys.platlibdir] 1899 if sys.platlibdir != "lib": 1900 libdirs.append("lib") 1901@@ -392,7 +420,7 @@ def setquit(): 1902 The repr of each object contains a hint at how it works. 1903 1904 """ 1905- if os.sep == '\\': 1906+ if sys.platform == 'win32': 1907 eof = 'Ctrl-Z plus Return' 1908 else: 1909 eof = 'Ctrl-D (i.e. EOF)' 1910diff --git a/Lib/ssl.py b/Lib/ssl.py 1911index ced87d4..ebb6b6f 100644 1912--- a/Lib/ssl.py 1913+++ b/Lib/ssl.py 1914@@ -254,7 +254,7 @@ class _TLSMessageType: 1915 CHANGE_CIPHER_SPEC = 0x0101 1916 1917 1918-if sys.platform == "win32": 1919+if sys.platform == "win32" and sys.version.find("GCC") == -1: 1920 from _ssl import enum_certificates, enum_crls 1921 1922 from socket import socket, SOCK_STREAM, create_connection 1923@@ -591,7 +591,7 @@ def _load_windows_store_certs(self, storename, purpose): 1924 def load_default_certs(self, purpose=Purpose.SERVER_AUTH): 1925 if not isinstance(purpose, _ASN1Object): 1926 raise TypeError(purpose) 1927- if sys.platform == "win32": 1928+ if sys.platform == "win32" and sys.version.find("GCC") == -1: 1929 for storename in self._windows_cert_stores: 1930 self._load_windows_store_certs(storename, purpose) 1931 self.set_default_verify_paths() 1932diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py 1933index ebe3711..8035d2e 100644 1934--- a/Lib/sysconfig.py 1935+++ b/Lib/sysconfig.py 1936@@ -2,6 +2,7 @@ 1937 1938 import os 1939 import sys 1940+import textwrap 1941 from os.path import pardir, realpath 1942 1943 __all__ = [ 1944@@ -47,13 +48,13 @@ 1945 'data': '{base}', 1946 }, 1947 'nt': { 1948- 'stdlib': '{installed_base}/Lib', 1949- 'platstdlib': '{base}/Lib', 1950- 'purelib': '{base}/Lib/site-packages', 1951- 'platlib': '{base}/Lib/site-packages', 1952- 'include': '{installed_base}/Include', 1953- 'platinclude': '{installed_base}/Include', 1954- 'scripts': '{base}/Scripts', 1955+ 'stdlib': '{installed_base}/lib/python{py_version_short}', 1956+ 'platstdlib': '{base}/lib/python{py_version_short}', 1957+ 'purelib': '{base}/lib/python{py_version_short}/site-packages', 1958+ 'platlib': '{base}/lib/python{py_version_short}/site-packages', 1959+ 'include': '{installed_base}/include/python{py_version_short}', 1960+ 'platinclude': '{installed_base}/include/python{py_version_short}', 1961+ 'scripts': '{base}/bin', 1962 'data': '{base}', 1963 }, 1964 # Downstream distributors can overwrite the default install scheme. 1965@@ -97,13 +98,18 @@ 1966 }, 1967 } 1968 1969+# GCC[mingw*] use posix build system 1970+_POSIX_BUILD = os.name == 'posix' or \ 1971+ (os.name == "nt" and 'GCC' in sys.version) 1972+ 1973 # For the OS-native venv scheme, we essentially provide an alias: 1974-if os.name == 'nt': 1975+if os.name == 'nt' and not _POSIX_BUILD: 1976 _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv'] 1977 else: 1978 _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] 1979 1980 1981+ 1982 # NOTE: site.py has copy of this function. 1983 # Sync it when modify this function. 1984 def _getuserbase(): 1985@@ -118,7 +124,7 @@ def _getuserbase(): 1986 def joinuser(*args): 1987 return os.path.expanduser(os.path.join(*args)) 1988 1989- if os.name == "nt": 1990+ if os.name == "nt" and not _POSIX_BUILD: 1991 base = os.environ.get("APPDATA") or "~" 1992 return joinuser(base, "Python") 1993 1994@@ -134,20 +140,20 @@ def joinuser(*args): 1995 _INSTALL_SCHEMES |= { 1996 # NOTE: When modifying "purelib" scheme, update site._get_path() too. 1997 'nt_user': { 1998- 'stdlib': '{userbase}/Python{py_version_nodot_plat}', 1999- 'platstdlib': '{userbase}/Python{py_version_nodot_plat}', 2000- 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages', 2001- 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages', 2002- 'include': '{userbase}/Python{py_version_nodot_plat}/Include', 2003- 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts', 2004+ 'stdlib': '{userbase}/lib/python{py_version_short_plat}', 2005+ 'platstdlib': '{userbase}/lib/python{py_version_short_plat}', 2006+ 'purelib': '{userbase}/lib/python{py_version_short_plat}/site-packages', 2007+ 'platlib': '{userbase}/lib/python{py_version_short_plat}/site-packages', 2008+ 'include': '{userbase}/include/python{py_version_short_plat}', 2009+ 'scripts': '{userbase}/bin', 2010 'data': '{userbase}', 2011 }, 2012 'posix_user': { 2013- 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}', 2014- 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}', 2015- 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', 2016- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', 2017- 'include': '{userbase}/include/python{py_version_short}', 2018+ 'stdlib': '{userbase}/{platlibdir}/python{py_version_short_plat}', 2019+ 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short_plat}', 2020+ 'purelib': '{userbase}/lib/python{py_version_short_plat}/site-packages', 2021+ 'platlib': '{userbase}/lib/python{py_version_short_plat}/site-packages', 2022+ 'include': '{userbase}/include/python{py_version_short_plat}', 2023 'scripts': '{userbase}/bin', 2024 'data': '{userbase}', 2025 }, 2026@@ -277,7 +283,7 @@ def _expand_vars(scheme, vars): 2027 2028 2029 def _get_preferred_schemes(): 2030- if os.name == 'nt': 2031+ if os.name == 'nt' and not _POSIX_BUILD: 2032 return { 2033 'prefix': 'nt', 2034 'home': 'posix_home', 2035@@ -435,6 +441,14 @@ def _parse_makefile(filename, vars=None, keep_unresolved=True): 2036 if isinstance(v, str): 2037 done[k] = v.strip() 2038 2039+ # any keys that have one with the same name suffixed with _b2h 2040+ # need to be replaced with the value of the _b2h key. 2041+ # This converts from MSYS*/Cygwin paths to Windows paths. 2042+ for k, v in dict(done).items(): 2043+ if isinstance(k, str): 2044+ if k.endswith("_b2h"): 2045+ done[k[:-4]]=v 2046+ 2047 # save the results in the global dictionary 2048 vars.update(done) 2049 return vars 2050@@ -514,11 +528,30 @@ def _generate_posix_vars(): 2051 os.makedirs(pybuilddir, exist_ok=True) 2052 destfile = os.path.join(pybuilddir, name + '.py') 2053 2054+ replacement = """ 2055+ keys_to_replace = [ 2056+ 'BINDIR', 'BINLIBDEST', 'CONFINCLUDEDIR', 2057+ 'CONFINCLUDEPY', 'DESTDIRS', 'DESTLIB', 'DESTSHARED', 2058+ 'INCLDIRSTOMAKE', 'INCLUDEDIR', 'INCLUDEPY', 2059+ 'LIBDEST', 'LIBDIR', 'LIBPC', 'LIBPL', 'MACHDESTLIB', 2060+ 'MANDIR', 'SCRIPTDIR', 'datarootdir', 'exec_prefix', 2061+ 'TZPATH', 2062+ ] 2063+ 2064+ prefix = build_time_vars['BINDIR'][:-4] 2065+ 2066+ for key in keys_to_replace: 2067+ value = build_time_vars[key] 2068+ build_time_vars[key] = value.replace(prefix, sys.prefix) 2069+ """ 2070+ 2071 with open(destfile, 'w', encoding='utf8') as f: 2072+ f.write('import sys\n') 2073 f.write('# system configuration generated and used by' 2074 ' the sysconfig module\n') 2075 f.write('build_time_vars = ') 2076 pprint.pprint(vars, stream=f) 2077+ f.write('\n%s' % textwrap.dedent(replacement)) 2078 2079 # Create file used for sys.path fixup -- see Modules/getpath.c 2080 with open('pybuilddir.txt', 'w', encoding='utf8') as f: 2081@@ -541,7 +574,7 @@ def _init_non_posix(vars): 2082 vars['INCLUDEPY'] = get_path('include') 2083 vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] 2084 vars['EXE'] = '.exe' 2085- vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT 2086+ vars['VERSION'] = _PY_VERSION_SHORT 2087 vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) 2088 vars['TZPATH'] = '' 2089 2090@@ -587,7 +620,7 @@ def parse_config_h(fp, vars=None): 2091 def get_config_h_filename(): 2092 """Return the path of pyconfig.h.""" 2093 if _PYTHON_BUILD: 2094- if os.name == "nt": 2095+ if os.name == "nt" and not _POSIX_BUILD: 2096 inc_dir = os.path.join(_PROJECT_BASE, "PC") 2097 else: 2098 inc_dir = _PROJECT_BASE 2099@@ -662,11 +695,15 @@ def get_config_vars(*args): 2100 _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') 2101 except AttributeError: 2102 _CONFIG_VARS['py_version_nodot_plat'] = '' 2103+ if os.name == 'nt' and _POSIX_BUILD: 2104+ _CONFIG_VARS['py_version_short_plat'] = f'{_PY_VERSION_SHORT}-{get_platform()}' 2105+ else: 2106+ _CONFIG_VARS['py_version_short_plat'] = _PY_VERSION_SHORT 2107 2108- if os.name == 'nt': 2109+ if os.name == 'nt' and not _POSIX_BUILD: 2110 _init_non_posix(_CONFIG_VARS) 2111 _CONFIG_VARS['VPATH'] = sys._vpath 2112- if os.name == 'posix': 2113+ if _POSIX_BUILD: 2114 _init_posix(_CONFIG_VARS) 2115 if _HAS_USER_BASE: 2116 # Setting 'userbase' is done below the call to the 2117@@ -676,7 +713,7 @@ def get_config_vars(*args): 2118 2119 # Always convert srcdir to an absolute path 2120 srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) 2121- if os.name == 'posix': 2122+ if _POSIX_BUILD: 2123 if _PYTHON_BUILD: 2124 # If srcdir is a relative path (typically '.' or '..') 2125 # then it should be interpreted relative to the directory 2126@@ -714,7 +751,7 @@ def get_config_var(name): 2127 """ 2128 return get_config_vars().get(name) 2129 2130- 2131+# make sure to change site._get_platform() while changing this function 2132 def get_platform(): 2133 """Return a string that identifies the current platform. 2134 2135@@ -737,6 +774,22 @@ def get_platform(): 2136 2137 """ 2138 if os.name == 'nt': 2139+ if 'gcc' in sys.version.lower(): 2140+ if 'ucrt' in sys.version.lower(): 2141+ if 'amd64' in sys.version.lower(): 2142+ return 'mingw_x86_64_ucrt' 2143+ return 'mingw_i686_ucrt' 2144+ if 'clang' in sys.version.lower(): 2145+ if 'amd64' in sys.version.lower(): 2146+ return 'mingw_x86_64_clang' 2147+ if 'arm64' in sys.version.lower(): 2148+ return 'mingw_aarch64' 2149+ if 'arm' in sys.version.lower(): 2150+ return 'mingw_armv7' 2151+ return 'mingw_i686_clang' 2152+ if 'amd64' in sys.version.lower(): 2153+ return 'mingw_x86_64' 2154+ return 'mingw_i686' 2155 if 'amd64' in sys.version.lower(): 2156 return 'win-amd64' 2157 if '(arm)' in sys.version.lower(): 2158diff --git a/Lib/test/__main__.py b/Lib/test/__main__.py 2159index 19a6b2b..7641b32 100644 2160--- a/Lib/test/__main__.py 2161+++ b/Lib/test/__main__.py 2162@@ -1,2 +1,10 @@ 2163+import os 2164+import sys 2165+ 2166 from test.libregrtest import main 2167+ 2168+if sys.platform == "win32": 2169+ # Enable DLL loading from PATH. 2170+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1" 2171+ 2172 main() 2173diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py 2174index 53ba1ad..3b6f4ab 100644 2175--- a/Lib/test/test_bytes.py 2176+++ b/Lib/test/test_bytes.py 2177@@ -1105,7 +1105,7 @@ def test_from_format(self): 2178 2179 if os.name == 'nt': 2180 # Windows (MSCRT) 2181- ptr_format = '0x%0{}X'.format(2 * sizeof_ptr) 2182+ ptr_format = '0x%0{}x'.format(2 * sizeof_ptr) 2183 def ptr_formatter(ptr): 2184 return (ptr_format % ptr) 2185 else: 2186diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py 2187index 8d5b426..82ad71d 100644 2188--- a/Lib/test/test_getpath.py 2189+++ b/Lib/test/test_getpath.py 2190@@ -838,6 +838,7 @@ def test_symlink_buildpath_macos(self): 2191 ENV_PYTHONHOME="", 2192 ENV_PYTHONEXECUTABLE="", 2193 ENV___PYVENV_LAUNCHER__="", 2194+ ENV_MSYSTEM="", 2195 argv0="", 2196 py_setpath="", 2197 real_executable="", 2198@@ -877,6 +878,7 @@ def __init__(self, *a, argv0=None, config=None, **kw): 2199 self.update(DEFAULT_NAMESPACE) 2200 self["config"] = DEFAULT_CONFIG.copy() 2201 self["os_name"] = "nt" 2202+ self["is_mingw"] = 0 2203 self["PLATLIBDIR"] = "DLLs" 2204 self["PYWINVER"] = "9.8-XY" 2205 self["VPATH"] = r"..\.." 2206@@ -912,6 +914,9 @@ def __missing__(self, key): 2207 except AttributeError: 2208 raise KeyError(key) from None 2209 2210+ def normpath(self, path): 2211+ return ntpath.normpath(path) 2212+ 2213 def abspath(self, path): 2214 if self.isabs(path): 2215 return path 2216@@ -1053,6 +1058,7 @@ def __init__(self, *a, argv0=None, config=None, **kw): 2217 self.update(DEFAULT_NAMESPACE) 2218 self["config"] = DEFAULT_CONFIG.copy() 2219 self["os_name"] = "posix" 2220+ self["is_mingw"] = 0 2221 self["PLATLIBDIR"] = "lib" 2222 self["WITH_NEXT_FRAMEWORK"] = 0 2223 super().__init__(*a, **kw) 2224@@ -1089,6 +1095,9 @@ def __missing__(self, key): 2225 except AttributeError: 2226 raise KeyError(key) from None 2227 2228+ def normpath(self, path): 2229+ return path 2230+ 2231 def abspath(self, path): 2232 if self.isabs(path): 2233 return path 2234diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py 2235index cdd1bea..cfd8a10 100644 2236--- a/Lib/test/test_httpservers.py 2237+++ b/Lib/test/test_httpservers.py 2238@@ -442,10 +442,10 @@ def test_undecodable_filename(self): 2239 def test_undecodable_parameter(self): 2240 # sanity check using a valid parameter 2241 response = self.request(self.base_url + '/?x=123').read() 2242- self.assertRegex(response, f'listing for {self.base_url}/\?x=123'.encode('latin1')) 2243+ self.assertRegex(response, rf'listing for {self.base_url}/\?x=123'.encode('latin1')) 2244 # now the bogus encoding 2245 response = self.request(self.base_url + '/?x=%bb').read() 2246- self.assertRegex(response, f'listing for {self.base_url}/\?x=\xef\xbf\xbd'.encode('latin1')) 2247+ self.assertRegex(response, rf'listing for {self.base_url}/\?x=\xef\xbf\xbd'.encode('latin1')) 2248 2249 def test_get_dir_redirect_location_domain_injection_bug(self): 2250 """Ensure //evil.co/..%2f../../X does not put //evil.co/ in Location. 2251diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py 2252index b7dfe86..58a8f5d 100644 2253--- a/Lib/test/test_importlib/test_windows.py 2254+++ b/Lib/test/test_importlib/test_windows.py 2255@@ -24,6 +24,23 @@ def get_platform(): 2256 'x64' : 'win-amd64', 2257 'arm' : 'win-arm32', 2258 } 2259+ if os.name == 'nt': 2260+ if 'gcc' in sys.version.lower(): 2261+ if 'ucrt' in sys.version.lower(): 2262+ if 'amd64' in sys.version.lower(): 2263+ return 'mingw_x86_64_ucrt' 2264+ return 'mingw_i686_ucrt' 2265+ if 'clang' in sys.version.lower(): 2266+ if 'amd64' in sys.version.lower(): 2267+ return 'mingw_x86_64_clang' 2268+ if 'arm64' in sys.version.lower(): 2269+ return 'mingw_aarch64' 2270+ if 'arm' in sys.version.lower(): 2271+ return 'mingw_armv7' 2272+ return 'mingw_i686_clang' 2273+ if 'amd64' in sys.version.lower(): 2274+ return 'mingw_x86_64' 2275+ return 'mingw_i686' 2276 if ('VSCMD_ARG_TGT_ARCH' in os.environ and 2277 os.environ['VSCMD_ARG_TGT_ARCH'] in TARGET_TO_PLAT): 2278 return TARGET_TO_PLAT[os.environ['VSCMD_ARG_TGT_ARCH']] 2279diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py 2280index d96371d..a75a664 100644 2281--- a/Lib/test/test_sysconfig.py 2282+++ b/Lib/test/test_sysconfig.py 2283@@ -17,7 +17,7 @@ 2284 from sysconfig import (get_paths, get_platform, get_config_vars, 2285 get_path, get_path_names, _INSTALL_SCHEMES, 2286 get_default_scheme, get_scheme_names, get_config_var, 2287- _expand_vars, _get_preferred_schemes, _main) 2288+ _expand_vars, _get_preferred_schemes, _main, _POSIX_BUILD) 2289 import _osx_support 2290 2291 2292@@ -180,7 +180,7 @@ def test_nt_venv_scheme(self): 2293 self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='nt_venv')) 2294 2295 def test_venv_scheme(self): 2296- if sys.platform == 'win32': 2297+ if not _POSIX_BUILD and sys.platform == 'win32': 2298 self.assertEqual( 2299 sysconfig.get_path('scripts', scheme='venv'), 2300 sysconfig.get_path('scripts', scheme='nt_venv') 2301@@ -371,6 +371,10 @@ def test_user_similar(self): 2302 if HAS_USER_BASE: 2303 user_path = get_path(name, 'posix_user') 2304 expected = os.path.normpath(global_path.replace(base, user, 1)) 2305+ if os.name == 'nt' and _POSIX_BUILD: 2306+ expected = expected.replace( 2307+ f'python{sysconfig.get_python_version()}', 2308+ f'python{sysconfig.get_python_version()}-{get_platform()}') 2309 # bpo-44860: platlib of posix_user doesn't use sys.platlibdir, 2310 # whereas posix_prefix does. 2311 if name == 'platlib': 2312diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py 2313index 4403f2b..ab5be51 100644 2314--- a/Lib/venv/__init__.py 2315+++ b/Lib/venv/__init__.py 2316@@ -302,7 +302,7 @@ def setup_python(self, context): 2317 if not os.path.islink(path): 2318 os.chmod(path, 0o755) 2319 else: 2320- if self.symlinks: 2321+ if self.symlinks and not _POSIX_BUILD: 2322 # For symlinking, we need a complete copy of the root directory 2323 # If symlinks fail, you'll get unnecessary copies of files, but 2324 # we assume that if you've opted into symlinks on Windows then 2325@@ -326,6 +326,12 @@ def setup_python(self, context): 2326 if os.path.lexists(src): 2327 copier(src, os.path.join(binpath, suffix)) 2328 2329+ if _POSIX_BUILD: 2330+ # copy from python/pythonw so the venvlauncher magic in symlink_or_copy triggers 2331+ copier(os.path.join(dirname, 'python.exe'), os.path.join(binpath, 'python3.exe')) 2332+ copier(os.path.join(dirname, 'python.exe'), os.path.join(binpath, 'python%d.%d.exe' % sys.version_info[:2])) 2333+ copier(os.path.join(dirname, 'pythonw.exe'), os.path.join(binpath, 'python3w.exe')) 2334+ 2335 if sysconfig.is_python_build(): 2336 # copy init.tcl 2337 for root, dirs, files in os.walk(context.python_dir): 2338@@ -350,6 +356,7 @@ def _call_new_python(self, context, *py_args, **kwargs): 2339 env['VIRTUAL_ENV'] = context.env_dir 2340 env.pop('PYTHONHOME', None) 2341 env.pop('PYTHONPATH', None) 2342+ env.pop("MSYSTEM", None) 2343 kwargs['cwd'] = context.env_dir 2344 kwargs['executable'] = context.env_exec_cmd 2345 subprocess.check_output(args, **kwargs) 2346diff --git a/Makefile.pre.in b/Makefile.pre.in 2347index 3ea8653..2707d04 100644 2348--- a/Makefile.pre.in 2349+++ b/Makefile.pre.in 2350@@ -39,6 +39,7 @@ CXX= @CXX@ 2351 MAINCC= @MAINCC@ 2352 LINKCC= @LINKCC@ 2353 AR= @AR@ 2354+WINDRES= @WINDRES@ 2355 READELF= @READELF@ 2356 SOABI= @SOABI@ 2357 LDVERSION= @LDVERSION@ 2358@@ -123,6 +124,7 @@ PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE 2359 PY_CORE_LDFLAGS=$(PY_LDFLAGS) $(PY_LDFLAGS_NODIST) 2360 # Strict or non-strict aliasing flags used to compile dtoa.c, see above 2361 CFLAGS_ALIASING=@CFLAGS_ALIASING@ 2362+RCFLAGS=@RCFLAGS@ 2363 2364 2365 # Machine-dependent subdirectories 2366@@ -141,6 +143,12 @@ exec_prefix= @exec_prefix@ 2367 # Install prefix for data files 2368 datarootdir= @datarootdir@ 2369 2370+# Locations needed for semi-native fixup of sysconfig. 2371+srcdir_b2h= @srcdir_b2h@ 2372+abs_srcdir_b2h= @abs_srcdir_b2h@ 2373+abs_builddir_b2h= @abs_builddir_b2h@ 2374+prefix_b2h= @prefix_b2h@ 2375+ 2376 # Expanded directories 2377 BINDIR= @bindir@ 2378 LIBDIR= @libdir@ 2379@@ -158,10 +166,12 @@ BINLIBDEST= @BINLIBDEST@ 2380 LIBDEST= $(SCRIPTDIR)/python$(VERSION) 2381 INCLUDEPY= $(INCLUDEDIR)/python$(LDVERSION) 2382 CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(LDVERSION) 2383+VENVLAUNCHERDIR= $(BINLIBDEST)/venv/scripts/nt 2384 2385 # Symbols used for using shared libraries 2386 SHLIB_SUFFIX= @SHLIB_SUFFIX@ 2387 EXT_SUFFIX= @EXT_SUFFIX@ 2388+PYD_PLATFORM_TAG = @PYD_PLATFORM_TAG@ 2389 LDSHARED= @LDSHARED@ $(PY_LDFLAGS) 2390 BLDSHARED= @BLDSHARED@ $(PY_CORE_LDFLAGS) 2391 LDCXXSHARED= @LDCXXSHARED@ 2392@@ -268,6 +278,8 @@ LIBRARY_DEPS= @LIBRARY_DEPS@ 2393 LINK_PYTHON_DEPS=@LINK_PYTHON_DEPS@ 2394 PY_ENABLE_SHARED= @PY_ENABLE_SHARED@ 2395 STATIC_LIBPYTHON= @STATIC_LIBPYTHON@ 2396+ABI3DLLLIBRARY= libpython3.dll 2397+ABI3LDLIBRARY= libpython3.dll.a 2398 2399 2400 LIBS= @LIBS@ 2401@@ -284,6 +296,7 @@ LIBOBJS= @LIBOBJS@ 2402 2403 PYTHON= python$(EXE) 2404 BUILDPYTHON= python$(BUILDEXE) 2405+BUILDPYTHONW= pythonw$(BUILDEXE) 2406 2407 HOSTRUNNER= @HOSTRUNNER@ 2408 2409@@ -344,6 +357,7 @@ IO_OBJS= \ 2410 ########################################################################## 2411 2412 LIBFFI_INCLUDEDIR= @LIBFFI_INCLUDEDIR@ 2413+NCURSESW_INCLUDEDIR= @NCURSESW_INCLUDEDIR@ 2414 2415 ########################################################################## 2416 # Parser 2417@@ -390,7 +404,7 @@ PYTHON_OBJS= \ 2418 Python/dynamic_annotations.o \ 2419 Python/errors.o \ 2420 Python/frame.o \ 2421- Python/frozenmain.o \ 2422+ @PYTHON_OBJS_FROZENMAIN@ \ 2423 Python/future.o \ 2424 Python/getargs.o \ 2425 Python/getcompiler.o \ 2426@@ -402,6 +416,7 @@ PYTHON_OBJS= \ 2427 Python/import.o \ 2428 Python/importdl.o \ 2429 Python/initconfig.o \ 2430+ Python/iscygpty.o \ 2431 Python/marshal.o \ 2432 Python/modsupport.o \ 2433 Python/mysnprintf.o \ 2434@@ -584,8 +599,8 @@ LIBEXPAT_HEADERS= \ 2435 2436 # Default target 2437 all: @DEF_MAKE_ALL_RULE@ 2438-build_all: check-clean-src $(BUILDPYTHON) platform oldsharedmods sharedmods \ 2439- gdbhooks Programs/_testembed python-config 2440+build_all: check-clean-src $(BUILDPYTHON) $(BUILDPYTHONW) platform oldsharedmods sharedmods \ 2441+ gdbhooks Programs/_testembed python-config $(ABI3DLLLIBRARY) $(ABI3LDLIBRARY) 2442 build_wasm: check-clean-src $(BUILDPYTHON) platform oldsharedmods python-config 2443 2444 # Check that the source is clean when building out of source. 2445@@ -700,9 +715,30 @@ coverage-report: regen-token regen-frozen 2446 clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c 2447 $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) 2448 2449+python_exe.o: $(srcdir)/PC/python_exe.rc 2450+ $(WINDRES) $(RCFLAGS) -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_exe.rc $@ 2451+ 2452+pythonw_exe.o: $(srcdir)/PC/pythonw_exe.rc 2453+ $(WINDRES) $(RCFLAGS) -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pythonw_exe.rc $@ 2454+ 2455+python_nt.o: $(srcdir)/PC/python_nt.rc 2456+ $(WINDRES) $(RCFLAGS) -DORIGINAL_FILENAME=\\\"$(DLLLIBRARY)\\\" -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_nt.rc $@ 2457+ 2458+python3dll_nt.o: $(srcdir)/PC/python_nt.rc 2459+ $(WINDRES) $(RCFLAGS) -DORIGINAL_FILENAME=\\\"$(ABI3DLLLIBRARY)\\\" -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_nt.rc $@ 2460+ 2461+venvlauncher.o: $(srcdir)/PC/pylauncher.rc 2462+ $(WINDRES) $(RCFLAGS) -DPY_ICON -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pylauncher.rc $@ 2463+ 2464+venvwlauncher.o: $(srcdir)/PC/pylauncher.rc 2465+ $(WINDRES) $(RCFLAGS) -DPYW_ICON -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pylauncher.rc $@ 2466+ 2467+$(BUILDPYTHONW): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) pythonw_exe.o 2468+ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -municode -mwindows -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) pythonw_exe.o 2469+ 2470 # Build the interpreter 2471-$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) 2472- $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) 2473+$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) python_exe.o 2474+ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -municode -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) python_exe.o 2475 2476 platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt 2477 $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform 2478@@ -806,13 +842,17 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \ 2479 2480 # This rule builds the Cygwin Python DLL and import library if configured 2481 # for a shared core library; otherwise, this rule is a noop. 2482-$(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS) 2483+$(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS) python_nt.o 2484 if test -n "$(DLLLIBRARY)"; then \ 2485 $(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \ 2486- $(LIBS) $(MODLIBS) $(SYSLIBS); \ 2487+ $(LIBS) $(LDFLAGS_NODIST) $(MODLIBS) $(SYSLIBS) python_nt.o; \ 2488 else true; \ 2489 fi 2490 2491+$(ABI3DLLLIBRARY) $(ABI3LDLIBRARY): python3dll_nt.o $(srcdir)/PC/launcher.c 2492+ $(LDSHARED) -DPYTHON_DLL_NAME=\"$(DLLLIBRARY)\" $(srcdir)/PC/python3dll.c -Wl,--out-implib=$(ABI3LDLIBRARY) -o $(ABI3DLLLIBRARY) python3dll_nt.o \ 2493+ $(LDFLAGS_NODIST); 2494+ 2495 # wasm32-emscripten browser build 2496 # wasm assets directory is relative to current build dir, e.g. "./usr/local". 2497 # --preload-file turns a relative asset path into an absolute path. 2498@@ -974,7 +1014,7 @@ BOOTSTRAP_HEADERS = \ 2499 Programs/_bootstrap_python.o: Programs/_bootstrap_python.c $(BOOTSTRAP_HEADERS) $(PYTHON_HEADERS) 2500 2501 _bootstrap_python: $(LIBRARY_OBJS_OMIT_FROZEN) Programs/_bootstrap_python.o Modules/getpath.o Modules/Setup.local 2502- $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ $(LIBRARY_OBJS_OMIT_FROZEN) \ 2503+ $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ -municode -mwindows $(LIBRARY_OBJS_OMIT_FROZEN) \ 2504 Programs/_bootstrap_python.o Modules/getpath.o $(LIBS) $(MODLIBS) $(SYSLIBS) 2505 2506 2507@@ -1276,9 +1316,15 @@ Python/dynload_hpux.o: $(srcdir)/Python/dynload_hpux.c Makefile 2508 -DSHLIB_EXT='"$(EXT_SUFFIX)"' \ 2509 -o $@ $(srcdir)/Python/dynload_hpux.c 2510 2511+Python/dynload_win.o: $(srcdir)/Python/dynload_win.c Makefile 2512+ $(CC) -c $(PY_CORE_CFLAGS) \ 2513+ -DPYD_PLATFORM_TAG='"$(PYD_PLATFORM_TAG)"' \ 2514+ -o $@ $(srcdir)/Python/dynload_win.c 2515+ 2516 Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h 2517 $(CC) -c $(PY_CORE_CFLAGS) \ 2518 -DABIFLAGS='"$(ABIFLAGS)"' \ 2519+ -DVPATH='"$(VPATH)"' \ 2520 $(MULTIARCH_CPPFLAGS) \ 2521 -o $@ $(srcdir)/Python/sysmodule.c 2522 2523@@ -1496,6 +1542,7 @@ PYTHON_HEADERS= \ 2524 $(srcdir)/Include/frameobject.h \ 2525 $(srcdir)/Include/import.h \ 2526 $(srcdir)/Include/intrcheck.h \ 2527+ $(srcdir)/Include/iscygpty.h \ 2528 $(srcdir)/Include/iterobject.h \ 2529 $(srcdir)/Include/listobject.h \ 2530 $(srcdir)/Include/longobject.h \ 2531@@ -1791,7 +1838,7 @@ $(DESTSHARED): 2532 # Install the interpreter with $(VERSION) affixed 2533 # This goes into $(exec_prefix) 2534 altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ 2535- @for i in $(BINDIR) $(LIBDIR); \ 2536+ @for i in $(BINDIR) $(LIBDIR) $(VENVLAUNCHERDIR); \ 2537 do \ 2538 if test ! -d $(DESTDIR)$$i; then \ 2539 echo "Creating directory $$i"; \ 2540@@ -1801,6 +1848,7 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ 2541 done 2542 if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ 2543 $(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ 2544+ $(INSTALL_PROGRAM) $(BUILDPYTHONW) $(DESTDIR)$(BINDIR)/python3w$(EXE); \ 2545 else \ 2546 $(INSTALL_PROGRAM) $(STRIPFLAG) Mac/pythonw $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ 2547 fi 2548@@ -1814,6 +1862,7 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ 2549 if test -f $(LDLIBRARY) && test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ 2550 if test -n "$(DLLLIBRARY)" ; then \ 2551 $(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \ 2552+ $(INSTALL_SHARED) $(ABI3DLLLIBRARY) $(DESTDIR)$(BINDIR); \ 2553 else \ 2554 $(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ 2555 if test $(LDLIBRARY) != $(INSTSONAME); then \ 2556@@ -1924,6 +1973,7 @@ LIBSUBDIRS= asyncio \ 2557 tkinter \ 2558 tomllib \ 2559 turtledemo \ 2560+ msilib \ 2561 unittest \ 2562 urllib \ 2563 venv venv/scripts venv/scripts/common venv/scripts/posix \ 2564@@ -2223,8 +2273,9 @@ libainstall: all python-config 2565 @if test "$(STATIC_LIBPYTHON)" = 1; then \ 2566 if test -d $(LIBRARY); then :; else \ 2567 if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ 2568- if test "$(SHLIB_SUFFIX)" = .dll; then \ 2569- $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \ 2570+ if test "$(SHLIB_SUFFIX)" = .dll -o "$(SHLIB_SUFFIX)" = .pyd; then \ 2571+ $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBDIR) ; \ 2572+ $(INSTALL_DATA) $(ABI3LDLIBRARY) $(DESTDIR)$(LIBDIR) ; \ 2573 else \ 2574 $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ 2575 fi; \ 2576@@ -2263,16 +2314,23 @@ libainstall: all python-config 2577 else true; \ 2578 fi 2579 2580+ifeq ($(shell uname -o),Msys) 2581+DESTDIRFINAL=$(DESTDIR) 2582+else 2583+DESTDIRFINAL=$(DESTDIR)/ 2584+endif 2585+ 2586 # Install the dynamically loadable modules 2587 # This goes into $(exec_prefix) 2588 sharedinstall: all 2589+ MSYS2_ARG_CONV_EXCL="--prefix=;--install-scripts=;--install-platlib=" \ 2590 $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \ 2591 --prefix=$(prefix) \ 2592 --install-scripts=$(BINDIR) \ 2593 --install-platlib=$(DESTSHARED) \ 2594- --root=$(DESTDIR)/ 2595- -rm $(DESTDIR)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py 2596- -rm -r $(DESTDIR)$(DESTSHARED)/__pycache__ 2597+ --root=$(DESTDIRFINAL) 2598+ -rm $(DESTDIRFINAL)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py 2599+ -rm -r $(DESTDIRFINAL)$(DESTSHARED)/__pycache__ 2600 2601 # Here are a couple of targets for MacOSX again, to install a full 2602 # framework-based Python. frameworkinstall installs everything, the 2603@@ -2464,7 +2522,7 @@ clean: clean-retain-profile 2604 fi 2605 2606 clobber: clean 2607- -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \ 2608+ -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY)$(ABI3LDLIBRARY) $(ABI3DLLLIBRARY) \ 2609 tags TAGS \ 2610 config.cache config.log pyconfig.h Modules/config.c 2611 -rm -rf build platform 2612diff --git a/Misc/NEWS.d/3.11.4.rst b/Misc/NEWS.d/3.11.4.rst 2613new file mode 100644 2614index 0000000..71ed43d 2615--- /dev/null 2616+++ b/Misc/NEWS.d/3.11.4.rst 2617@@ -0,0 +1,785 @@ 2618+.. date: 2023-06-01-03-24-58 2619+.. gh-issue: 103142 2620+.. nonce: GLWDMX 2621+.. release date: 2023-06-06 2622+.. section: Security 2623+ 2624+The version of OpenSSL used in our binary builds has been upgraded to 1.1.1u 2625+to address several CVEs. 2626+ 2627+.. 2628+ 2629+.. date: 2023-05-02-17-56-32 2630+.. gh-issue: 99889 2631+.. nonce: l664SU 2632+.. section: Security 2633+ 2634+Fixed a security in flaw in :func:`uu.decode` that could allow for directory 2635+traversal based on the input if no ``out_file`` was specified. 2636+ 2637+.. 2638+ 2639+.. date: 2023-05-01-15-03-25 2640+.. gh-issue: 104049 2641+.. nonce: b01Y3g 2642+.. section: Security 2643+ 2644+Do not expose the local on-disk location in directory indexes produced by 2645+:class:`http.client.SimpleHTTPRequestHandler`. 2646+ 2647+.. 2648+ 2649+.. date: 2023-03-07-20-59-17 2650+.. gh-issue: 102153 2651+.. nonce: 14CLSZ 2652+.. section: Security 2653+ 2654+:func:`urllib.parse.urlsplit` now strips leading C0 control and space 2655+characters following the specification for URLs defined by WHATWG in 2656+response to CVE-2023-24329. Patch by Illia Volochii. 2657+ 2658+.. 2659+ 2660+.. date: 2023-05-31-19-35-22 2661+.. gh-issue: 105164 2662+.. nonce: 6Wajph 2663+.. section: Core and Builtins 2664+ 2665+Ensure annotations are set up correctly if the only annotation in a block is 2666+within a :keyword:`match` block. Patch by Jelle Zijlstra. 2667+ 2668+.. 2669+ 2670+.. date: 2023-05-18-13-00-21 2671+.. gh-issue: 104615 2672+.. nonce: h_rtw2 2673+.. section: Core and Builtins 2674+ 2675+Fix wrong ordering of assignments in code like ``a, a = x, y``. Contributed 2676+by Carl Meyer. 2677+ 2678+.. 2679+ 2680+.. date: 2023-05-14-18-56-54 2681+.. gh-issue: 104482 2682+.. nonce: yaQsv8 2683+.. section: Core and Builtins 2684+ 2685+Fix three error handling bugs in ast.c's validation of pattern matching 2686+statements. 2687+ 2688+.. 2689+ 2690+.. date: 2023-05-13-06-22-52 2691+.. gh-issue: 102818 2692+.. nonce: HIX1Dr 2693+.. section: Core and Builtins 2694+ 2695+Do not add a frame to the traceback in the ``sys.setprofile`` and 2696+``sys.settrace`` trampoline functions. This ensures that frames are not 2697+duplicated if an exception is raised in the callback function, and ensures 2698+that frames are not omitted if a C callback is used and that does not add 2699+the frame. 2700+ 2701+.. 2702+ 2703+.. date: 2023-05-12-00-19-02 2704+.. gh-issue: 104405 2705+.. nonce: tXV5fn 2706+.. section: Core and Builtins 2707+ 2708+Fix an issue where some :term:`bytecode` instructions could ignore 2709+:pep:`523` when "inlining" calls. 2710+ 2711+.. 2712+ 2713+.. date: 2023-05-01-12-03-52 2714+.. gh-issue: 104018 2715+.. nonce: PFxGS4 2716+.. section: Core and Builtins 2717+ 2718+Disallow the "z" format specifier in %-format of bytes objects. 2719+ 2720+.. 2721+ 2722+.. date: 2023-04-28-18-57-13 2723+.. gh-issue: 103971 2724+.. nonce: Q3U9lv 2725+.. section: Core and Builtins 2726+ 2727+Fix an issue where incorrect locations numbers could be assigned to code 2728+following ``case`` blocks. 2729+ 2730+.. 2731+ 2732+.. date: 2023-04-21-17-03-14 2733+.. gh-issue: 102310 2734+.. nonce: anLjDx 2735+.. section: Core and Builtins 2736+ 2737+Change the error range for invalid bytes literals. 2738+ 2739+.. 2740+ 2741+.. date: 2023-04-21-16-12-41 2742+.. gh-issue: 103590 2743+.. nonce: 7DHDOE 2744+.. section: Core and Builtins 2745+ 2746+Do not wrap a single exception raised from a ``try-except*`` construct in an 2747+:exc:`ExceptionGroup`. 2748+ 2749+.. 2750+ 2751+.. date: 2023-04-14-22-35-23 2752+.. gh-issue: 101517 2753+.. nonce: 5EqM-S 2754+.. section: Core and Builtins 2755+ 2756+Fix bug in line numbers of instructions emitted for :keyword:`except* 2757+<except_star>`. 2758+ 2759+.. 2760+ 2761+.. date: 2023-04-08-17-13-07 2762+.. gh-issue: 103242 2763+.. nonce: ysI1b3 2764+.. section: Core and Builtins 2765+ 2766+Migrate :meth:`~ssl.SSLContext.set_ecdh_curve` method not to use deprecated 2767+OpenSSL APIs. Patch by Dong-hee Na. 2768+ 2769+.. 2770+ 2771+.. date: 2023-04-01-00-46-31 2772+.. gh-issue: 102700 2773+.. nonce: 493NB4 2774+.. section: Core and Builtins 2775+ 2776+Allow built-in modules to be submodules. This allows submodules to be 2777+statically linked into a CPython binary. 2778+ 2779+.. 2780+ 2781+.. date: 2023-02-12-22-40-22 2782+.. gh-issue: 101857 2783+.. nonce: _bribG 2784+.. section: Core and Builtins 2785+ 2786+Fix xattr support detection on Linux systems by widening the check to linux, 2787+not just glibc. This fixes support for musl. 2788+ 2789+.. 2790+ 2791+.. date: 2022-11-08-12-36-25 2792+.. gh-issue: 99184 2793+.. nonce: KIaqzz 2794+.. section: Core and Builtins 2795+ 2796+Bypass instance attribute access of ``__name__`` in ``repr`` of 2797+:class:`weakref.ref`. 2798+ 2799+.. 2800+ 2801+.. date: 2022-09-27-11-59-13 2802+.. gh-issue: 96670 2803+.. nonce: XrBBit 2804+.. section: Core and Builtins 2805+ 2806+The parser now raises :exc:`SyntaxError` when parsing source code containing 2807+null bytes. Backported from ``aab01e3``. Patch by Pablo Galindo 2808+ 2809+.. 2810+ 2811+.. bpo: 31821 2812+.. date: 2019-12-01-12-58-31 2813+.. nonce: 1FNmwk 2814+.. section: Core and Builtins 2815+ 2816+Fix :func:`!pause_reading` to work when called from :func:`!connection_made` 2817+in :mod:`asyncio`. 2818+ 2819+.. 2820+ 2821+.. date: 2023-06-02-02-38-26 2822+.. gh-issue: 105080 2823+.. nonce: 2imGMg 2824+.. section: Library 2825+ 2826+Fixed inconsistent signature on derived classes for 2827+:func:`inspect.signature` 2828+ 2829+.. 2830+ 2831+.. date: 2023-05-24-09-34-23 2832+.. gh-issue: 104874 2833+.. nonce: oqyJSy 2834+.. section: Library 2835+ 2836+Document the ``__name__`` and ``__supertype__`` attributes of 2837+:class:`typing.NewType`. Patch by Jelle Zijlstra. 2838+ 2839+.. 2840+ 2841+.. date: 2023-05-17-20-03-01 2842+.. gh-issue: 104340 2843+.. nonce: kp_XmX 2844+.. section: Library 2845+ 2846+When an ``asyncio`` pipe protocol loses its connection due to an error, and 2847+the caller doesn't await ``wait_closed()`` on the corresponding 2848+``StreamWriter``, don't log a warning about an exception that was never 2849+retrieved. After all, according to the ``StreamWriter.close()`` docs, the 2850+``wait_closed()`` call is optional ("not mandatory"). 2851+ 2852+.. 2853+ 2854+.. date: 2023-05-17-08-01-36 2855+.. gh-issue: 104372 2856+.. nonce: jpoWs6 2857+.. section: Library 2858+ 2859+Refactored the ``_posixsubprocess`` internals to avoid Python C API usage 2860+between fork and exec when marking ``pass_fds=`` file descriptors 2861+inheritable. 2862+ 2863+.. 2864+ 2865+.. date: 2023-05-16-11-02-44 2866+.. gh-issue: 75367 2867+.. nonce: qLWR35 2868+.. section: Library 2869+ 2870+Fix data descriptor detection in :func:`inspect.getattr_static`. 2871+ 2872+.. 2873+ 2874+.. date: 2023-05-16-10-07-16 2875+.. gh-issue: 104536 2876+.. nonce: hFWD8f 2877+.. section: Library 2878+ 2879+Fix a race condition in the internal :mod:`multiprocessing.process` cleanup 2880+logic that could manifest as an unintended ``AttributeError`` when calling 2881+``process.close()``. 2882+ 2883+.. 2884+ 2885+.. date: 2023-05-11-23-03-00 2886+.. gh-issue: 104399 2887+.. nonce: MMatTP 2888+.. section: Library 2889+ 2890+Prepare the ``_tkinter`` module for building with Tcl 9.0 and future 2891+libtommath by replacing usage of deprecated functions 2892+:c:func:`mp_to_unsigned_bin_n` and :c:func:`mp_unsigned_bin_size` when 2893+necessary. 2894+ 2895+.. 2896+ 2897+.. date: 2023-05-08-20-57-17 2898+.. gh-issue: 104307 2899+.. nonce: DSB93G 2900+.. section: Library 2901+ 2902+:func:`socket.getnameinfo` now releases the GIL while contacting the DNS 2903+server 2904+ 2905+.. 2906+ 2907+.. date: 2023-05-08-15-39-00 2908+.. gh-issue: 87695 2909+.. nonce: f6iO7v 2910+.. section: Library 2911+ 2912+Fix issue where :meth:`pathlib.Path.glob` raised :exc:`OSError` when it 2913+encountered a symlink to an overly long path. 2914+ 2915+.. 2916+ 2917+.. date: 2023-05-07-19-56-45 2918+.. gh-issue: 104265 2919+.. nonce: fVblry 2920+.. section: Library 2921+ 2922+Prevent possible crash by disallowing instantiation of the 2923+:class:`!_csv.Reader` and :class:`!_csv.Writer` types. The regression was 2924+introduced in 3.10.0a4 with PR 23224 (:issue:`14935`). Patch by Radislav 2925+Chugunov. 2926+ 2927+.. 2928+ 2929+.. date: 2023-05-01-16-43-28 2930+.. gh-issue: 104035 2931+.. nonce: MrJBw8 2932+.. section: Library 2933+ 2934+Do not ignore user-defined ``__getstate__`` and ``__setstate__`` methods for 2935+slotted frozen dataclasses. 2936+ 2937+.. 2938+ 2939+.. date: 2023-04-29-18-23-16 2940+.. gh-issue: 103987 2941+.. nonce: sRgALL 2942+.. section: Library 2943+ 2944+In :mod:`mmap`, fix several bugs that could lead to access to memory-mapped 2945+files after they have been invalidated. 2946+ 2947+.. 2948+ 2949+.. date: 2023-04-27-20-03-08 2950+.. gh-issue: 103935 2951+.. nonce: Uaf2M0 2952+.. section: Library 2953+ 2954+Use :func:`io.open_code` for files to be executed instead of raw 2955+:func:`open` 2956+ 2957+.. 2958+ 2959+.. date: 2023-04-27-00-45-41 2960+.. gh-issue: 100370 2961+.. nonce: MgZ3KY 2962+.. section: Library 2963+ 2964+Fix potential :exc:`OverflowError` in :meth:`sqlite3.Connection.blobopen` 2965+for 32-bit builds. Patch by Erlend E. Aasland. 2966+ 2967+.. 2968+ 2969+.. date: 2023-04-26-09-54-25 2970+.. gh-issue: 103848 2971+.. nonce: aDSnpR 2972+.. section: Library 2973+ 2974+Add checks to ensure that ``[`` bracketed ``]`` hosts found by 2975+:func:`urllib.parse.urlsplit` are of IPv6 or IPvFuture format. 2976+ 2977+.. 2978+ 2979+.. date: 2023-04-26-09-38-47 2980+.. gh-issue: 103872 2981+.. nonce: 8LBsDz 2982+.. section: Library 2983+ 2984+Update the bundled copy of pip to version 23.1.2. 2985+ 2986+.. 2987+ 2988+.. date: 2023-04-25-19-58-13 2989+.. gh-issue: 103861 2990+.. nonce: JeozgD 2991+.. section: Library 2992+ 2993+Fix ``zipfile.Zipfile`` creating invalid zip files when ``force_zip64`` was 2994+used to add files to them. Patch by Carey Metcalfe. 2995+ 2996+.. 2997+ 2998+.. date: 2023-04-24-00-34-23 2999+.. gh-issue: 103685 3000+.. nonce: U14jBM 3001+.. section: Library 3002+ 3003+Prepare :meth:`tkinter.Menu.index` for Tk 8.7 so that it does not raise 3004+``TclError: expected integer but got ""`` when it should return ``None``. 3005+ 3006+.. 3007+ 3008+.. date: 2023-04-22-22-14-09 3009+.. gh-issue: 81403 3010+.. nonce: zVz9Td 3011+.. section: Library 3012+ 3013+:class:`urllib.request.CacheFTPHandler` no longer raises :class:`URLError` 3014+if a cached FTP instance is reused. ftplib's endtransfer method calls 3015+voidresp to drain the connection to handle FTP instance reuse properly. 3016+ 3017+.. 3018+ 3019+.. date: 2023-04-16-18-29-04 3020+.. gh-issue: 103578 3021+.. nonce: fly1wc 3022+.. section: Library 3023+ 3024+Fixed a bug where :mod:`pdb` crashes when reading source file with different 3025+encoding by replacing :func:`io.open` with :func:`io.open_code`. The new 3026+method would also call into the hook set by :func:`PyFile_SetOpenCodeHook`. 3027+ 3028+.. 3029+ 3030+.. date: 2023-04-15-12-19-14 3031+.. gh-issue: 103556 3032+.. nonce: TEf-2m 3033+.. section: Library 3034+ 3035+Now creating :class:`inspect.Signature` objects with positional-only 3036+parameter with a default followed by a positional-or-keyword parameter 3037+without one is impossible. 3038+ 3039+.. 3040+ 3041+.. date: 2023-04-15-11-21-38 3042+.. gh-issue: 103559 3043+.. nonce: a9rYHG 3044+.. section: Library 3045+ 3046+Update the bundled copy of pip to version 23.1.1. 3047+ 3048+.. 3049+ 3050+.. date: 2023-04-12-17-59-55 3051+.. gh-issue: 103365 3052+.. nonce: UBEE0U 3053+.. section: Library 3054+ 3055+Set default Flag boundary to ``STRICT`` and fix bitwise operations. 3056+ 3057+.. 3058+ 3059+.. date: 2023-04-12-13-04-16 3060+.. gh-issue: 103472 3061+.. nonce: C6bOHv 3062+.. section: Library 3063+ 3064+Avoid a potential :exc:`ResourceWarning` in 3065+:class:`http.client.HTTPConnection` by closing the proxy / tunnel's CONNECT 3066+response explicitly. 3067+ 3068+.. 3069+ 3070+.. date: 2023-04-11-21-38-39 3071+.. gh-issue: 103449 3072+.. nonce: -nxmhb 3073+.. section: Library 3074+ 3075+Fix a bug in doc string generation in :func:`dataclasses.dataclass`. 3076+ 3077+.. 3078+ 3079+.. date: 2023-04-06-17-28-36 3080+.. gh-issue: 103256 3081+.. nonce: 1syxfs 3082+.. section: Library 3083+ 3084+Fixed a bug that caused :mod:`hmac` to raise an exception when the requested 3085+hash algorithm was not available in OpenSSL despite being available 3086+separately as part of ``hashlib`` itself. It now falls back properly to the 3087+built-in. This could happen when, for example, your OpenSSL does not include 3088+SHA3 support and you want to compute ``hmac.digest(b'K', b'M', 3089+'sha3_256')``. 3090+ 3091+.. 3092+ 3093+.. date: 2023-04-05-01-28-53 3094+.. gh-issue: 103225 3095+.. nonce: QD3JVU 3096+.. section: Library 3097+ 3098+Fix a bug in :mod:`pdb` when displaying line numbers of module-level source 3099+code. 3100+ 3101+.. 3102+ 3103+.. date: 2023-04-04-12-43-38 3104+.. gh-issue: 93910 3105+.. nonce: jurMzv 3106+.. section: Library 3107+ 3108+Remove deprecation of enum ``memmber.member`` access. 3109+ 3110+.. 3111+ 3112+.. date: 2023-04-03-23-44-34 3113+.. gh-issue: 102978 3114+.. nonce: gy9eVk 3115+.. section: Library 3116+ 3117+Fixes :func:`unittest.mock.patch` not enforcing function signatures for 3118+methods decorated with ``@classmethod`` or ``@staticmethod`` when patch is 3119+called with ``autospec=True``. 3120+ 3121+.. 3122+ 3123+.. date: 2023-04-02-23-05-22 3124+.. gh-issue: 103204 3125+.. nonce: bbDmu0 3126+.. section: Library 3127+ 3128+Fixes :mod:`http.server` accepting HTTP requests with HTTP version numbers 3129+preceded by '+', or '-', or with digit-separating '_' characters. The 3130+length of the version numbers is also constrained. 3131+ 3132+.. 3133+ 3134+.. date: 2023-03-23-15-24-38 3135+.. gh-issue: 102953 3136+.. nonce: YR4KaK 3137+.. section: Library 3138+ 3139+The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`, 3140+have a new a *filter* argument that allows limiting tar features than may be 3141+surprising or dangerous, such as creating files outside the destination 3142+directory. See :ref:`tarfile-extraction-filter` for details. 3143+ 3144+.. 3145+ 3146+.. date: 2023-02-09-22-24-34 3147+.. gh-issue: 101640 3148+.. nonce: oFuEpB 3149+.. section: Library 3150+ 3151+:class:`argparse.ArgumentParser` now catches errors when writing messages, 3152+such as when :data:`sys.stderr` is ``None``. Patch by Oleg Iarygin. 3153+ 3154+.. 3155+ 3156+.. date: 2022-09-07-09-32-07 3157+.. gh-issue: 96522 3158+.. nonce: t73oqp 3159+.. section: Library 3160+ 3161+Fix potential deadlock in pty.spawn() 3162+ 3163+.. 3164+ 3165+.. date: 2022-08-27-21-41-41 3166+.. gh-issue: 87474 3167+.. nonce: 9X-kxt 3168+.. section: Library 3169+ 3170+Fix potential file descriptor leaks in :class:`subprocess.Popen`. 3171+ 3172+.. 3173+ 3174+.. date: 2023-05-28-21-01-00 3175+.. gh-issue: 89455 3176+.. nonce: qAKRrA 3177+.. section: Documentation 3178+ 3179+Add missing documentation for the ``max_group_depth`` and 3180+``max_group_width`` parameters and the ``exceptions`` attribute of the 3181+:class:`traceback.TracebackException` class. 3182+ 3183+.. 3184+ 3185+.. date: 2023-05-28-19-08-42 3186+.. gh-issue: 89412 3187+.. nonce: j4cg7K 3188+.. section: Documentation 3189+ 3190+Add missing documentation for the ``end_lineno`` and ``end_offset`` 3191+attributes of the :class:`traceback.TracebackException` class. 3192+ 3193+.. 3194+ 3195+.. date: 2023-05-25-22-34-31 3196+.. gh-issue: 104943 3197+.. nonce: J2v1Pc 3198+.. section: Documentation 3199+ 3200+Remove mentions of old Python versions in :class:`typing.NamedTuple`. 3201+ 3202+.. 3203+ 3204+.. date: 2023-05-14-12-11-28 3205+.. gh-issue: 67056 3206+.. nonce: nVC2Rf 3207+.. section: Documentation 3208+ 3209+Document that the effect of registering or unregistering an :mod:`atexit` 3210+cleanup function from within a registered cleanup function is undefined. 3211+ 3212+.. 3213+ 3214+.. date: 2023-04-25-22-58-08 3215+.. gh-issue: 48241 3216+.. nonce: l1Gxxh 3217+.. section: Documentation 3218+ 3219+Clarifying documentation about the url parameter to urllib.request.urlopen 3220+and urllib.request.Requst needing to be encoded properly. 3221+ 3222+.. 3223+ 3224+.. date: 2023-05-15-02-22-44 3225+.. gh-issue: 104494 3226+.. nonce: Bkrbfn 3227+.. section: Tests 3228+ 3229+Update ``test_pack_configure_in`` and ``test_place_configure_in`` for 3230+changes to error message formatting in Tk 8.7. 3231+ 3232+.. 3233+ 3234+.. date: 2023-05-14-03-00-00 3235+.. gh-issue: 104461 3236+.. nonce: Rmex11 3237+.. section: Tests 3238+ 3239+Run test_configure_screen on X11 only, since the ``DISPLAY`` environment 3240+variable and ``-screen`` option for toplevels are not useful on Tk for Win32 3241+or Aqua. 3242+ 3243+.. 3244+ 3245+.. date: 2023-04-08-00-50-23 3246+.. gh-issue: 103329 3247+.. nonce: M38tqF 3248+.. section: Tests 3249+ 3250+Regression tests for the behaviour of ``unittest.mock.PropertyMock`` were 3251+added. 3252+ 3253+.. 3254+ 3255+.. date: 2023-02-11-22-36-10 3256+.. gh-issue: 85984 3257+.. nonce: EVXjT9 3258+.. section: Tests 3259+ 3260+Utilize new "winsize" functions from termios in pty tests. 3261+ 3262+.. 3263+ 3264+.. date: 2022-11-06-18-42-38 3265+.. gh-issue: 75729 3266+.. nonce: uGYJrv 3267+.. section: Tests 3268+ 3269+Fix the :func:`os.spawn* <os.spawnl>` tests failing on Windows when the 3270+working directory or interpreter path contains spaces. 3271+ 3272+.. 3273+ 3274+.. date: 2023-06-06-09-08-10 3275+.. gh-issue: 90005 3276+.. nonce: 8mmeJQ 3277+.. section: Build 3278+ 3279+Fix a regression in :file:`configure` where we could end up unintentionally 3280+linking with ``libbsd``. 3281+ 3282+.. 3283+ 3284+.. date: 2023-05-04-10-56-14 3285+.. gh-issue: 104106 3286+.. nonce: -W9BJS 3287+.. section: Build 3288+ 3289+Add gcc fallback of mkfifoat/mknodat for macOS. Patch by Dong-hee Na. 3290+ 3291+.. 3292+ 3293+.. date: 2023-02-11-05-31-05 3294+.. gh-issue: 99069 3295+.. nonce: X4LDvY 3296+.. section: Build 3297+ 3298+Extended workaround defining ``static_assert`` when missing from the libc 3299+headers to all clang and gcc builds. In particular, this fixes building on 3300+macOS <= 10.10. 3301+ 3302+.. 3303+ 3304+.. date: 2023-05-31-16-14-31 3305+.. gh-issue: 105146 3306+.. nonce: gNjqq8 3307+.. section: Windows 3308+ 3309+Updated the links at the end of the installer to point to Discourse rather 3310+than the mailing lists. 3311+ 3312+.. 3313+ 3314+.. date: 2023-05-18-22-46-03 3315+.. gh-issue: 104623 3316+.. nonce: HJZhm1 3317+.. section: Windows 3318+ 3319+Update Windows installer to use SQLite 3.42.0. 3320+ 3321+.. 3322+ 3323+.. date: 2023-03-24-11-25-28 3324+.. gh-issue: 102997 3325+.. nonce: dredy2 3326+.. section: Windows 3327+ 3328+Update Windows installer to use SQLite 3.41.2. 3329+ 3330+.. 3331+ 3332+.. date: 2023-03-18-21-38-00 3333+.. gh-issue: 88013 3334+.. nonce: Z3loxC 3335+.. section: Windows 3336+ 3337+Fixed a bug where :exc:`TypeError` was raised when calling 3338+:func:`ntpath.realpath` with a bytes parameter in some cases. 3339+ 3340+.. 3341+ 3342+.. date: 2023-05-30-23-30-46 3343+.. gh-issue: 103142 3344+.. nonce: 55lMXQ 3345+.. section: macOS 3346+ 3347+Update macOS installer to use OpenSSL 1.1.1u. 3348+ 3349+.. 3350+ 3351+.. date: 2023-05-18-22-31-49 3352+.. gh-issue: 104623 3353+.. nonce: 6h7Xfx 3354+.. section: macOS 3355+ 3356+Update macOS installer to SQLite 3.42.0. 3357+ 3358+.. 3359+ 3360+.. date: 2023-03-24-11-20-47 3361+.. gh-issue: 102997 3362+.. nonce: ZgQkbq 3363+.. section: macOS 3364+ 3365+Update macOS installer to SQLite 3.41.2. 3366+ 3367+.. 3368+ 3369+.. date: 2023-05-23-17-19-49 3370+.. gh-issue: 104719 3371+.. nonce: rvYXH- 3372+.. section: IDLE 3373+ 3374+Remove IDLE's modification of tokenize.tabsize and test other uses of 3375+tokenize data and methods. 3376+ 3377+.. 3378+ 3379+.. date: 2023-05-17-17-32-21 3380+.. gh-issue: 104499 3381+.. nonce: hNeqV4 3382+.. section: IDLE 3383+ 3384+Fix completions for Tk Aqua 8.7 (currently blank). 3385+ 3386+.. 3387+ 3388+.. date: 2023-05-17-15-11-11 3389+.. gh-issue: 104496 3390+.. nonce: wjav-y 3391+.. section: IDLE 3392+ 3393+About prints both tcl and tk versions if different (expected someday). 3394+ 3395+.. 3396+ 3397+.. date: 2023-04-30-20-01-18 3398+.. gh-issue: 88496 3399+.. nonce: y65vUb 3400+.. section: IDLE 3401+ 3402+Fix IDLE test hang on macOS. 3403diff --git a/Misc/config_mingw b/Misc/config_mingw 3404new file mode 100644 3405index 0000000..9be43fd 3406--- /dev/null 3407+++ b/Misc/config_mingw 3408@@ -0,0 +1,15 @@ 3409+# configure defaults for mingw* hosts 3410+ 3411+# mingw functions to ignore 3412+ac_cv_func_ftruncate=ignore # implement it as _chsize 3413+ 3414+# mingw-w64 functions to ignore 3415+ac_cv_func_truncate=ignore 3416+ac_cv_func_alarm=ignore 3417+ 3418+# files to ignore 3419+ac_cv_file__dev_ptmx=ignore #NOTE: under MSYS environment device exist 3420+ac_cv_file__dev_ptc=no 3421+ 3422+# force detection of winsock2 functionality - require wxp or newer 3423+ac_cv_func_getpeername=yes 3424diff --git a/Misc/cross_mingw32 b/Misc/cross_mingw32 3425new file mode 100644 3426index 0000000..03fde9e 3427--- /dev/null 3428+++ b/Misc/cross_mingw32 3429@@ -0,0 +1,11 @@ 3430+# configure defaults for mingw32 host if cross-build 3431+ 3432+ac_cv_little_endian_double=yes 3433+ac_cv_big_endian_double=no 3434+ac_cv_mixed_endian_double=no 3435+ 3436+ac_cv_tanh_preserves_zero_sign=yes 3437+ 3438+ac_cv_wchar_t_signed=no 3439+ 3440+ac_cv_have_size_t_format=no 3441diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in 3442index 2602fe2..e0e048a 100644 3443--- a/Misc/python-config.sh.in 3444+++ b/Misc/python-config.sh.in 3445@@ -1,32 +1,44 @@ 3446 #!/bin/sh 3447 3448-# Keep this script in sync with python-config.in 3449- 3450 exit_with_usage () 3451 { 3452 echo "Usage: $0 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir|--embed" 3453- exit $1 3454+ exit 1 3455 } 3456 3457+# Really, python-config.py (and thus .sh) should be called directly, but 3458+# sometimes software (e.g. GDB) calls python-config.sh as if it were the 3459+# Python executable, passing python-config.py as the first argument. 3460+# Work around that oddness by ignoring any .py passed as first arg. 3461+case "$1" in 3462+ *.py) 3463+ shift 3464+ ;; 3465+esac 3466+ 3467 if [ "$1" = "" ] ; then 3468- exit_with_usage 1 3469+ exit_with_usage 3470 fi 3471 3472 # Returns the actual prefix where this script was installed to. 3473 installed_prefix () 3474 { 3475- RESULT=$(dirname $(cd $(dirname "$1") && pwd -P)) 3476- if which readlink >/dev/null 2>&1 ; then 3477- if readlink -f "$RESULT" >/dev/null 2>&1; then 3478- RESULT=$(readlink -f "$RESULT") 3479- fi 3480+ local RESULT=$(dirname $(cd $(dirname "$1") && pwd -P)) 3481+ if [ $(which readlink) ] ; then 3482+ RESULT=$(readlink -f "$RESULT") 3483+ fi 3484+ # Since we don't know where the output from this script will end up 3485+ # we keep all paths in Windows-land since MSYS2 can handle that 3486+ # while native tools can't handle paths in MSYS2-land. 3487+ if [ "$OSTYPE" = "msys" ]; then 3488+ RESULT=$(cd "$RESULT" && pwd -W) 3489 fi 3490 echo $RESULT 3491 } 3492 3493 prefix_real=$(installed_prefix "$0") 3494 3495-# Use sed to fix paths from their built-to locations to their installed-to 3496+# Use sed to fix paths from their built-to locations to their installed to 3497 # locations. Keep prefix & exec_prefix using their original values in case 3498 # they are referenced in other configure variables, to prevent double 3499 # substitution, issue #22140. 3500@@ -41,13 +53,17 @@ LIBM="@LIBM@" 3501 LIBC="@LIBC@" 3502 SYSLIBS="$LIBM $LIBC" 3503 ABIFLAGS="@ABIFLAGS@" 3504+# Protect against lack of substitution. 3505+if [ "$ABIFLAGS" = "@""ABIFLAGS""@" ] ; then 3506+ ABIFLAGS= 3507+fi 3508 LIBS="@LIBPYTHON@ @LIBS@ $SYSLIBS" 3509 LIBS_EMBED="-lpython${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS" 3510 BASECFLAGS="@BASECFLAGS@" 3511-LDLIBRARY="@LDLIBRARY@" 3512 OPT="@OPT@" 3513 PY_ENABLE_SHARED="@PY_ENABLE_SHARED@" 3514 LDVERSION="@LDVERSION@" 3515+LDLIBRARY="@LDLIBRARY@" 3516 LIBDEST=${prefix_real}/lib/python${VERSION} 3517 LIBPL=$(echo "@LIBPL@" | sed "s#$prefix#$prefix_real#") 3518 SO="@EXT_SUFFIX@" 3519@@ -61,7 +77,7 @@ for ARG in $* 3520 do 3521 case $ARG in 3522 --help) 3523- exit_with_usage 0 3524+ exit_with_usage 3525 ;; 3526 --embed) 3527 PY_EMBED=1 3528@@ -69,7 +85,7 @@ do 3529 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--abiflags|--configdir) 3530 ;; 3531 *) 3532- exit_with_usage 1 3533+ exit_with_usage 3534 ;; 3535 esac 3536 done 3537@@ -80,37 +96,37 @@ fi 3538 3539 for ARG in "$@" 3540 do 3541- case "$ARG" in 3542+ case $ARG in 3543 --prefix) 3544- echo "$prefix_real" 3545+ echo -ne "$prefix_real" 3546 ;; 3547 --exec-prefix) 3548- echo "$exec_prefix_real" 3549+ echo -ne "$exec_prefix_real " 3550 ;; 3551 --includes) 3552- echo "$INCDIR $PLATINCDIR" 3553+ echo -ne "$INCDIR $PLATINCDIR" 3554 ;; 3555 --cflags) 3556- echo "$INCDIR $PLATINCDIR $BASECFLAGS $CFLAGS $OPT" 3557+ echo -ne "$INCDIR $PLATINCDIR $BASECFLAGS $CFLAGS $OPT" 3558 ;; 3559 --libs) 3560- echo "$LIBS" 3561+ echo -ne "$LIBS" 3562 ;; 3563 --ldflags) 3564 LIBPLUSED= 3565 if [ "$PY_ENABLE_SHARED" = "0" ] ; then 3566 LIBPLUSED="-L$LIBPL" 3567 fi 3568- echo "$LIBPLUSED -L$libdir $LIBS" 3569+ echo -ne "$LIBPLUSED -L$libdir $LIBS " 3570 ;; 3571 --extension-suffix) 3572- echo "$SO" 3573+ echo -ne "$SO " 3574 ;; 3575 --abiflags) 3576- echo "$ABIFLAGS" 3577+ echo -ne "$ABIFLAGS " 3578 ;; 3579 --configdir) 3580- echo "$LIBPL" 3581+ echo -ne "$LIBPL " 3582 ;; 3583 esac 3584 done 3585diff --git a/Misc/python.pc.in b/Misc/python.pc.in 3586index 87e04de..3900190 100644 3587--- a/Misc/python.pc.in 3588+++ b/Misc/python.pc.in 3589@@ -9,5 +9,5 @@ Description: Build a C extension for Python 3590 Requires: 3591 Version: @VERSION@ 3592 Libs.private: @LIBS@ 3593-Libs: 3594+Libs: -L${libdir} -lpython@VERSION@@ABIFLAGS@ 3595 Cflags: -I${includedir}/python@VERSION@@ABIFLAGS@ 3596diff --git a/Modules/Setup.bootstrap.in b/Modules/Setup.bootstrap.in 3597index e3e9b96..6986290 100644 3598--- a/Modules/Setup.bootstrap.in 3599+++ b/Modules/Setup.bootstrap.in 3600@@ -8,15 +8,15 @@ 3601 # module C APIs are used in core 3602 atexit atexitmodule.c 3603 faulthandler faulthandler.c 3604-posix posixmodule.c 3605-_signal signalmodule.c 3606+@INITSYS@ posixmodule.c 3607+_signal signalmodule.c -lws2_32 3608 _tracemalloc _tracemalloc.c 3609 3610 # modules used by importlib, deepfreeze, freeze, runpy, and sysconfig 3611 _codecs _codecsmodule.c 3612 _collections _collectionsmodule.c 3613 errno errnomodule.c 3614-_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c 3615+_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c _io/winconsoleio.c 3616 itertools itertoolsmodule.c 3617 _sre _sre/sre.c 3618 _thread _threadmodule.c 3619@@ -33,3 +33,8 @@ _symtable symtablemodule.c 3620 3621 # for systems without $HOME env, used by site._getuserbase() 3622 @MODULE_PWD_TRUE@pwd pwdmodule.c 3623+ 3624+# build-in modules for windows platform: 3625+@USE_WIN32_MODULE@winreg ../PC/winreg.c 3626+@MODULE_MSVCRT_TRUE@msvcrt -DPy_BUILD_CORE ../PC/msvcrtmodule.c 3627+@MODULE__WINAPI_TRUE@_winapi _winapi.c 3628diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c 3629index fc73264..6ed71fa 100644 3630--- a/Modules/_ctypes/_ctypes.c 3631+++ b/Modules/_ctypes/_ctypes.c 3632@@ -3403,6 +3403,18 @@ static PPROC FindAddress(void *handle, const char *name, PyObject *type) 3633 mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */ 3634 if (!mangled_name) 3635 return NULL; 3636+ /* Issue: for stdcall decorated export functions MSVC compiler adds 3637+ * underscore, but GCC compiler create them without. This is 3638+ * visible by example for _ctypes_test.pyd module. 3639+ * As well functions from system libraries are without underscore. 3640+ * Solutions: 3641+ * - If a python module is build with gcc option --add-stdcall-alias 3642+ * the module will contain XXX as alias for function XXX@ as result 3643+ * first search in this method will succeed. 3644+ * - Distutil may use compiler to create def-file, to modify it as 3645+ * add underscore alias and with new def file to create module. 3646+ * - Or may be just to search for function without underscore. 3647+ */ 3648 for (i = 0; i < 32; ++i) { 3649 sprintf(mangled_name, "_%s@%d", name, i*4); 3650 Py_BEGIN_ALLOW_THREADS 3651@@ -3410,6 +3422,13 @@ static PPROC FindAddress(void *handle, const char *name, PyObject *type) 3652 Py_END_ALLOW_THREADS 3653 if (address) 3654 return address; 3655+ /* search for function without underscore as weel */ 3656+ sprintf(mangled_name, "%s@%d", name, i*4); 3657+ Py_BEGIN_ALLOW_THREADS 3658+ address = (PPROC)GetProcAddress(handle, mangled_name); 3659+ Py_END_ALLOW_THREADS 3660+ if (address) 3661+ return address; 3662 } 3663 return NULL; 3664 #endif 3665diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c 3666index e6440fa..f42714a 100644 3667--- a/Modules/_gdbmmodule.c 3668+++ b/Modules/_gdbmmodule.c 3669@@ -12,7 +12,7 @@ 3670 #include <sys/stat.h> 3671 #include <sys/types.h> 3672 3673-#if defined(WIN32) && !defined(__CYGWIN__) 3674+#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__) 3675 #include "gdbmerrno.h" 3676 extern const char * gdbm_strerror(gdbm_error); 3677 #endif 3678diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c 3679index 4496609..80cc6f9 100644 3680--- a/Modules/_io/fileio.c 3681+++ b/Modules/_io/fileio.c 3682@@ -20,6 +20,7 @@ 3683 #endif 3684 #include <stddef.h> /* For offsetof */ 3685 #include "_iomodule.h" 3686+#include "iscygpty.h" 3687 3688 /* 3689 * Known likely problems: 3690@@ -1129,7 +1130,7 @@ _io_FileIO_isatty_impl(fileio *self) 3691 return err_closed(); 3692 Py_BEGIN_ALLOW_THREADS 3693 _Py_BEGIN_SUPPRESS_IPH 3694- res = isatty(self->fd); 3695+ res = isatty(self->fd) || is_cygpty(self->fd); 3696 _Py_END_SUPPRESS_IPH 3697 Py_END_ALLOW_THREADS 3698 return PyBool_FromLong(res); 3699diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c 3700index 23c38e1..dfb6c7e 100644 3701--- a/Modules/_localemodule.c 3702+++ b/Modules/_localemodule.c 3703@@ -12,6 +12,13 @@ This software comes with no warranty. Use at your own risk. 3704 #define PY_SSIZE_T_CLEAN 3705 #include "Python.h" 3706 #include "pycore_fileutils.h" 3707+#ifdef __MINGW32__ 3708+/* The header libintl.h and library libintl may exist on mingw host. 3709+ * To be compatible with MSVC build we has to undef some defines. 3710+ */ 3711+#undef HAVE_LIBINTL_H 3712+#undef HAVE_BIND_TEXTDOMAIN_CODESET 3713+#endif 3714 3715 #include <stdio.h> 3716 #include <locale.h> 3717diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c 3718index 0809c24..bbb1b38 100644 3719--- a/Modules/_multiprocessing/multiprocessing.c 3720+++ b/Modules/_multiprocessing/multiprocessing.c 3721@@ -172,7 +172,7 @@ static PyMethodDef module_methods[] = { 3722 _MULTIPROCESSING_RECV_METHODDEF 3723 _MULTIPROCESSING_SEND_METHODDEF 3724 #endif 3725-#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) 3726+#if defined(MS_WINDOWS) || (!defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)) 3727 _MULTIPROCESSING_SEM_UNLINK_METHODDEF 3728 #endif 3729 {NULL} 3730diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h 3731index 3a8314b..c07cfe8 100644 3732--- a/Modules/_multiprocessing/multiprocessing.h 3733+++ b/Modules/_multiprocessing/multiprocessing.h 3734@@ -21,7 +21,10 @@ 3735 # endif 3736 # define SEM_HANDLE HANDLE 3737 # define SEM_VALUE_MAX LONG_MAX 3738-# define HAVE_MP_SEMAPHORE 3739+# define HAVE_MP_SEMAPHORE 3740+# if defined(HAVE_SEM_OPEN) && defined(_POSIX_THREADS) 3741+# include <semaphore.h> 3742+# endif 3743 #else 3744 # include <fcntl.h> /* O_CREAT and O_EXCL */ 3745 # if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) 3746diff --git a/Modules/_winapi.c b/Modules/_winapi.c 3747index f6bb07f..56f3306 100644 3748--- a/Modules/_winapi.c 3749+++ b/Modules/_winapi.c 3750@@ -41,7 +41,9 @@ 3751 3752 #define WINDOWS_LEAN_AND_MEAN 3753 #include "windows.h" 3754+#if defined(Py_DEBUG) 3755 #include <crtdbg.h> 3756+#endif 3757 #include "winreparse.h" 3758 3759 #if defined(MS_WIN32) && !defined(MS_WIN64) 3760@@ -957,7 +959,7 @@ getattributelist(PyObject *obj, const char *name, AttributeList *attribute_list) 3761 DWORD err; 3762 BOOL result; 3763 PyObject *value; 3764- Py_ssize_t handle_list_size; 3765+ Py_ssize_t handle_list_size = 0; 3766 DWORD attribute_count = 0; 3767 SIZE_T attribute_list_size = 0; 3768 3769diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c 3770index e5b96be..0e5ab45 100644 3771--- a/Modules/_xxsubinterpretersmodule.c 3772+++ b/Modules/_xxsubinterpretersmodule.c 3773@@ -1765,7 +1765,7 @@ PyDoc_STRVAR(channelid_doc, 3774 "A channel ID identifies a channel and may be used as an int."); 3775 3776 static PyTypeObject ChannelIDtype = { 3777- PyVarObject_HEAD_INIT(&PyType_Type, 0) 3778+ PyVarObject_HEAD_INIT(NULL, 0) 3779 "_xxsubinterpreters.ChannelID", /* tp_name */ 3780 sizeof(channelid), /* tp_basicsize */ 3781 0, /* tp_itemsize */ 3782diff --git a/Modules/getpath.c b/Modules/getpath.c 3783index bc730fc..0419c2a 100644 3784--- a/Modules/getpath.c 3785+++ b/Modules/getpath.c 3786@@ -54,6 +54,25 @@ 3787 3788 /* HELPER FUNCTIONS for getpath.py */ 3789 3790+static PyObject * 3791+getpath_normpath(PyObject *Py_UNUSED(self), PyObject *args) 3792+{ 3793+ PyObject *r = NULL; 3794+ PyObject *pathobj; 3795+ wchar_t *path; 3796+ if (!PyArg_ParseTuple(args, "U", &pathobj)) { 3797+ return NULL; 3798+ } 3799+ Py_ssize_t len; 3800+ wchar_t *buffer = PyUnicode_AsWideCharString(pathobj, &len); 3801+ if (!buffer) { 3802+ return NULL; 3803+ } 3804+ r = PyUnicode_FromWideChar(_Py_normpath(buffer, len), -1); 3805+ PyMem_Free(buffer); 3806+ return r; 3807+} 3808+ 3809 static PyObject * 3810 getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args) 3811 { 3812@@ -88,6 +107,12 @@ getpath_basename(PyObject *Py_UNUSED(self), PyObject *args) 3813 } 3814 Py_ssize_t end = PyUnicode_GET_LENGTH(path); 3815 Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1); 3816+#ifdef ALTSEP 3817+ if (pos < 0) { 3818+ // try using altsep 3819+ pos = PyUnicode_FindChar(path, ALTSEP, 0, end, -1); 3820+ } 3821+#endif 3822 if (pos < 0) { 3823 return Py_NewRef(path); 3824 } 3825@@ -104,6 +129,12 @@ getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args) 3826 } 3827 Py_ssize_t end = PyUnicode_GET_LENGTH(path); 3828 Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1); 3829+#ifdef ALTSEP 3830+ if (pos < 0) { 3831+ // try using altsep 3832+ pos = PyUnicode_FindChar(path, ALTSEP, 0, end, -1); 3833+ } 3834+#endif 3835 if (pos < 0) { 3836 return PyUnicode_FromStringAndSize(NULL, 0); 3837 } 3838@@ -513,6 +544,7 @@ getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args) 3839 3840 3841 static PyMethodDef getpath_methods[] = { 3842+ {"normpath", getpath_normpath, METH_VARARGS, NULL}, 3843 {"abspath", getpath_abspath, METH_VARARGS, NULL}, 3844 {"basename", getpath_basename, METH_VARARGS, NULL}, 3845 {"dirname", getpath_dirname, METH_VARARGS, NULL}, 3846@@ -884,6 +916,11 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) 3847 #else 3848 !decode_to_dict(dict, "os_name", "posix") || 3849 #endif 3850+#ifdef __MINGW32__ 3851+ !int_to_dict(dict, "is_mingw", 1) || 3852+#else 3853+ !int_to_dict(dict, "is_mingw", 0) || 3854+#endif 3855 #ifdef WITH_NEXT_FRAMEWORK 3856 !int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 1) || 3857 #else 3858@@ -910,6 +947,9 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) 3859 !funcs_to_dict(dict, config->pathconfig_warnings) || 3860 #ifndef MS_WINDOWS 3861 PyDict_SetItemString(dict, "winreg", Py_None) < 0 || 3862+#endif 3863+#ifdef __MINGW32__ 3864+ !env_to_dict(dict, "ENV_MSYSTEM", 0) || 3865 #endif 3866 PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins()) < 0 3867 ) { 3868diff --git a/Modules/getpath.py b/Modules/getpath.py 3869index 74f918c..c98cb1f 100644 3870--- a/Modules/getpath.py 3871+++ b/Modules/getpath.py 3872@@ -30,6 +30,7 @@ 3873 3874 # ** Values known at compile time ** 3875 # os_name -- [in] one of 'nt', 'posix', 'darwin' 3876+# is_mingw -- [in] True if targeting MinGW 3877 # PREFIX -- [in] sysconfig.get_config_var(...) 3878 # EXEC_PREFIX -- [in] sysconfig.get_config_var(...) 3879 # PYTHONPATH -- [in] sysconfig.get_config_var(...) 3880@@ -51,6 +52,7 @@ 3881 # ENV_PYTHONHOME -- [in] getenv(...) 3882 # ENV_PYTHONEXECUTABLE -- [in] getenv(...) 3883 # ENV___PYVENV_LAUNCHER__ -- [in] getenv(...) 3884+# ENV_MSYSTEM -- [in] getenv(...) 3885 3886 # ** Values calculated at runtime ** 3887 # config -- [in/out] dict of the PyConfig structure 3888@@ -185,8 +187,27 @@ 3889 ZIP_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}{VERSION_MINOR}.zip' 3890 DELIM = ':' 3891 SEP = '/' 3892+ ALTSEP = None 3893 3894-elif os_name == 'nt': 3895+elif os_name == 'nt' and is_mingw: 3896+ BUILDDIR_TXT = 'pybuilddir.txt' 3897+ BUILD_LANDMARK = 'Modules/Setup.local' 3898+ DEFAULT_PROGRAM_NAME = f'python{VERSION_MAJOR}' 3899+ STDLIB_SUBDIR = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}' 3900+ STDLIB_LANDMARKS = [f'{STDLIB_SUBDIR}/os.py', f'{STDLIB_SUBDIR}/os.pyc'] 3901+ PLATSTDLIB_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}/lib-dynload' 3902+ BUILDSTDLIB_LANDMARKS = ['Lib/os.py'] 3903+ VENV_LANDMARK = 'pyvenv.cfg' 3904+ ZIP_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}{VERSION_MINOR}.zip' 3905+ DELIM = ';' 3906+ if ENV_MSYSTEM: 3907+ SEP = '/' 3908+ ALTSEP = '\\' 3909+ else: 3910+ SEP = '\\' 3911+ ALTSEP = '/' 3912+ 3913+elif os_name == 'nt': # MSVC 3914 BUILDDIR_TXT = 'pybuilddir.txt' 3915 BUILD_LANDMARK = f'{VPATH}\\Modules\\Setup.local' 3916 DEFAULT_PROGRAM_NAME = f'python' 3917@@ -199,6 +220,7 @@ 3918 WINREG_KEY = f'SOFTWARE\\Python\\PythonCore\\{PYWINVER}\\PythonPath' 3919 DELIM = ';' 3920 SEP = '\\' 3921+ ALTSEP = '/' 3922 3923 3924 # ****************************************************************************** 3925@@ -211,6 +233,8 @@ def search_up(prefix, *landmarks, test=isfile): 3926 return prefix 3927 prefix = dirname(prefix) 3928 3929+def _normpath(p): 3930+ return normpath(p) if p is not None else None 3931 3932 # ****************************************************************************** 3933 # READ VARIABLES FROM config 3934@@ -263,10 +287,10 @@ def search_up(prefix, *landmarks, test=isfile): 3935 if not executable: 3936 executable = real_executable 3937 3938-if not executable and SEP in program_name: 3939+if not executable and (SEP in program_name or 3940+ (ALTSEP and ALTSEP in program_name)): 3941 # Resolve partial path program_name against current directory 3942 executable = abspath(program_name) 3943- 3944 if not executable: 3945 # All platforms default to real_executable if known at this 3946 # stage. POSIX does not set this value. 3947@@ -497,15 +521,15 @@ def search_up(prefix, *landmarks, test=isfile): 3948 except (FileNotFoundError, PermissionError): 3949 if isfile(joinpath(real_executable_dir, BUILD_LANDMARK)): 3950 build_prefix = joinpath(real_executable_dir, VPATH) 3951- if os_name == 'nt': 3952+ if os_name == 'nt' and not is_mingw: 3953 # QUIRK: Windows builds need platstdlib_dir to be the executable 3954 # dir. Normally the builddir marker handles this, but in this 3955 # case we need to correct manually. 3956 platstdlib_dir = real_executable_dir 3957 3958 if build_prefix: 3959- if os_name == 'nt': 3960- # QUIRK: No searching for more landmarks on Windows 3961+ if os_name == 'nt' and not is_mingw: 3962+ # QUIRK: No searching for more landmarks on MSVC 3963 build_stdlib_prefix = build_prefix 3964 else: 3965 build_stdlib_prefix = search_up(build_prefix, *BUILDSTDLIB_LANDMARKS) 3966@@ -552,6 +576,9 @@ def search_up(prefix, *landmarks, test=isfile): 3967 # First try to detect prefix by looking alongside our runtime library, if known 3968 if library and not prefix: 3969 library_dir = dirname(library) 3970+ if os_name == 'nt' and is_mingw: 3971+ # QUIRK: On Windows, mingw Python DLLs are in the bin directory 3972+ library_dir = joinpath(library_dir, '..') 3973 if ZIP_LANDMARK: 3974 if os_name == 'nt': 3975 # QUIRK: Windows does not search up for ZIP file 3976@@ -597,7 +624,7 @@ def search_up(prefix, *landmarks, test=isfile): 3977 3978 # Detect exec_prefix by searching from executable for the platstdlib_dir 3979 if PLATSTDLIB_LANDMARK and not exec_prefix: 3980- if os_name == 'nt': 3981+ if os_name == 'nt' and (not is_mingw): 3982 # QUIRK: Windows always assumed these were the same 3983 # gh-100320: Our PYDs are assumed to be relative to the Lib directory 3984 # (that is, prefix) rather than the executable (that is, executable_dir) 3985@@ -607,7 +634,7 @@ def search_up(prefix, *landmarks, test=isfile): 3986 if not exec_prefix and EXEC_PREFIX: 3987 exec_prefix = EXEC_PREFIX 3988 if not exec_prefix or not isdir(joinpath(exec_prefix, PLATSTDLIB_LANDMARK)): 3989- if os_name == 'nt': 3990+ if os_name == 'nt' and (not is_mingw): 3991 # QUIRK: If DLLs is missing on Windows, don't warn, just assume 3992 # that they're in exec_prefix 3993 if not platstdlib_dir: 3994@@ -645,7 +672,7 @@ def search_up(prefix, *landmarks, test=isfile): 3995 3996 if py_setpath: 3997 # If Py_SetPath was called then it overrides any existing search path 3998- config['module_search_paths'] = py_setpath.split(DELIM) 3999+ config['module_search_paths'] = [_normpath(p) for p in py_setpath.split(DELIM)] 4000 config['module_search_paths_set'] = 1 4001 4002 elif not pythonpath_was_set: 4003@@ -660,7 +687,7 @@ def search_up(prefix, *landmarks, test=isfile): 4004 pythonpath.append(abspath(p)) 4005 4006 # Then add the default zip file 4007- if os_name == 'nt': 4008+ if os_name == 'nt' and (not is_mingw): 4009 # QUIRK: Windows uses the library directory rather than the prefix 4010 if library: 4011 library_dir = dirname(library) 4012@@ -673,7 +700,7 @@ def search_up(prefix, *landmarks, test=isfile): 4013 else: 4014 pythonpath.append(joinpath(prefix, ZIP_LANDMARK)) 4015 4016- if os_name == 'nt' and use_environment and winreg: 4017+ if (not is_mingw) and os_name == 'nt' and use_environment and winreg: 4018 # QUIRK: Windows also lists paths in the registry. Paths are stored 4019 # as the default value of each subkey of 4020 # {HKCU,HKLM}\Software\Python\PythonCore\{winver}\PythonPath 4021@@ -714,7 +741,7 @@ def search_up(prefix, *landmarks, test=isfile): 4022 if not platstdlib_dir and exec_prefix: 4023 platstdlib_dir = joinpath(exec_prefix, PLATSTDLIB_LANDMARK) 4024 4025- if os_name == 'nt': 4026+ if os_name == 'nt' and (not is_mingw): 4027 # QUIRK: Windows generates paths differently 4028 if platstdlib_dir: 4029 pythonpath.append(platstdlib_dir) 4030@@ -732,7 +759,7 @@ def search_up(prefix, *landmarks, test=isfile): 4031 if platstdlib_dir: 4032 pythonpath.append(platstdlib_dir) 4033 4034- config['module_search_paths'] = pythonpath 4035+ config['module_search_paths'] = [_normpath(p) for p in pythonpath] 4036 config['module_search_paths_set'] = 1 4037 4038 4039@@ -742,8 +769,8 @@ def search_up(prefix, *landmarks, test=isfile): 4040 4041 # QUIRK: Non-Windows replaces prefix/exec_prefix with defaults when running 4042 # in build directory. This happens after pythonpath calculation. 4043-if os_name != 'nt' and build_prefix: 4044- prefix = config.get('prefix') or PREFIX 4045+if (os_name != 'nt' or is_mingw) and build_prefix: 4046+ prefix = config.get('prefix') or abspath(PREFIX) 4047 exec_prefix = config.get('exec_prefix') or EXEC_PREFIX or prefix 4048 4049 4050@@ -767,23 +794,23 @@ def search_up(prefix, *landmarks, test=isfile): 4051 warn("unsupported 'import' line in ._pth file") 4052 else: 4053 pythonpath.append(joinpath(pth_dir, line)) 4054- config['module_search_paths'] = pythonpath 4055+ config['module_search_paths'] = [_normpath(p) for p in pythonpath] 4056 config['module_search_paths_set'] = 1 4057 4058 # ****************************************************************************** 4059 # UPDATE config FROM CALCULATED VALUES 4060 # ****************************************************************************** 4061 4062-config['program_name'] = program_name 4063-config['home'] = home 4064-config['executable'] = executable 4065-config['base_executable'] = base_executable 4066-config['prefix'] = prefix 4067-config['exec_prefix'] = exec_prefix 4068-config['base_prefix'] = base_prefix or prefix 4069-config['base_exec_prefix'] = base_exec_prefix or exec_prefix 4070+config['program_name'] = _normpath(program_name) 4071+config['home'] = _normpath(home) 4072+config['executable'] = _normpath(executable) 4073+config['base_executable'] = _normpath(base_executable) 4074+config['prefix'] = _normpath(prefix) 4075+config['exec_prefix'] = _normpath(exec_prefix) 4076+config['base_prefix'] = _normpath(base_prefix or prefix) 4077+config['base_exec_prefix'] = _normpath(base_exec_prefix or exec_prefix) 4078 4079-config['platlibdir'] = platlibdir 4080+config['platlibdir'] = _normpath(platlibdir) 4081 # test_embed expects empty strings, not None 4082-config['stdlib_dir'] = stdlib_dir or '' 4083-config['platstdlib_dir'] = platstdlib_dir or '' 4084+config['stdlib_dir'] = _normpath(stdlib_dir or '') 4085+config['platstdlib_dir'] = _normpath(platstdlib_dir or '') 4086diff --git a/Modules/main.c b/Modules/main.c 4087index 6904e3f..5c8708e 100644 4088--- a/Modules/main.c 4089+++ b/Modules/main.c 4090@@ -7,6 +7,7 @@ 4091 #include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() 4092 #include "pycore_pylifecycle.h" // _Py_PreInitializeFromPyArgv() 4093 #include "pycore_pystate.h" // _PyInterpreterState_GET() 4094+#include "iscygpty.h" 4095 4096 /* Includes for exit_sigint() */ 4097 #include <stdio.h> // perror() 4098@@ -92,7 +93,7 @@ static inline int config_run_code(const PyConfig *config) 4099 static int 4100 stdin_is_interactive(const PyConfig *config) 4101 { 4102- return (isatty(fileno(stdin)) || config->interactive); 4103+ return (isatty(fileno(stdin)) || config->interactive || is_cygpty(fileno(stdin))); 4104 } 4105 4106 4107diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c 4108index 8d09f54..cc668df 100644 4109--- a/Modules/posixmodule.c 4110+++ b/Modules/posixmodule.c 4111@@ -55,6 +55,7 @@ 4112 #ifdef __ANDROID__ 4113 # undef HAVE_FACCESSAT 4114 #endif 4115+#include "iscygpty.h" 4116 4117 #include <stdio.h> // ctermid() 4118 #include <stdlib.h> // system() 4119@@ -355,6 +356,32 @@ corresponding Unix manual entries for more information on calls."); 4120 # define HAVE_CWAIT 1 4121 # define HAVE_FSYNC 1 4122 # define fsync _commit 4123+# elif defined(__MINGW32__) /* GCC for windows hosts */ 4124+/* getlogin is detected by configure on mingw-w64 */ 4125+# undef HAVE_GETLOGIN 4126+/* opendir is detected by configure on mingw-w64, and for some reason 4127+things don't work as expected. For example, os.listdir always returns 4128+the cwd's directory listing instead of the one specified. By 4129+un-defining, this, os.listdir will use the one which uses native 4130+windows API. */ 4131+# undef HAVE_OPENDIR 4132+/*# define HAVE_GETCWD 1 - detected by configure*/ 4133+# define HAVE_GETPPID 1 4134+# define HAVE_GETLOGIN 1 4135+# define HAVE_SPAWNV 1 4136+# define HAVE_WSPAWNV 1 4137+# define HAVE_WEXECV 1 4138+/*# define HAVE_EXECV 1 - detected by configure*/ 4139+# define HAVE_PIPE 1 4140+# define HAVE_POPEN 1 4141+# define HAVE_SYSTEM 1 4142+# define HAVE_CWAIT 1 4143+# define HAVE_FSYNC 1 4144+# define fsync _commit 4145+# include <winioctl.h> 4146+# ifndef _MAX_ENV 4147+# define _MAX_ENV 32767 4148+# endif 4149 # endif /* _MSC_VER */ 4150 #endif /* ! __WATCOMC__ || __QNX__ */ 4151 4152@@ -433,7 +460,7 @@ extern char *ctermid_r(char *); 4153 # endif 4154 #endif 4155 4156-#ifdef _MSC_VER 4157+#ifdef MS_WINDOWS 4158 # ifdef HAVE_DIRECT_H 4159 # include <direct.h> 4160 # endif 4161@@ -444,7 +471,7 @@ extern char *ctermid_r(char *); 4162 # include <process.h> 4163 # endif 4164 # include <malloc.h> 4165-#endif /* _MSC_VER */ 4166+#endif /* MS_WINDOWS */ 4167 4168 #ifndef MAXPATHLEN 4169 # if defined(PATH_MAX) && PATH_MAX > 1024 4170@@ -1598,9 +1625,9 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) 4171 ** man environ(7). 4172 */ 4173 #include <crt_externs.h> 4174-#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__)) 4175+#elif !defined(MS_WINDOWS) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__)) 4176 extern char **environ; 4177-#endif /* !_MSC_VER */ 4178+#endif /* !MS_WINDOWS */ 4179 4180 static PyObject * 4181 convertenviron(void) 4182@@ -3820,6 +3847,7 @@ posix_getcwd(int use_bytes) 4183 return PyErr_SetFromWindowsErr(0); 4184 } 4185 4186+ Py_NormalizeSepsW(wbuf2); 4187 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len); 4188 if (wbuf2 != wbuf) { 4189 PyMem_RawFree(wbuf2); 4190@@ -4424,6 +4452,7 @@ os__getfinalpathname_impl(PyObject *module, path_t *path) 4191 target_path = tmp; 4192 } 4193 4194+ Py_NormalizeSepsW(target_path); 4195 result = PyUnicode_FromWideChar(target_path, result_length); 4196 if (result && path->narrow) { 4197 Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); 4198@@ -5507,7 +5536,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, 4199 /*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/ 4200 { 4201 #ifdef MS_WINDOWS 4202- HANDLE hFile; 4203+ HANDLE hFile = 0; 4204 FILETIME atime, mtime; 4205 #else 4206 int result; 4207@@ -10234,7 +10263,7 @@ os_isatty_impl(PyObject *module, int fd) 4208 int return_value; 4209 Py_BEGIN_ALLOW_THREADS 4210 _Py_BEGIN_SUPPRESS_IPH 4211- return_value = isatty(fd); 4212+ return_value = isatty(fd) || is_cygpty(fd); 4213 _Py_END_SUPPRESS_IPH 4214 Py_END_ALLOW_THREADS 4215 return return_value; 4216@@ -14722,7 +14751,7 @@ os__add_dll_directory_impl(PyObject *module, path_t *path) 4217 loaded. */ 4218 Py_BEGIN_ALLOW_THREADS 4219 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || 4220- !(AddDllDirectory = (PAddDllDirectory)GetProcAddress( 4221+ !(AddDllDirectory = (PAddDllDirectory)(void *)GetProcAddress( 4222 hKernel32, "AddDllDirectory")) || 4223 !(cookie = (*AddDllDirectory)(path->wide))) { 4224 err = GetLastError(); 4225@@ -14772,7 +14801,7 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) 4226 loaded. */ 4227 Py_BEGIN_ALLOW_THREADS 4228 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || 4229- !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress( 4230+ !(RemoveDllDirectory = (PRemoveDllDirectory)(void *)GetProcAddress( 4231 hKernel32, "RemoveDllDirectory")) || 4232 !(*RemoveDllDirectory)(cookieValue)) { 4233 err = GetLastError(); 4234diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c 4235index 4eea928..6be3582 100644 4236--- a/Modules/selectmodule.c 4237+++ b/Modules/selectmodule.c 4238@@ -146,9 +146,9 @@ seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) 4239 v = PyObject_AsFileDescriptor( o ); 4240 if (v == -1) goto finally; 4241 4242-#if defined(_MSC_VER) 4243+#if defined(MS_WIN32) 4244 max = 0; /* not used for Win32 */ 4245-#else /* !_MSC_VER */ 4246+#else /* !MS_WIN32 */ 4247 if (!_PyIsSelectable_fd(v)) { 4248 PyErr_SetString(PyExc_ValueError, 4249 "filedescriptor out of range in select()"); 4250@@ -156,7 +156,7 @@ seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) 4251 } 4252 if (v > max) 4253 max = v; 4254-#endif /* _MSC_VER */ 4255+#endif /* MS_WIN32 */ 4256 FD_SET(v, set); 4257 4258 /* add object and its file descriptor to the list */ 4259diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c 4260index 65d0e10..d1bfe3d 100644 4261--- a/Modules/socketmodule.c 4262+++ b/Modules/socketmodule.c 4263@@ -274,7 +274,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\ 4264 # endif 4265 4266 /* Macros based on the IPPROTO enum, see: https://bugs.python.org/issue29515 */ 4267-#ifdef MS_WINDOWS 4268+#ifdef _MSC_VER 4269 #define IPPROTO_ICMP IPPROTO_ICMP 4270 #define IPPROTO_IGMP IPPROTO_IGMP 4271 #define IPPROTO_GGP IPPROTO_GGP 4272@@ -305,7 +305,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\ 4273 #define IPPROTO_PGM IPPROTO_PGM // WinSock2 only 4274 #define IPPROTO_L2TP IPPROTO_L2TP // WinSock2 only 4275 #define IPPROTO_SCTP IPPROTO_SCTP // WinSock2 only 4276-#endif /* MS_WINDOWS */ 4277+#endif /* _MSC_VER */ 4278 4279 /* Provides the IsWindows7SP1OrGreater() function */ 4280 #include <versionhelpers.h> 4281@@ -404,6 +404,10 @@ remove_unusable_flags(PyObject *m) 4282 /* Do not include addrinfo.h for MSVC7 or greater. 'addrinfo' and 4283 * EAI_* constants are defined in (the already included) ws2tcpip.h. 4284 */ 4285+#elif defined(__MINGW32__) 4286+ /* Do not include addrinfo.h as minimum supported version is 4287+ * _WIN32_WINNT >= WindowsXP(0x0501) 4288+ */ 4289 #else 4290 # include "addrinfo.h" 4291 #endif 4292diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h 4293index 1b35b11..cff1f1d 100644 4294--- a/Modules/socketmodule.h 4295+++ b/Modules/socketmodule.h 4296@@ -68,8 +68,10 @@ struct SOCKADDR_BTH_REDEF { 4297 */ 4298 # ifdef SIO_GET_MULTICAST_FILTER 4299 # include <mstcpip.h> /* for SIO_RCVALL */ 4300+#ifndef __MINGW32__ /* resolve by configure */ 4301 # define HAVE_ADDRINFO 4302 # define HAVE_SOCKADDR_STORAGE 4303+#endif 4304 # define HAVE_GETADDRINFO 4305 # define HAVE_GETNAMEINFO 4306 # define ENABLE_IPV6 4307diff --git a/Modules/timemodule.c b/Modules/timemodule.c 4308index 18f9ddb..4edc2e7 100644 4309--- a/Modules/timemodule.c 4310+++ b/Modules/timemodule.c 4311@@ -783,7 +783,7 @@ time_strftime(PyObject *module, PyObject *args) 4312 return NULL; 4313 } 4314 4315-#if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__) 4316+#if defined(MS_WINDOWS) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__) 4317 if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) { 4318 PyErr_SetString(PyExc_ValueError, 4319 "strftime() requires year in [1; 9999]"); 4320diff --git a/Objects/fileobject.c b/Objects/fileobject.c 4321index ffe55eb..1d73c09 100644 4322--- a/Objects/fileobject.c 4323+++ b/Objects/fileobject.c 4324@@ -3,6 +3,7 @@ 4325 #define PY_SSIZE_T_CLEAN 4326 #include "Python.h" 4327 #include "pycore_call.h" // _PyObject_CallNoArgs() 4328+#include "iscygpty.h" 4329 #include "pycore_runtime.h" // _PyRuntime 4330 4331 #if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER) 4332@@ -387,7 +388,7 @@ stdprinter_isatty(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored)) 4333 } 4334 4335 Py_BEGIN_ALLOW_THREADS 4336- res = isatty(self->fd); 4337+ res = isatty(self->fd) || is_cygpty(self->fd); 4338 Py_END_ALLOW_THREADS 4339 4340 return PyBool_FromLong(res); 4341diff --git a/PC/_testconsole.c b/PC/_testconsole.c 4342index a830883..52aca33 100644 4343--- a/PC/_testconsole.c 4344+++ b/PC/_testconsole.c 4345@@ -10,7 +10,7 @@ 4346 #ifdef MS_WINDOWS 4347 4348 #include "pycore_fileutils.h" // _Py_get_osfhandle() 4349-#include "..\modules\_io\_iomodule.h" 4350+#include "../Modules/_io/_iomodule.h" 4351 4352 #define WIN32_LEAN_AND_MEAN 4353 #include <windows.h> 4354@@ -108,7 +108,7 @@ _testconsole_read_output_impl(PyObject *module, PyObject *file) 4355 Py_RETURN_NONE; 4356 } 4357 4358-#include "clinic\_testconsole.c.h" 4359+#include "clinic/_testconsole.c.h" 4360 4361 PyMethodDef testconsole_methods[] = { 4362 _TESTCONSOLE_WRITE_INPUT_METHODDEF 4363diff --git a/PC/launcher.c b/PC/launcher.c 4364index da566a1..09ac7d9 100644 4365--- a/PC/launcher.c 4366+++ b/PC/launcher.c 4367@@ -155,12 +155,12 @@ static wchar_t * get_env(wchar_t * key) 4368 #else 4369 #if defined(_WINDOWS) 4370 4371-#define PYTHON_EXECUTABLE L"pythonw.exe" 4372+#define PYTHON_EXECUTABLE PYTHON_EXECUTABLE_WITH_VERSION 4373 #define EXECUTABLEPATH_VALUE L"WindowedExecutablePath" 4374 4375 #else 4376 4377-#define PYTHON_EXECUTABLE L"python.exe" 4378+#define PYTHON_EXECUTABLE PYTHON_EXECUTABLE_WITH_VERSION 4379 #define EXECUTABLEPATH_VALUE L"ExecutablePath" 4380 4381 #endif 4382@@ -925,7 +925,7 @@ static COMMAND path_command; 4383 static COMMAND * find_on_path(wchar_t * name) 4384 { 4385 wchar_t * pathext; 4386- size_t varsize; 4387+ size_t requiredSize; 4388 wchar_t * context = NULL; 4389 wchar_t * extension; 4390 COMMAND * result = NULL; 4391@@ -942,18 +942,23 @@ static COMMAND * find_on_path(wchar_t * name) 4392 } 4393 else { 4394 /* No extension - search using registered extensions. */ 4395- rc = _wdupenv_s(&pathext, &varsize, L"PATHEXT"); 4396- if (rc == 0) { 4397- extension = wcstok_s(pathext, L";", &context); 4398- while (extension) { 4399- len = SearchPathW(NULL, name, extension, MSGSIZE, path_command.value, NULL); 4400- if (len) { 4401- result = &path_command; 4402- break; 4403+ _wgetenv_s(&requiredSize, NULL, 0, L"PATHEXT"); 4404+ if (requiredSize > 0) { 4405+ pathext = (wchar_t *)malloc(requiredSize * sizeof(wchar_t)); 4406+ /* No extension - search using registered extensions. */ 4407+ rc = _wgetenv_s(&requiredSize, pathext, requiredSize, L"PATHEXT"); 4408+ if (rc == 0) { 4409+ extension = wcstok_s(pathext, L";", &context); 4410+ while (extension) { 4411+ len = SearchPathW(NULL, name, extension, MSGSIZE, path_command.value, NULL); 4412+ if (len) { 4413+ result = &path_command; 4414+ break; 4415+ } 4416+ extension = wcstok_s(NULL, L";", &context); 4417 } 4418- extension = wcstok_s(NULL, L";", &context); 4419+ free(pathext); 4420 } 4421- free(pathext); 4422 } 4423 } 4424 return result; 4425@@ -1913,7 +1918,7 @@ process(int argc, wchar_t ** argv) 4426 if (_wfopen_s(&f, venv_cfg_path, L"r")) { 4427 error(RC_BAD_VENV_CFG, L"Cannot read '%ls'", venv_cfg_path); 4428 } 4429- cb = fread_s(buffer, sizeof(buffer), sizeof(buffer[0]), 4430+ cb = fread(buffer, sizeof(buffer[0]), 4431 sizeof(buffer) / sizeof(buffer[0]), f); 4432 fclose(f); 4433 4434diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c 4435index 1f78d99..0f2da80 100644 4436--- a/PC/msvcrtmodule.c 4437+++ b/PC/msvcrtmodule.c 4438@@ -22,7 +22,9 @@ 4439 #include <io.h> 4440 #include <conio.h> 4441 #include <sys/locking.h> 4442+#ifdef _DEBUG 4443 #include <crtdbg.h> 4444+#endif 4445 #include <windows.h> 4446 4447 #ifdef _MSC_VER 4448diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc 4449index 1186264..84b2917 100644 4450--- a/PC/pylauncher.rc 4451+++ b/PC/pylauncher.rc 4452@@ -12,17 +12,17 @@ 4453 1 RT_MANIFEST "python.manifest" 4454 4455 #if defined(PY_ICON) 4456-1 ICON DISCARDABLE "icons\python.ico" 4457+1 ICON DISCARDABLE "icons/python.ico" 4458 #elif defined(PYW_ICON) 4459-1 ICON DISCARDABLE "icons\pythonw.ico" 4460+1 ICON DISCARDABLE "icons/pythonw.ico" 4461 #else 4462-1 ICON DISCARDABLE "icons\launcher.ico" 4463-2 ICON DISCARDABLE "icons\py.ico" 4464-3 ICON DISCARDABLE "icons\pyc.ico" 4465-4 ICON DISCARDABLE "icons\pyd.ico" 4466-5 ICON DISCARDABLE "icons\python.ico" 4467-6 ICON DISCARDABLE "icons\pythonw.ico" 4468-7 ICON DISCARDABLE "icons\setup.ico" 4469+1 ICON DISCARDABLE "icons/launcher.ico" 4470+2 ICON DISCARDABLE "icons/py.ico" 4471+3 ICON DISCARDABLE "icons/pyc.ico" 4472+4 ICON DISCARDABLE "icons/pyd.ico" 4473+5 ICON DISCARDABLE "icons/python.ico" 4474+6 ICON DISCARDABLE "icons/pythonw.ico" 4475+7 ICON DISCARDABLE "icons/setup.ico" 4476 #endif 4477 4478 1 USAGE "launcher-usage.txt" 4479@@ -64,4 +64,4 @@ BEGIN 4480 BEGIN 4481 VALUE "Translation", 0x0, 1200 4482 END 4483-END 4484\ No newline at end of file 4485+END 4486diff --git a/PC/python3dll.c b/PC/python3dll.c 4487index 50e7a96..8b524fd 100755 4488--- a/PC/python3dll.c 4489+++ b/PC/python3dll.c 4490@@ -3,6 +3,7 @@ 4491 4492 /* Generated by Tools/scripts/stable_abi.py */ 4493 4494+#ifdef _MSC_VER 4495 #ifdef _M_IX86 4496 #define DECORATE "_" 4497 #else 4498@@ -13,6 +14,13 @@ 4499 __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name)) 4500 #define EXPORT_DATA(name) \ 4501 __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name ",DATA")) 4502+#else 4503+// XXX: Why do we need the .dll extension and no DECORATE compared to the MSVC case? 4504+#define EXPORT_FUNC(name) \ 4505+ asm(".section .drectve\n\t.ascii \" -export:" #name "=\\\"" PYTHON_DLL_NAME "." #name "\\\" \""); 4506+#define EXPORT_DATA(name) \ 4507+ asm(".section .drectve\n\t.ascii \" -export:" #name "=\\\"" PYTHON_DLL_NAME "." #name "\\\",DATA \""); 4508+#endif 4509 4510 EXPORT_FUNC(_Py_BuildValue_SizeT) 4511 EXPORT_FUNC(_Py_CheckRecursiveCall) 4512diff --git a/PC/python_exe.rc b/PC/python_exe.rc 4513index c3d3bff..dde0e53 100644 4514--- a/PC/python_exe.rc 4515+++ b/PC/python_exe.rc 4516@@ -12,7 +12,7 @@ 4517 // current versions of Windows. 4518 1 RT_MANIFEST "python.manifest" 4519 4520-1 ICON DISCARDABLE "icons\python.ico" 4521+1 ICON DISCARDABLE "icons/python.ico" 4522 4523 4524 ///////////////////////////////////////////////////////////////////////////// 4525diff --git a/PC/pythonw_exe.rc b/PC/pythonw_exe.rc 4526index 38570b7..7ce1043 100644 4527--- a/PC/pythonw_exe.rc 4528+++ b/PC/pythonw_exe.rc 4529@@ -12,7 +12,7 @@ 4530 // current versions of Windows. 4531 1 RT_MANIFEST "python.manifest" 4532 4533-1 ICON DISCARDABLE "icons\pythonw.ico" 4534+1 ICON DISCARDABLE "icons/pythonw.ico" 4535 4536 4537 ///////////////////////////////////////////////////////////////////////////// 4538diff --git a/PC/winreg.c b/PC/winreg.c 4539index f668cf3..08548a7 100644 4540--- a/PC/winreg.c 4541+++ b/PC/winreg.c 4542@@ -18,6 +18,25 @@ 4543 #include "structmember.h" // PyMemberDef 4544 #include <windows.h> 4545 4546+#ifndef SIZEOF_HKEY 4547+/* used only here */ 4548+#if defined(MS_WIN64) 4549+# define SIZEOF_HKEY 8 4550+#elif defined(MS_WIN32) 4551+# define SIZEOF_HKEY 4 4552+#else 4553+# error "SIZEOF_HKEY is not defined" 4554+#endif 4555+#endif 4556+ 4557+#ifndef REG_LEGAL_CHANGE_FILTER 4558+#define REG_LEGAL_CHANGE_FILTER (\ 4559+ REG_NOTIFY_CHANGE_NAME |\ 4560+ REG_NOTIFY_CHANGE_ATTRIBUTES |\ 4561+ REG_NOTIFY_CHANGE_LAST_SET |\ 4562+ REG_NOTIFY_CHANGE_SECURITY ) 4563+#endif 4564+ 4565 static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK); 4566 static BOOL clinic_HKEY_converter(PyObject *ob, void *p); 4567 static PyObject *PyHKEY_FromHKEY(HKEY h); 4568@@ -806,6 +825,7 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) 4569 case REG_BINARY: 4570 /* ALSO handle ALL unknown data types here. Even if we can't 4571 support it natively, we should handle the bits. */ 4572+ /* fallthrough */ 4573 default: 4574 if (retDataSize == 0) { 4575 Py_INCREF(Py_None); 4576diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c 4577index e20bd53..c035b6b 100644 4578--- a/Python/bltinmodule.c 4579+++ b/Python/bltinmodule.c 4580@@ -1,6 +1,7 @@ 4581 /* Built-in functions */ 4582 4583 #include "Python.h" 4584+#include "iscygpty.h" 4585 #include <ctype.h> 4586 #include "pycore_ast.h" // _PyAST_Validate() 4587 #include "pycore_call.h" // _PyObject_CallNoArgs() 4588@@ -2135,7 +2136,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) 4589 Py_DECREF(tmp); 4590 if (fd < 0 && PyErr_Occurred()) 4591 return NULL; 4592- tty = fd == fileno(stdin) && isatty(fd); 4593+ tty = fd == fileno(stdin) && (isatty(fd) || is_cygpty(fd)); 4594 } 4595 if (tty) { 4596 tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(fileno)); 4597@@ -2148,7 +2149,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) 4598 Py_DECREF(tmp); 4599 if (fd < 0 && PyErr_Occurred()) 4600 return NULL; 4601- tty = fd == fileno(stdout) && isatty(fd); 4602+ tty = fd == fileno(stdout) && (isatty(fd) || is_cygpty(fd)); 4603 } 4604 } 4605 4606diff --git a/Python/dynamic_annotations.c b/Python/dynamic_annotations.c 4607index 7febaa0..70d5b3d 100644 4608--- a/Python/dynamic_annotations.c 4609+++ b/Python/dynamic_annotations.c 4610@@ -27,7 +27,7 @@ 4611 * Author: Kostya Serebryany 4612 */ 4613 4614-#ifdef _MSC_VER 4615+#ifdef MS_WINDOWS 4616 # include <windows.h> 4617 #endif 4618 4619diff --git a/Python/dynload_win.c b/Python/dynload_win.c 4620index 5dc4095..fcb7321 100644 4621--- a/Python/dynload_win.c 4622+++ b/Python/dynload_win.c 4623@@ -4,6 +4,7 @@ 4624 #include "Python.h" 4625 #include "pycore_fileutils.h" // _Py_add_relfile() 4626 #include "pycore_pystate.h" // _PyInterpreterState_GET() 4627+#include "pycore_initconfig.h" 4628 4629 #ifdef HAVE_DIRECT_H 4630 #include <direct.h> 4631@@ -170,8 +171,7 @@ static char *GetPythonImport (HINSTANCE hModule) 4632 Return whether the DLL was found. 4633 */ 4634 extern HMODULE PyWin_DLLhModule; 4635-static int 4636-_Py_CheckPython3(void) 4637+int _Py_CheckPython3(void) 4638 { 4639 static int python3_checked = 0; 4640 static HANDLE hPython3; 4641@@ -224,7 +224,21 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, 4642 dl_funcptr p; 4643 char funcname[258], *import_python; 4644 4645- _Py_CheckPython3(); 4646+ int use_legacy = 0; 4647+ DWORD load_library_flags = 0; 4648+ 4649+ _Py_get_env_flag(1, &use_legacy, "PYTHONLEGACYWINDOWSDLLLOADING"); 4650+ 4651+ if (use_legacy) { 4652+ load_library_flags = LOAD_WITH_ALTERED_SEARCH_PATH; 4653+ } else { 4654+ load_library_flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | 4655+ LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR; 4656+ } 4657+ 4658+#ifdef _MSC_VER 4659+ _Py_CheckPython3(); 4660+#endif 4661 4662 #if USE_UNICODE_WCHAR_CACHE 4663 const wchar_t *wpathname = _PyUnicode_AsUnicode(pathname); 4664@@ -248,9 +262,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, 4665 AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to 4666 ensure DLLs adjacent to the PYD are preferred. */ 4667 Py_BEGIN_ALLOW_THREADS 4668- hDLL = LoadLibraryExW(wpathname, NULL, 4669- LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | 4670- LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); 4671+ hDLL = LoadLibraryExW(wpathname, NULL, load_library_flags); 4672 Py_END_ALLOW_THREADS 4673 #if !USE_UNICODE_WCHAR_CACHE 4674 PyMem_Free(wpathname); 4675diff --git a/Python/fileutils.c b/Python/fileutils.c 4676index b310a6c..c575e5a 100644 4677--- a/Python/fileutils.c 4678+++ b/Python/fileutils.c 4679@@ -1,4 +1,5 @@ 4680 #include "Python.h" 4681+#include "iscygpty.h" 4682 #include "pycore_fileutils.h" // fileutils definitions 4683 #include "pycore_runtime.h" // _PyRuntime 4684 #include "osdefs.h" // SEP 4685@@ -71,7 +72,7 @@ _Py_device_encoding(int fd) 4686 int valid; 4687 Py_BEGIN_ALLOW_THREADS 4688 _Py_BEGIN_SUPPRESS_IPH 4689- valid = isatty(fd); 4690+ valid = isatty(fd) || is_cygpty(fd); 4691 _Py_END_SUPPRESS_IPH 4692 Py_END_ALLOW_THREADS 4693 if (!valid) 4694@@ -1809,12 +1810,12 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held) 4695 depending on heap usage). */ 4696 if (gil_held) { 4697 Py_BEGIN_ALLOW_THREADS 4698- if (isatty(fd)) { 4699+ if (isatty(fd) || is_cygpty(fd)) { 4700 count = 32767; 4701 } 4702 Py_END_ALLOW_THREADS 4703 } else { 4704- if (isatty(fd)) { 4705+ if (isatty(fd) || is_cygpty(fd)) { 4706 count = 32767; 4707 } 4708 } 4709@@ -2004,19 +2005,31 @@ int 4710 _Py_isabs(const wchar_t *path) 4711 { 4712 #ifdef MS_WINDOWS 4713+ // create a copy of path and replace all forward slashes with backslashes 4714+ // pathccskiproot does not handle forward slashes 4715+ wchar_t *path_copy = _wcsdup(path); 4716+ if (path_copy == NULL) { 4717+ return 0; 4718+ } 4719+ Py_NormalizeSepsPathcchW(path_copy); 4720+ 4721 const wchar_t *tail; 4722- HRESULT hr = PathCchSkipRoot(path, &tail); 4723- if (FAILED(hr) || path == tail) { 4724+ HRESULT hr = PathCchSkipRoot(path_copy, &tail); 4725+ if (FAILED(hr) || path_copy == tail) { 4726+ free(path_copy); 4727 return 0; 4728 } 4729- if (tail == &path[1] && (path[0] == SEP || path[0] == ALTSEP)) { 4730+ if (tail == &path_copy[1] && (path_copy[0] == SEP || path_copy[0] == ALTSEP)) { 4731 // Exclude paths with leading SEP 4732+ free(path_copy); 4733 return 0; 4734 } 4735- if (tail == &path[2] && path[1] == L':') { 4736+ if (tail == &path_copy[2] && path_copy[1] == L':') { 4737 // Exclude drive-relative paths (e.g. C:filename.ext) 4738+ free(path_copy); 4739 return 0; 4740 } 4741+ free(path_copy); 4742 return 1; 4743 #else 4744 return (path[0] == SEP); 4745@@ -2049,7 +2062,11 @@ _Py_abspath(const wchar_t *path, wchar_t **abspath_p) 4746 } 4747 4748 #ifdef MS_WINDOWS 4749- return _PyOS_getfullpathname(path, abspath_p); 4750+ if (_PyOS_getfullpathname(path, abspath_p) < 0){ 4751+ return -1; 4752+ } 4753+ *abspath_p = _Py_normpath(*abspath_p, -1); 4754+ return 0; 4755 #else 4756 wchar_t cwd[MAXPATHLEN + 1]; 4757 cwd[Py_ARRAY_LENGTH(cwd) - 1] = 0; 4758@@ -2093,6 +2110,8 @@ join_relfile(wchar_t *buffer, size_t bufsize, 4759 const wchar_t *dirname, const wchar_t *relfile) 4760 { 4761 #ifdef MS_WINDOWS 4762+ Py_NormalizeSepsPathcchW(dirname); 4763+ Py_NormalizeSepsPathcchW(relfile); 4764 if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile, 4765 PATHCCH_ALLOW_LONG_PATHS))) { 4766 return -1; 4767@@ -2195,11 +2214,16 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4768 wchar_t *minP2 = path; // the beginning of the destination range 4769 wchar_t lastC = L'\0'; // the last ljusted character, p2[-1] in most cases 4770 4771+ const wchar_t sep = Py_GetSepW(NULL); 4772+#ifdef ALTSEP 4773+ const wchar_t altsep = Py_GetAltSepW(NULL); 4774+#endif 4775+ 4776 #define IS_END(x) (pEnd ? (x) == pEnd : !*(x)) 4777 #ifdef ALTSEP 4778-#define IS_SEP(x) (*(x) == SEP || *(x) == ALTSEP) 4779+#define IS_SEP(x) (*(x) == sep || *(x) == altsep) 4780 #else 4781-#define IS_SEP(x) (*(x) == SEP) 4782+#define IS_SEP(x) (*(x) == sep) 4783 #endif 4784 #define SEP_OR_END(x) (IS_SEP(x) || IS_END(x)) 4785 4786@@ -2210,7 +2234,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4787 path++; 4788 } 4789 p1 = p2 = minP2 = path; 4790- lastC = SEP; 4791+ lastC = sep; 4792 } 4793 #ifdef MS_WINDOWS 4794 // Skip past drive segment and update minP2 4795@@ -2224,13 +2248,13 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4796 // and network paths, including the first segment. 4797 else if (IS_SEP(&p1[0]) && IS_SEP(&p1[1])) { 4798 int sepCount = 2; 4799- *p2++ = SEP; 4800- *p2++ = SEP; 4801+ *p2++ = sep; 4802+ *p2++ = sep; 4803 p1 += 2; 4804 for (; !IS_END(p1) && sepCount; ++p1) { 4805 if (IS_SEP(p1)) { 4806 --sepCount; 4807- *p2++ = lastC = SEP; 4808+ *p2++ = lastC = sep; 4809 } else { 4810 *p2++ = lastC = *p1; 4811 } 4812@@ -2243,7 +2267,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4813 *p2++ = *p1++; 4814 *p2++ = *p1++; 4815 minP2 = p2 - 1; // Absolute path has SEP at minP2 4816- lastC = SEP; 4817+ lastC = sep; 4818 } 4819 #endif /* MS_WINDOWS */ 4820 4821@@ -2251,18 +2275,18 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4822 for (; !IS_END(p1); ++p1) { 4823 wchar_t c = *p1; 4824 #ifdef ALTSEP 4825- if (c == ALTSEP) { 4826- c = SEP; 4827+ if (c == altsep) { 4828+ c = sep; 4829 } 4830 #endif 4831- if (lastC == SEP) { 4832+ if (lastC == sep) { 4833 if (c == L'.') { 4834 int sep_at_1 = SEP_OR_END(&p1[1]); 4835 int sep_at_2 = !sep_at_1 && SEP_OR_END(&p1[2]); 4836 if (sep_at_2 && p1[1] == L'.') { 4837 wchar_t *p3 = p2; 4838- while (p3 != minP2 && *--p3 == SEP) { } 4839- while (p3 != minP2 && *(p3 - 1) != SEP) { --p3; } 4840+ while (p3 != minP2 && *--p3 == sep) { } 4841+ while (p3 != minP2 && *(p3 - 1) != sep) { --p3; } 4842 if (p2 == minP2 4843 || (p3[0] == L'.' && p3[1] == L'.' && IS_SEP(&p3[2]))) 4844 { 4845@@ -2271,7 +2295,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4846 *p2++ = L'.'; 4847 *p2++ = L'.'; 4848 lastC = L'.'; 4849- } else if (p3[0] == SEP) { 4850+ } else if (p3[0] == sep) { 4851 // Absolute path, so absorb segment 4852 p2 = p3 + 1; 4853 } else { 4854@@ -2282,7 +2306,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4855 } else { 4856 *p2++ = lastC = c; 4857 } 4858- } else if (c == SEP) { 4859+ } else if (c == sep) { 4860 } else { 4861 *p2++ = lastC = c; 4862 } 4863@@ -2292,7 +2316,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4864 } 4865 *p2 = L'\0'; 4866 if (p2 != minP2) { 4867- while (--p2 != minP2 && *p2 == SEP) { 4868+ while (--p2 != minP2 && *p2 == sep) { 4869 *p2 = L'\0'; 4870 } 4871 } else { 4872diff --git a/Python/frozenmain.c b/Python/frozenmain.c 4873index 8743e08..c6f5f19 100644 4874--- a/Python/frozenmain.c 4875+++ b/Python/frozenmain.c 4876@@ -3,6 +3,7 @@ 4877 #include "Python.h" 4878 #include "pycore_runtime.h" // _PyRuntime_Initialize() 4879 #include <locale.h> 4880+#include "iscygpty.h" 4881 4882 #ifdef MS_WINDOWS 4883 extern void PyWinFreeze_ExeInit(void); 4884@@ -71,7 +72,7 @@ Py_FrozenMain(int argc, char **argv) 4885 sts = 0; 4886 } 4887 4888- if (inspect && isatty((int)fileno(stdin))) { 4889+ if (inspect && (isatty((int)fileno(stdin)) || is_cygpty((int)fileno(stdin)))) 4890 sts = PyRun_AnyFile(stdin, "<stdin>") != 0; 4891 } 4892 4893diff --git a/Python/getcompiler.c b/Python/getcompiler.c 4894index a5d2623..4b0b9b3 100644 4895--- a/Python/getcompiler.c 4896+++ b/Python/getcompiler.c 4897@@ -7,10 +7,40 @@ 4898 4899 // Note the __clang__ conditional has to come before the __GNUC__ one because 4900 // clang pretends to be GCC. 4901-#if defined(__clang__) 4902+#if defined(__clang__) && !defined(_WIN32) 4903 #define COMPILER "[Clang " __clang_version__ "]" 4904 #elif defined(__GNUC__) 4905-#define COMPILER "[GCC " __VERSION__ "]" 4906+/* To not break compatibility with things that determine 4907+ CPU arch by calling get_build_version in msvccompiler.py 4908+ (such as NumPy) add "32 bit" or "64 bit (AMD64)" on Windows 4909+ and also use a space as a separator rather than a newline. */ 4910+#if defined(_WIN32) 4911+#define COMP_SEP " " 4912+#if defined(__x86_64__) 4913+#define ARCH_SUFFIX " 64 bit (AMD64)" 4914+#elif defined(__aarch64__) 4915+#define ARCH_SUFFIX " 64 bit (ARM64)" 4916+#elif defined(__arm__) 4917+#define ARCH_SUFFIX " 32 bit (ARM)" 4918+#else 4919+#define ARCH_SUFFIX " 32 bit" 4920+#endif 4921+#else 4922+#define COMP_SEP "\n" 4923+#define ARCH_SUFFIX "" 4924+#endif 4925+#if defined(__clang__) 4926+#define str(x) #x 4927+#define xstr(x) str(x) 4928+#define COMPILER COMP_SEP "[GCC Clang " xstr(__clang_major__) "." \ 4929+ xstr(__clang_minor__) "." xstr(__clang_patchlevel__) ARCH_SUFFIX "]" 4930+#else 4931+#if defined(_UCRT) 4932+#define COMPILER COMP_SEP "[GCC UCRT " __VERSION__ ARCH_SUFFIX "]" 4933+#else 4934+#define COMPILER COMP_SEP "[GCC " __VERSION__ ARCH_SUFFIX "]" 4935+#endif 4936+#endif 4937 // Generic fallbacks. 4938 #elif defined(__cplusplus) 4939 #define COMPILER "[C++]" 4940diff --git a/Python/initconfig.c b/Python/initconfig.c 4941index d81cbaf..c54d238 100644 4942--- a/Python/initconfig.c 4943+++ b/Python/initconfig.c 4944@@ -176,7 +176,7 @@ static const char usage_envvars[] = 4945 "PYTHONVERBOSE : trace import statements (-v)\n" 4946 "PYTHONWARNINGS=arg : warning control (-W arg)\n"; 4947 4948-#if defined(MS_WINDOWS) 4949+#if defined(_MSC_VER) 4950 # define PYTHONHOMEHELP "<prefix>\\python{major}{minor}" 4951 #else 4952 # define PYTHONHOMEHELP "<prefix>/lib/pythonX.X" 4953diff --git a/Python/iscygpty.c b/Python/iscygpty.c 4954new file mode 100644 4955index 0000000..722f88f 4956--- /dev/null 4957+++ b/Python/iscygpty.c 4958@@ -0,0 +1,185 @@ 4959+/* 4960+ * iscygpty.c -- part of ptycheck 4961+ * https://github.com/k-takata/ptycheck 4962+ * 4963+ * Copyright (c) 2015-2017 K.Takata 4964+ * 4965+ * You can redistribute it and/or modify it under the terms of either 4966+ * the MIT license (as described below) or the Vim license. 4967+ * 4968+ * Permission is hereby granted, free of charge, to any person obtaining 4969+ * a copy of this software and associated documentation files (the 4970+ * "Software"), to deal in the Software without restriction, including 4971+ * without limitation the rights to use, copy, modify, merge, publish, 4972+ * distribute, sublicense, and/or sell copies of the Software, and to 4973+ * permit persons to whom the Software is furnished to do so, subject to 4974+ * the following conditions: 4975+ * 4976+ * The above copyright notice and this permission notice shall be 4977+ * included in all copies or substantial portions of the Software. 4978+ * 4979+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 4980+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 4981+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 4982+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 4983+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 4984+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 4985+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 4986+ */ 4987+ 4988+#ifdef _WIN32 4989+ 4990+#include <ctype.h> 4991+#include <io.h> 4992+#include <wchar.h> 4993+#include <windows.h> 4994+ 4995+#ifdef USE_FILEEXTD 4996+/* VC 7.1 or earlier doesn't support SAL. */ 4997+# if !defined(_MSC_VER) || (_MSC_VER < 1400) 4998+# define __out 4999+# define __in 5000+# define __in_opt 5001+# endif 5002+/* Win32 FileID API Library: 5003+ * http://www.microsoft.com/en-us/download/details.aspx?id=22599 5004+ * Needed for WinXP. */ 5005+# include <fileextd.h> 5006+#else /* USE_FILEEXTD */ 5007+/* VC 8 or earlier. */ 5008+# if defined(_MSC_VER) && (_MSC_VER < 1500) 5009+# ifdef ENABLE_STUB_IMPL 5010+# define STUB_IMPL 5011+# else 5012+# error "Win32 FileID API Library is required for VC2005 or earlier." 5013+# endif 5014+# endif 5015+#endif /* USE_FILEEXTD */ 5016+ 5017+ 5018+#include "iscygpty.h" 5019+ 5020+//#define USE_DYNFILEID 5021+#ifdef USE_DYNFILEID 5022+typedef BOOL (WINAPI *pfnGetFileInformationByHandleEx)( 5023+ HANDLE hFile, 5024+ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, 5025+ LPVOID lpFileInformation, 5026+ DWORD dwBufferSize 5027+); 5028+static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL; 5029+ 5030+# ifndef USE_FILEEXTD 5031+static BOOL WINAPI stub_GetFileInformationByHandleEx( 5032+ HANDLE hFile, 5033+ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, 5034+ LPVOID lpFileInformation, 5035+ DWORD dwBufferSize 5036+ ) 5037+{ 5038+ return FALSE; 5039+} 5040+# endif 5041+ 5042+static void setup_fileid_api(void) 5043+{ 5044+ if (pGetFileInformationByHandleEx != NULL) { 5045+ return; 5046+ } 5047+ pGetFileInformationByHandleEx = (pfnGetFileInformationByHandleEx) 5048+ GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), 5049+ "GetFileInformationByHandleEx"); 5050+ if (pGetFileInformationByHandleEx == NULL) { 5051+# ifdef USE_FILEEXTD 5052+ pGetFileInformationByHandleEx = GetFileInformationByHandleEx; 5053+# else 5054+ pGetFileInformationByHandleEx = stub_GetFileInformationByHandleEx; 5055+# endif 5056+ } 5057+} 5058+#else 5059+# define pGetFileInformationByHandleEx GetFileInformationByHandleEx 5060+# define setup_fileid_api() 5061+#endif 5062+ 5063+ 5064+#define is_wprefix(s, prefix) \ 5065+ (wcsncmp((s), (prefix), sizeof(prefix) / sizeof(WCHAR) - 1) == 0) 5066+ 5067+/* Check if the fd is a cygwin/msys's pty. */ 5068+int is_cygpty(int fd) 5069+{ 5070+#ifdef STUB_IMPL 5071+ return 0; 5072+#else 5073+ HANDLE h; 5074+ int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * (MAX_PATH - 1); 5075+ FILE_NAME_INFO *nameinfo; 5076+ WCHAR *p = NULL; 5077+ 5078+ setup_fileid_api(); 5079+ 5080+ h = (HANDLE) _get_osfhandle(fd); 5081+ if (h == INVALID_HANDLE_VALUE) { 5082+ return 0; 5083+ } 5084+ /* Cygwin/msys's pty is a pipe. */ 5085+ if (GetFileType(h) != FILE_TYPE_PIPE) { 5086+ return 0; 5087+ } 5088+ nameinfo = malloc(size + sizeof(WCHAR)); 5089+ if (nameinfo == NULL) { 5090+ return 0; 5091+ } 5092+ /* Check the name of the pipe: 5093+ * '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master' */ 5094+ if (pGetFileInformationByHandleEx(h, FileNameInfo, nameinfo, size)) { 5095+ nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0'; 5096+ p = nameinfo->FileName; 5097+ if (is_wprefix(p, L"\\cygwin-")) { /* Cygwin */ 5098+ p += 8; 5099+ } else if (is_wprefix(p, L"\\msys-")) { /* MSYS and MSYS2 */ 5100+ p += 6; 5101+ } else { 5102+ p = NULL; 5103+ } 5104+ if (p != NULL) { 5105+ while (*p && isxdigit(*p)) /* Skip 16-digit hexadecimal. */ 5106+ ++p; 5107+ if (is_wprefix(p, L"-pty")) { 5108+ p += 4; 5109+ } else { 5110+ p = NULL; 5111+ } 5112+ } 5113+ if (p != NULL) { 5114+ while (*p && isdigit(*p)) /* Skip pty number. */ 5115+ ++p; 5116+ if (is_wprefix(p, L"-from-master")) { 5117+ //p += 12; 5118+ } else if (is_wprefix(p, L"-to-master")) { 5119+ //p += 10; 5120+ } else { 5121+ p = NULL; 5122+ } 5123+ } 5124+ } 5125+ free(nameinfo); 5126+ return (p != NULL); 5127+#endif /* STUB_IMPL */ 5128+} 5129+ 5130+/* Check if at least one cygwin/msys pty is used. */ 5131+int is_cygpty_used(void) 5132+{ 5133+ int fd, ret = 0; 5134+ 5135+ for (fd = 0; fd < 3; fd++) { 5136+ ret |= is_cygpty(fd); 5137+ } 5138+ return ret; 5139+} 5140+ 5141+#endif /* _WIN32 */ 5142+ 5143+/* vim: set ts=4 sw=4: */ 5144diff --git a/Python/pathconfig.c b/Python/pathconfig.c 5145index be0f97c..7eb9006 100644 5146--- a/Python/pathconfig.c 5147+++ b/Python/pathconfig.c 5148@@ -2,7 +2,7 @@ 5149 5150 #include "Python.h" 5151 #include "marshal.h" // PyMarshal_ReadObjectFromString 5152-#include "osdefs.h" // DELIM 5153+#include "osdefs.h" // DELIM, SEP 5154 #include "pycore_initconfig.h" 5155 #include "pycore_fileutils.h" 5156 #include "pycore_pathconfig.h" 5157@@ -18,6 +18,158 @@ 5158 extern "C" { 5159 #endif 5160 5161+#ifdef __MINGW32__ 5162+#define wcstok wcstok_s 5163+#include <windows.h> 5164+#endif 5165+ 5166+static int 5167+Py_StartsWithA(const char * str, const char * prefix) 5168+{ 5169+ while(*prefix) 5170+ { 5171+ if(*prefix++ != *str++) 5172+ return 0; 5173+ } 5174+ 5175+ return 1; 5176+} 5177+ 5178+static int 5179+Py_StartsWithW(const wchar_t * str, const wchar_t * prefix) 5180+{ 5181+ while(*prefix) 5182+ { 5183+ if(*prefix++ != *str++) 5184+ return 0; 5185+ } 5186+ 5187+ return 1; 5188+} 5189+ 5190+char 5191+Py_GetSepA(const char *name) 5192+{ 5193+ static char sep = '\0'; 5194+#ifdef _WIN32 5195+ /* https://msdn.microsoft.com/en-gb/library/windows/desktop/aa365247%28v=vs.85%29.aspx 5196+ * The "\\?\" prefix .. indicate that the path should be passed to the system with minimal 5197+ * modification, which means that you cannot use forward slashes to represent path separators 5198+ */ 5199+ if (name != NULL && Py_StartsWithA(name, "\\\\?\\") != 0) 5200+ { 5201+ return '\\'; 5202+ } 5203+#endif 5204+ if (sep != '\0') 5205+ return sep; 5206+#if defined(__MINGW32__) 5207+ char* msystem = getenv("MSYSTEM"); 5208+ if (msystem != NULL && strcmp(msystem, "") != 0) 5209+ sep = '/'; 5210+ else 5211+ sep = '\\'; 5212+#else 5213+ sep = SEP; 5214+#endif 5215+ return sep; 5216+} 5217+ 5218+static char 5219+Py_GetAltSepA(const char *name) 5220+{ 5221+ char sep = Py_GetSepA(name); 5222+ if (sep == '/') 5223+ return '\\'; 5224+ return '/'; 5225+} 5226+ 5227+void 5228+Py_NormalizeSepsA(char *name) 5229+{ 5230+ assert(name != NULL); 5231+ char sep = Py_GetSepA(name); 5232+ char altsep = Py_GetAltSepA(name); 5233+ char* seps; 5234+ if (name[0] != '\0' && name[1] == ':') { 5235+ name[0] = toupper(name[0]); 5236+ } 5237+ seps = strchr(name, altsep); 5238+ while(seps) { 5239+ *seps = sep; 5240+ seps = strchr(seps, altsep); 5241+ } 5242+} 5243+ 5244+wchar_t 5245+Py_GetSepW(const wchar_t *name) 5246+{ 5247+ static wchar_t sep = L'\0'; 5248+#ifdef _WIN32 5249+ /* https://msdn.microsoft.com/en-gb/library/windows/desktop/aa365247%28v=vs.85%29.aspx 5250+ * The "\\?\" prefix .. indicate that the path should be passed to the system with minimal 5251+ * modification, which means that you cannot use forward slashes to represent path separators 5252+ */ 5253+ if (name != NULL && Py_StartsWithW(name, L"\\\\?\\") != 0) 5254+ { 5255+ return L'\\'; 5256+ } 5257+#endif 5258+ if (sep != L'\0') 5259+ return sep; 5260+#if defined(__MINGW32__) 5261+ char* msystem = getenv("MSYSTEM"); 5262+ if (msystem != NULL && strcmp(msystem, "") != 0) 5263+ sep = L'/'; 5264+ else 5265+ sep = L'\\'; 5266+#else 5267+ sep = SEP; 5268+#endif 5269+ return sep; 5270+} 5271+ 5272+wchar_t 5273+Py_GetAltSepW(const wchar_t *name) 5274+{ 5275+ char sep = Py_GetSepW(name); 5276+ if (sep == L'/') 5277+ return L'\\'; 5278+ return L'/'; 5279+} 5280+ 5281+void 5282+Py_NormalizeSepsW(wchar_t *name) 5283+{ 5284+ assert(name != NULL); 5285+ wchar_t sep = Py_GetSepW(name); 5286+ wchar_t altsep = Py_GetAltSepW(name); 5287+ wchar_t* seps; 5288+ if (name[0] != L'\0' && name[1] == L':') { 5289+ name[0] = towupper(name[0]); 5290+ } 5291+ seps = wcschr(name, altsep); 5292+ while(seps) { 5293+ *seps = sep; 5294+ seps = wcschr(seps, altsep); 5295+ } 5296+} 5297+ 5298+void 5299+Py_NormalizeSepsPathcchW(wchar_t *name) 5300+{ 5301+#ifdef MS_WINDOWS 5302+ assert(name != NULL); 5303+ wchar_t sep = '\\'; 5304+ wchar_t altsep = '/'; 5305+ wchar_t* seps; 5306+ seps = wcschr(name, altsep); 5307+ while(seps) { 5308+ *seps = sep; 5309+ seps = wcschr(seps, altsep); 5310+ } 5311+#endif 5312+} 5313 5314 /* External interface */ 5315 5316@@ -317,6 +469,7 @@ _Py_SetProgramFullPath(const wchar_t *program_full_path) 5317 if (has_value && _Py_path_config.program_full_path == NULL) { 5318 path_out_of_memory(__func__); 5319 } 5320+ Py_NormalizeSepsW(_Py_path_config.program_name); 5321 } 5322 5323 5324@@ -509,7 +662,7 @@ _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) 5325 } 5326 #endif /* All others */ 5327 5328- PyObject *path0_obj = PyUnicode_FromWideChar(path0, n); 5329+ PyObject *path0_obj = PyUnicode_FromWideChar(_Py_normpath(path0, -1), n); 5330 if (path0_obj == NULL) { 5331 return -1; 5332 } 5333diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c 5334index 9248e97..1d53e12 100644 5335--- a/Python/pylifecycle.c 5336+++ b/Python/pylifecycle.c 5337@@ -31,6 +31,7 @@ 5338 5339 extern void _PyIO_Fini(void); 5340 5341+#include "iscygpty.h" 5342 #include <locale.h> // setlocale() 5343 #include <stdlib.h> // getenv() 5344 5345@@ -2954,7 +2955,7 @@ Py_Exit(int sts) 5346 int 5347 Py_FdIsInteractive(FILE *fp, const char *filename) 5348 { 5349- if (isatty((int)fileno(fp))) 5350+ if (isatty((int)fileno(fp)) || is_cygpty((int)fileno(fp))) 5351 return 1; 5352 if (!Py_InteractiveFlag) 5353 return 0; 5354@@ -2967,7 +2968,7 @@ Py_FdIsInteractive(FILE *fp, const char *filename) 5355 int 5356 _Py_FdIsInteractive(FILE *fp, PyObject *filename) 5357 { 5358- if (isatty((int)fileno(fp))) { 5359+ if (isatty((int)fileno(fp)) || is_cygpty((int)fileno(fp))) { 5360 return 1; 5361 } 5362 if (!Py_InteractiveFlag) { 5363diff --git a/Python/sysmodule.c b/Python/sysmodule.c 5364index 8bab703..fed0adb 100644 5365--- a/Python/sysmodule.c 5366+++ b/Python/sysmodule.c 5367@@ -43,7 +43,7 @@ Data members: 5368 #include <windows.h> 5369 #endif /* MS_WINDOWS */ 5370 5371-#ifdef MS_COREDLL 5372+#if defined(MS_WINDOWS) && defined(Py_ENABLE_SHARED) 5373 extern void *PyWin_DLLhModule; 5374 /* A string loaded from the DLL at startup: */ 5375 extern const char *PyWin_DLLVersionString; 5376@@ -2923,7 +2923,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) 5377 SET_SYS_FROM_STRING("byteorder", "little"); 5378 #endif 5379 5380-#ifdef MS_COREDLL 5381+#if defined(MS_WINDOWS) && defined(Py_ENABLE_SHARED) 5382 SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule)); 5383 SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString); 5384 #endif 5385diff --git a/Python/thread_nt.h b/Python/thread_nt.h 5386index 084bd58..f8a6765 100644 5387--- a/Python/thread_nt.h 5388+++ b/Python/thread_nt.h 5389@@ -360,8 +360,9 @@ PyThread_release_lock(PyThread_type_lock aLock) 5390 { 5391 dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); 5392 5393- if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) 5394+ if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) { 5395 dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError())); 5396+ } 5397 } 5398 5399 /* minimum/maximum thread stack sizes supported */ 5400diff --git a/Python/traceback.c b/Python/traceback.c 5401index 7f47349..23fda62 100644 5402--- a/Python/traceback.c 5403+++ b/Python/traceback.c 5404@@ -323,7 +323,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * 5405 filepath = PyBytes_AS_STRING(filebytes); 5406 5407 /* Search tail of filename in sys.path before giving up */ 5408- tail = strrchr(filepath, SEP); 5409+ tail = strrchr(filepath, Py_GetSepA(filepath)); 5410 if (tail == NULL) 5411 tail = filepath; 5412 else 5413diff --git a/configure.ac b/configure.ac 5414index 1c25abd..5cf7085 100644 5415--- a/configure.ac 5416+++ b/configure.ac 5417@@ -202,9 +202,11 @@ AC_SUBST([FREEZE_MODULE]) 5418 AC_SUBST([FREEZE_MODULE_DEPS]) 5419 AC_SUBST([PYTHON_FOR_BUILD_DEPS]) 5420 5421+NATIVE_PYTHON_SEARCH_PATH_MINGW=`echo $host | grep -Eq 'mingw*' && echo "$MINGW_PREFIX/bin" || echo $PATH` 5422 AC_CHECK_PROGS([PYTHON_FOR_REGEN], 5423 [python$PACKAGE_VERSION python3.10 python3.9 python3.8 python3.7 python3.6 python3 python], 5424- [python3]) 5425+ [python3], 5426+ [$NATIVE_PYTHON_SEARCH_PATH_MINGW]) 5427 AC_SUBST(PYTHON_FOR_REGEN) 5428 5429 AC_MSG_CHECKING([Python for regen version]) 5430@@ -545,6 +547,9 @@ then 5431 *-*-cygwin*) 5432 ac_sys_system=Cygwin 5433 ;; 5434+ *-*-mingw*) 5435+ ac_sys_system=MINGW 5436+ ;; 5437 *-*-vxworks*) 5438 ac_sys_system=VxWorks 5439 ;; 5440@@ -580,6 +585,7 @@ then 5441 linux*) MACHDEP="linux";; 5442 cygwin*) MACHDEP="cygwin";; 5443 darwin*) MACHDEP="darwin";; 5444+ mingw*) MACHDEP="win32";; 5445 '') MACHDEP="unknown";; 5446 esac 5447 fi 5448@@ -605,6 +611,9 @@ if test "$cross_compiling" = yes; then 5449 ;; 5450 wasm32-*-* | wasm64-*-*) 5451 _host_cpu=$host_cpu 5452+ ;; 5453+ *-*-mingw*) 5454+ _host_cpu= 5455 ;; 5456 *) 5457 # for now, limit cross builds to known configurations 5458@@ -612,6 +621,14 @@ if test "$cross_compiling" = yes; then 5459 AC_MSG_ERROR([cross build not supported for $host]) 5460 esac 5461 _PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}" 5462+ 5463+ case "$host_os" in 5464+ mingw*) 5465+ # As sys.platform() return 'win32' to build python and extantions 5466+ # we will use 'mingw' (in setup.py and etc.) 5467+ _PYTHON_HOST_PLATFORM=mingw 5468+ ;; 5469+ esac 5470 fi 5471 5472 # Some systems cannot stand _XOPEN_SOURCE being defined at all; they 5473@@ -723,6 +740,65 @@ then 5474 AC_DEFINE(_INCLUDE__STDC_A1_SOURCE, 1, Define to include mbstate_t for mbrtowc) 5475 fi 5476 5477+# On 'semi-native' build systems (MSYS*/Cygwin targeting MinGW-w64) 5478+# _sysconfigdata.py will contain paths that are correct only in the 5479+# build environment. This means external modules will fail to build 5480+# without setting up the same env and also that the build of Python 5481+# itself will fail as the paths are not correct for the host tools. 5482+# 5483+# To work around these issues a set of _b2h variables are created: 5484+# prefix_b2h, srcdir_b2h, abs_srcdir_b2h 5485+# and abs_builddir_b2h 5486+# .. where b2h stands for build to host. sysconfig.py replaces path 5487+# prefixes matching the non-b2h versions with the b2h equivalents. 5488+# 5489+# (note this assumes the host compilers are native and *not* cross 5490+# - in the 'semi-native' scenario only that is.) 5491+ 5492+AC_DEFUN([ABS_PATH_HOST], 5493+[$1=$(cd $$2 && pwd) 5494+ case $build_os in 5495+ mingw*) 5496+ case $host_os in 5497+ mingw*) $1=$(cd $$2 && pwd -W) ;; 5498+ *) ;; 5499+ esac 5500+ ;; 5501+ cygwin*) 5502+ case $host_os in 5503+ mingw*) $1=$(cygpath -w -m $$2) ;; 5504+ *) ;; 5505+ esac 5506+ ;; 5507+ esac 5508+AC_SUBST([$1]) 5509+]) 5510+ 5511+AC_MSG_CHECKING(absolute host location of prefix) 5512+ABS_PATH_HOST([prefix_b2h],[prefix]) 5513+AC_MSG_RESULT([$prefix_b2h]) 5514+ 5515+AC_MSG_CHECKING(absolute host location of srcdir) 5516+ABS_PATH_HOST([srcdir_b2h],[srcdir]) 5517+AC_MSG_RESULT([$srcdir_b2h]) 5518+ 5519+AC_MSG_CHECKING(absolute host location of abs_srcdir) 5520+ABS_PATH_HOST([abs_srcdir_b2h],[srcdir]) 5521+AC_MSG_RESULT([$abs_srcdir_b2h]) 5522+ 5523+my_builddir=. 5524+AC_MSG_CHECKING(Absolute host location of abs_builddir) 5525+ABS_PATH_HOST([abs_builddir_b2h],[my_builddir]) 5526+AC_MSG_RESULT([$abs_builddir_b2h]) 5527+ 5528+AC_MSG_CHECKING([for init system calls]) 5529+AC_SUBST(INITSYS) 5530+case $host in 5531+ *-*-mingw*) INITSYS=nt;; 5532+ *) INITSYS=posix;; 5533+esac 5534+AC_MSG_RESULT([$INITSYS]) 5535+ 5536 # Record the configure-time value of MACOSX_DEPLOYMENT_TARGET, 5537 # it may influence the way we can build extensions, so distutils 5538 # needs to check it 5539@@ -1163,6 +1239,28 @@ AC_CACHE_CHECK([for -Wl,--no-as-needed], [ac_cv_wl_no_as_needed], [ 5540 ]) 5541 AC_SUBST(NO_AS_NEEDED) 5542 5543+# initialize default configuration 5544+py_config= 5545+case $host in 5546+ *-*-mingw*) py_config=mingw ;; 5547+esac 5548+if test -n "$py_config" ; then 5549+ AC_MSG_NOTICE([loading configure defaults from .../Misc/config_$py_config"]) 5550+ . "$srcdir/Misc/config_$py_config" 5551+fi 5552+ 5553+# initialize defaults for cross-builds 5554+if test "$cross_compiling" = yes; then 5555+ py_config=$host_os 5556+ case $py_config in 5557+ mingw32*) py_config=mingw32 ;; 5558+ esac 5559+ if test -f "$srcdir/Misc/cross_$py_config" ; then 5560+ AC_MSG_NOTICE([loading cross defaults from .../Misc/cross_$py_config"]) 5561+ . "$srcdir/Misc/cross_$py_config" 5562+ fi 5563+fi 5564+ 5565 AC_MSG_CHECKING([for the Android API level]) 5566 cat > conftest.c <<EOF 5567 #ifdef __ANDROID__ 5568@@ -1275,6 +1373,7 @@ AC_ARG_WITH([suffix], 5569 [Emscripten/browser*], [EXEEXT=.js], 5570 [Emscripten/node*], [EXEEXT=.js], 5571 [WASI/*], [EXEEXT=.wasm], 5572+ [MINGW*], [EXEEXT=.exe], 5573 [EXEEXT=] 5574 ) 5575 ]) 5576@@ -1298,6 +1397,10 @@ else 5577 fi 5578 rmdir CaseSensitiveTestDir 5579 5580+AS_CASE([$ac_sys_system], 5581+ [MINGW], [BUILDEXEEXT=".exe"] 5582+) 5583+ 5584 case $ac_sys_system in 5585 hp*|HP*) 5586 case $CC in 5587@@ -1475,6 +1578,11 @@ if test $enable_shared = "yes"; then 5588 LDLIBRARY='libpython$(LDVERSION).dll.a' 5589 DLLLIBRARY='libpython$(LDVERSION).dll' 5590 ;; 5591+ MINGW*) 5592+ LDLIBRARY='libpython$(LDVERSION).dll.a' 5593+ DLLLIBRARY='libpython$(LDVERSION).dll' 5594+ BLDLIBRARY='-L. -lpython$(LDVERSION)' 5595+ ;; 5596 SunOS*) 5597 LDLIBRARY='libpython$(LDVERSION).so' 5598 BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)' 5599@@ -1525,6 +1633,9 @@ else # shared is disabled 5600 BLDLIBRARY='$(LIBRARY)' 5601 LDLIBRARY='libpython$(LDVERSION).dll.a' 5602 ;; 5603+ MINGW*) 5604+ LDLIBRARY='libpython$(LDVERSION).a' 5605+ ;; 5606 esac 5607 fi 5608 5609@@ -1618,6 +1729,10 @@ AC_SUBST(LINK_PYTHON_OBJS) 5610 AC_SUBST(AR) 5611 AC_CHECK_TOOLS(AR, ar aal, ar) 5612 5613+# windres program 5614+AC_SUBST(WINDRES) 5615+AC_CHECK_TOOL(WINDRES, windres) 5616+ 5617 # tweak ARFLAGS only if the user didn't set it on the command line 5618 AC_SUBST(ARFLAGS) 5619 if test -z "$ARFLAGS" 5620@@ -2498,6 +2613,53 @@ then 5621 BASECFLAGS="$BASECFLAGS $ac_arch_flags" 5622 fi 5623 5624+dnl NOTE: 5625+dnl - GCC 4.4+ for mingw* require and use posix threads(pthreads-w32) 5626+dnl - Host may contain installed pthreads-w32. 5627+dnl - On windows platform only NT-thread model is supported. 5628+dnl To avoid miss detection scipt first will check for NT-thread model 5629+dnl and if is not found will try to detect build options for pthread 5630+dnl model. Autodetection could be overiden if variable with_nt_threads 5631+dnl is set in "Site Configuration" (see autoconf manual). 5632+dnl If NT-thread model is enabled script skips some checks that 5633+dnl impact build process. When a new functionality is added, developers 5634+dnl are responsible to update configure script to avoid thread models 5635+dnl to be mixed. 5636+ 5637+AC_MSG_CHECKING([for --with-nt-threads]) 5638+AC_ARG_WITH(nt-threads, 5639+ AS_HELP_STRING([--with-nt-threads], [build with windows threads (default is system-dependent)]), 5640+[ 5641+ case $withval in 5642+ no) with_nt_threads=no;; 5643+ yes) with_nt_threads=yes;; 5644+ *) with_nt_threads=yes;; 5645+ esac 5646+], [ 5647+ case $host in 5648+ *-*-mingw*) with_nt_threads=yes;; 5649+ *) with_nt_threads=no;; 5650+ esac 5651+]) 5652+AC_MSG_RESULT([$with_nt_threads]) 5653+ 5654+if test $with_nt_threads = yes ; then 5655+AC_MSG_CHECKING([whether linking with nt-threads work]) 5656+AC_LINK_IFELSE([ 5657+ AC_LANG_PROGRAM([[#include <process.h>]],[[_beginthread(0, 0, 0);]]) 5658+ ], 5659+ [AC_MSG_RESULT([yes])], 5660+ [AC_MSG_ERROR([failed to link with nt-threads])]) 5661+fi 5662+ 5663+if test $with_nt_threads = yes ; then 5664+ dnl temporary default flag to avoid additional pthread checks 5665+ dnl and initilize other ac..thread flags to no 5666+ ac_cv_pthread_is_default=no 5667+ ac_cv_kthread=no 5668+ ac_cv_pthread=no 5669+ dnl ac_cv_kpthread is set to no if default is yes (see below) 5670+else 5671 # On some compilers, pthreads are available without further options 5672 # (e.g. MacOS X). On some of these systems, the compiler will not 5673 # complain if unaccepted options are passed (e.g. gcc on Mac OS X). 5674@@ -2609,6 +2771,8 @@ int main(void){ 5675 CC="$ac_save_cc"]) 5676 fi 5677 5678+fi 5679+ 5680 # If we have set a CC compiler flag for thread support then 5681 # check if it works for CXX, too. 5682 ac_cv_cxx_thread=no 5683@@ -2629,6 +2793,10 @@ elif test "$ac_cv_pthread" = "yes" 5684 then 5685 CXX="$CXX -pthread" 5686 ac_cv_cxx_thread=yes 5687+elif test $with_nt_threads = yes 5688+then 5689+ dnl set to always to skip extra pthread check below 5690+ ac_cv_cxx_thread=always 5691 fi 5692 5693 if test $ac_cv_cxx_thread = yes 5694@@ -2663,11 +2831,11 @@ AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.]) 5695 5696 # checks for header files 5697 AC_CHECK_HEADERS([ \ 5698- alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ 5699+ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h endian.h errno.h fcntl.h grp.h \ 5700 ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/memfd.h \ 5701 linux/random.h linux/soundcard.h \ 5702- linux/tipc.h linux/wait.h netdb.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ 5703- sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ 5704+ linux/tipc.h linux/wait.h netdb.h netinet/in.h netpacket/packet.h poll.h process.h pty.h \ 5705+ setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ 5706 sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ 5707 sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \ 5708 sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \ 5709@@ -2675,9 +2843,24 @@ AC_CHECK_HEADERS([ \ 5710 sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \ 5711 termios.h util.h utime.h utmp.h \ 5712 ]) 5713+ 5714+case $host in 5715+ *-*-mingw*) ;; 5716+ *) AC_CHECK_HEADERS([dlfcn.h]);; 5717+esac 5718+ 5719+ 5720 AC_HEADER_DIRENT 5721 AC_HEADER_MAJOR 5722 5723+# If using nt threads, don't look for pthread.h or thread.h 5724+if test "x$with_nt_threads" = xno ; then 5725+AC_HEADER_STDC 5726+AC_CHECK_HEADERS(pthread.h sched.h thread.h) 5727+AC_HEADER_DIRENT 5728+AC_HEADER_MAJOR 5729+fi 5730+ 5731 # bluetooth/bluetooth.h has been known to not compile with -std=c99. 5732 # http://permalink.gmane.org/gmane.linux.bluez.kernel/22294 5733 SAVE_CFLAGS=$CFLAGS 5734@@ -2852,6 +3035,10 @@ dnl LFS does not work with Emscripten 3.1 5735 AS_CASE([$ac_sys_system], 5736 [Emscripten], [have_largefile_support="no"] 5737 ) 5738+dnl Activate on windows platforms (32&64-bit) where off_t(4) < fpos_t(8) 5739+AS_CASE([$ac_sys_system], 5740+ [MINGW], [have_largefile_support="yes"] 5741+) 5742 AS_VAR_IF([have_largefile_support], [yes], [ 5743 AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, 5744 [Defined to enable large file support when an off_t is bigger than a long 5745@@ -2882,6 +3069,10 @@ elif test "$ac_cv_pthread" = "yes" 5746 then CC="$CC -pthread" 5747 fi 5748 5749+if test $with_nt_threads = yes ; then 5750+ dnl skip check for pthread_t if NT-thread model is enabled 5751+ ac_cv_have_pthread_t=skip 5752+else 5753 AC_CACHE_CHECK([for pthread_t], [ac_cv_have_pthread_t], [ 5754 AC_COMPILE_IFELSE([ 5755 AC_LANG_PROGRAM([[#include <pthread.h>]], [[pthread_t x; x = *(pthread_t*)0;]]) 5756@@ -2913,7 +3104,7 @@ AS_VAR_IF([ac_cv_pthread_key_t_is_arithmetic_type], [yes], [ 5757 AC_DEFINE(PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT, 1, 5758 [Define if pthread_key_t is compatible with int.]) 5759 ]) 5760- 5761+fi 5762 CC="$ac_save_cc" 5763 5764 AC_SUBST(OTHER_LIBTOOL_OPT) 5765@@ -3089,6 +3280,9 @@ if test -z "$SHLIB_SUFFIX"; then 5766 CYGWIN*) SHLIB_SUFFIX=.dll;; 5767 *) SHLIB_SUFFIX=.so;; 5768 esac 5769+ case $host_os in 5770+ mingw*) SHLIB_SUFFIX=.pyd;; 5771+ esac 5772 fi 5773 AC_MSG_RESULT($SHLIB_SUFFIX) 5774 5775@@ -3218,6 +3412,10 @@ then 5776 CYGWIN*) 5777 LDSHARED="gcc -shared -Wl,--enable-auto-image-base" 5778 LDCXXSHARED="g++ -shared -Wl,--enable-auto-image-base";; 5779+ MINGW*) 5780+ LDSHARED='$(CC) -shared -Wl,--enable-auto-image-base' 5781+ LDCXXSHARED='$(CXX) -shared -Wl,--enable-auto-image-base' 5782+ ;; 5783 *) LDSHARED="ld";; 5784 esac 5785 fi 5786@@ -3341,6 +3539,11 @@ then 5787 VxWorks*) 5788 LINKFORSHARED='-Wl,-export-dynamic';; 5789 esac 5790+ case $host in 5791+ *-*-mingw*) 5792+ # for https://bugs.python.org/issue40458 on MINGW 5793+ LINKFORSHARED="-Wl,--stack,2000000";; 5794+ esac 5795 fi 5796 AC_MSG_RESULT($LINKFORSHARED) 5797 5798@@ -3385,7 +3588,12 @@ AC_MSG_RESULT($SHLIBS) 5799 5800 # checks for libraries 5801 AC_CHECK_LIB(sendfile, sendfile) 5802-AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV 5803+ 5804+case $host in 5805+ *-*-mingw*) ;; 5806+ *) AC_CHECK_LIB(dl, dlopen) ;; # Dynamic linking for SunOS/Solaris and SYSV 5807+esac 5808+ 5809 AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX 5810 5811 5812@@ -3448,16 +3656,30 @@ AS_VAR_IF([have_uuid], [missing], [ 5813 5814 AS_VAR_IF([have_uuid], [missing], [have_uuid=no]) 5815 5816+if test $with_nt_threads = yes ; then 5817+ dnl do not search for sem_init if NT-thread model is enabled 5818+ : 5819+else 5820 # 'Real Time' functions on Solaris 5821 # posix4 on Solaris 2.6 5822 # pthread (first!) on Linux 5823 AC_SEARCH_LIBS(sem_init, pthread rt posix4) 5824+fi 5825 5826 # check if we need libintl for locale functions 5827+case $host in 5828+ *-*-mingw*) 5829+ dnl Native windows build don't use libintl (see _localemodule.c). 5830+ dnl Also we don't like setup.py to add "intl" library to the list 5831+ dnl when build _locale module. 5832+ ;; 5833+ *) 5834 AC_CHECK_LIB(intl, textdomain, 5835 [AC_DEFINE(WITH_LIBINTL, 1, 5836 [Define to 1 if libintl is needed for locale functions.]) 5837 LIBS="-lintl $LIBS"]) 5838+ ;; 5839+esac 5840 5841 # checks for system dependent C++ extensions support 5842 case "$ac_sys_system" in 5843@@ -3645,7 +3867,7 @@ else 5844 fi 5845 5846 if test "$with_system_ffi" = "yes" && test -n "$PKG_CONFIG"; then 5847- LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ *$//'`" 5848+ LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ .*$//'`" 5849 else 5850 LIBFFI_INCLUDEDIR="" 5851 fi 5852@@ -3780,6 +4002,12 @@ AS_CASE([$ac_sys_system], 5853 [OSSAUDIODEV_LIBS=""] 5854 ) 5855 5856+dnl On MINGW, you need to link against ws2_32 and iphlpapi for sockets to work 5857+AS_CASE([$ac_sys_system], 5858+ [MINGW], [SOCKET_LIBS="-lws2_32 -liphlpapi"], 5859+ [SOCKET_LIBS=""] 5860+) 5861+ 5862 dnl detect sqlite3 from Emscripten emport 5863 PY_CHECK_EMSCRIPTEN_PORT([LIBSQLITE3], [-sUSE_SQLITE3]) 5864 5865@@ -4042,6 +4270,18 @@ AS_VAR_IF([with_dbmliborder], [error], [ 5866 ]) 5867 AC_MSG_RESULT($with_dbmliborder) 5868 5869+case $host in 5870+ *-*-mingw*) 5871+ CFLAGS_NODIST="$CFLAGS_NODIST -D_WIN32_WINNT=0x0602";; 5872+esac 5873+ 5874+# Determine if windows modules should be used. 5875+AC_SUBST(USE_WIN32_MODULE) 5876+USE_WIN32_MODULE='#' 5877+case $host in 5878+ *-*-mingw*) USE_WIN32_MODULE=;; 5879+esac 5880+ 5881 # Templates for things AC_DEFINEd more than once. 5882 # For a single AC_DEFINE, no template is needed. 5883 AH_TEMPLATE(_REENTRANT, 5884@@ -4076,6 +4316,11 @@ then 5885 CXX="$CXX -pthread" 5886 fi 5887 posix_threads=yes 5888+elif test $with_nt_threads = yes 5889+then 5890+ posix_threads=no 5891+ AC_DEFINE(NT_THREADS, 1, 5892+ [Define to 1 if you want to use native NT threads]) 5893 else 5894 if test ! -z "$withval" -a -d "$withval" 5895 then LDFLAGS="$LDFLAGS -L$withval" 5896@@ -4450,11 +4695,14 @@ AC_MSG_RESULT($with_freelists) 5897 AC_MSG_CHECKING(for --with-c-locale-coercion) 5898 AC_ARG_WITH(c-locale-coercion, 5899 AS_HELP_STRING([--with-c-locale-coercion], 5900- [enable C locale coercion to a UTF-8 based locale (default is yes)])) 5901+ [enable C locale coercion to a UTF-8 based locale (default is yes on Unix, no on Windows)])) 5902 5903 if test -z "$with_c_locale_coercion" 5904 then 5905- with_c_locale_coercion="yes" 5906+ case $host in 5907+ *-*-mingw*) with_c_locale_coercion="no";; 5908+ *) with_c_locale_coercion="yes";; 5909+ esac 5910 fi 5911 if test "$with_c_locale_coercion" != "no" 5912 then 5913@@ -4555,12 +4803,36 @@ then 5914 fi 5915 ;; 5916 esac 5917+ case $host in 5918+ *-*-mingw*) 5919+ DYNLOADFILE="dynload_win.o" 5920+ extra_machdep_objs="$extra_machdep_objs PC/dl_nt.o" 5921+ CFLAGS_NODIST="$CFLAGS_NODIST -DPY3_DLLNAME='L\"$DLLLIBRARY\"'" 5922+ case $host in 5923+ i686*) 5924+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-32\"'" 5925+ ;; 5926+ armv7*) 5927+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-arm32\"'" 5928+ ;; 5929+ aarch64*) 5930+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-arm64\"'" 5931+ ;; 5932+ *) 5933+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"$VERSION\"'" 5934+ ;; 5935+ esac 5936+ ;; 5937+ esac 5938 fi 5939 AC_MSG_RESULT($DYNLOADFILE) 5940 if test "$DYNLOADFILE" != "dynload_stub.o" 5941 then 5942+ have_dynamic_loading=yes 5943 AC_DEFINE(HAVE_DYNAMIC_LOADING, 1, 5944 [Defined when any dynamic module loading is enabled.]) 5945+else 5946+ have_dynamic_loading=no 5947 fi 5948 5949 # MACHDEP_OBJS can be set to platform-specific object files needed by Python 5950@@ -4580,13 +4852,22 @@ else 5951 fi 5952 5953 # checks for library functions 5954+if test $with_nt_threads = yes ; then 5955+ dnl GCC(mingw) 4.4+ require and use posix threads(pthreads-w32) 5956+ dnl and host may contain installed pthreads-w32. 5957+ dnl Skip checks for some functions declared in pthreads-w32 if 5958+ dnl NT-thread model is enabled. 5959+ ac_cv_func_pthread_kill=skip 5960+ ac_cv_func_sem_open=skip 5961+ ac_cv_func_sched_setscheduler=skip 5962+fi 5963 AC_CHECK_FUNCS([ \ 5964 accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \ 5965 copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \ 5966 faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ 5967 fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ 5968 gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \ 5969- getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \ 5970+ getgrnam_r getgrouplist getgroups getitimer getloadavg getlogin \ 5971 getpeername getpgid getpid getppid getpriority _getpty \ 5972 getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ 5973 getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \ 5974@@ -4599,7 +4880,7 @@ AC_CHECK_FUNCS([ \ 5975 sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ 5976 sem_timedwait sem_unlink sendfile setegid seteuid setgid sethostname \ 5977 setitimer setlocale setpgid setpgrp setpriority setregid setresgid \ 5978- setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \ 5979+ setresuid setreuid setsid setuid setvbuf sigaction sigaltstack \ 5980 sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \ 5981 sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ 5982 sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ 5983@@ -4829,7 +5110,13 @@ PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [ 5984 ]) 5985 5986 dnl PY_CHECK_NETDB_FUNC(FUNCTION) 5987-AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [#include <netdb.h>])]) 5988+AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [ 5989+#ifdef _WIN32 5990+ #include <winsock.h> 5991+#else 5992+ #include <netdb.h> 5993+#endif 5994+])]) 5995 5996 PY_CHECK_NETDB_FUNC([hstrerror]) 5997 dnl not available in WASI yet 5998@@ -4838,13 +5125,19 @@ PY_CHECK_NETDB_FUNC([getservbyport]) 5999 PY_CHECK_NETDB_FUNC([gethostbyname]) 6000 PY_CHECK_NETDB_FUNC([gethostbyaddr]) 6001 PY_CHECK_NETDB_FUNC([getprotobyname]) 6002+PY_CHECK_NETDB_FUNC([gethostname]) 6003+PY_CHECK_NETDB_FUNC([shutdown]) 6004 6005 dnl PY_CHECK_SOCKET_FUNC(FUNCTION) 6006 AC_DEFUN([PY_CHECK_SOCKET_FUNC], [PY_CHECK_FUNC([$1], [ 6007+#ifdef _WIN32 6008+#include <ws2tcpip.h> 6009+#else 6010 #include <sys/types.h> 6011 #include <sys/socket.h> 6012 #include <netinet/in.h> 6013 #include <arpa/inet.h> 6014+#endif 6015 ])]) 6016 6017 PY_CHECK_SOCKET_FUNC([inet_aton]) 6018@@ -4945,6 +5238,9 @@ WITH_SAVE_ENV([ 6019 ]) 6020 ]) 6021 6022+case $host in 6023+ *-*-mingw*) ;; 6024+ *) 6025 AC_CHECK_FUNCS(clock_gettime, [], [ 6026 AC_CHECK_LIB(rt, clock_gettime, [ 6027 LIBS="$LIBS -lrt" 6028@@ -4965,6 +5261,8 @@ AC_CHECK_FUNCS(clock_settime, [], [ 6029 AC_DEFINE(HAVE_CLOCK_SETTIME, 1) 6030 ]) 6031 ]) 6032+ ;; 6033+esac 6034 6035 AC_CHECK_FUNCS(clock_nanosleep, [], [ 6036 AC_CHECK_LIB(rt, clock_nanosleep, [ 6037@@ -5163,18 +5461,33 @@ if test $ac_cv_header_time_altzone = yes; then 6038 AC_DEFINE(HAVE_ALTZONE, 1, [Define this if your time.h defines altzone.]) 6039 fi 6040 6041+AC_CHECK_HEADERS([ws2tcpip.h]) 6042 AC_CACHE_CHECK([for addrinfo], [ac_cv_struct_addrinfo], 6043-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <netdb.h>]], [[struct addrinfo a]])], 6044+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 6045+#ifdef HAVE_WS2TCPIP_H 6046+# include <ws2tcpip.h> 6047+#else 6048+# include <netdb.h> 6049+#endif]], 6050+ [[struct addrinfo a]])], 6051 [ac_cv_struct_addrinfo=yes], 6052 [ac_cv_struct_addrinfo=no])) 6053 if test $ac_cv_struct_addrinfo = yes; then 6054- AC_DEFINE(HAVE_ADDRINFO, 1, [struct addrinfo (netdb.h)]) 6055+ AC_DEFINE(HAVE_ADDRINFO, 1, [struct addrinfo]) 6056 fi 6057 6058 AC_CACHE_CHECK([for sockaddr_storage], [ac_cv_struct_sockaddr_storage], 6059 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 6060-# include <sys/types.h> 6061-# include <sys/socket.h>]], [[struct sockaddr_storage s]])], 6062+#ifdef HAVE_WS2TCPIP_H 6063+#include <ws2tcpip.h> 6064+#endif 6065+#ifdef HAVE_SYS_TYPES_H 6066+#include <sys/types.h> 6067+#endif 6068+#ifdef HAVE_SYS_SOCKET_H 6069+#include <sys/socket.h> 6070+#endif]], 6071+ [[struct sockaddr_storage s]])], 6072 [ac_cv_struct_sockaddr_storage=yes], 6073 [ac_cv_struct_sockaddr_storage=no])) 6074 if test $ac_cv_struct_sockaddr_storage = yes; then 6075@@ -5508,6 +5821,10 @@ dnl actually works. For FreeBSD versions <= 7.2, 6076 dnl the kernel module that provides POSIX semaphores 6077 dnl isn't loaded by default, so an attempt to call 6078 dnl sem_open results in a 'Signal 12' error. 6079+if test $with_nt_threads = yes ; then 6080+ dnl skip posix semaphores test if NT-thread model is enabled 6081+ ac_cv_posix_semaphores_enabled=no 6082+fi 6083 AC_CACHE_CHECK([whether POSIX semaphores are enabled], [ac_cv_posix_semaphores_enabled], 6084 AC_RUN_IFELSE([ 6085 AC_LANG_SOURCE([ 6086@@ -5541,6 +5858,14 @@ AS_VAR_IF([ac_cv_posix_semaphores_enabled], [no], [ 6087 ]) 6088 6089 dnl Multiprocessing check for broken sem_getvalue 6090+if test $with_nt_threads = yes ; then 6091+ dnl Skip test if NT-thread model is enabled. 6092+ dnl NOTE the test case below fail for pthreads-w32 as: 6093+ dnl - SEM_FAILED is not defined; 6094+ dnl - sem_open is a stub; 6095+ dnl - sem_getvalue work(!). 6096+ ac_cv_broken_sem_getvalue=skip 6097+fi 6098 AC_CACHE_CHECK([for broken sem_getvalue], [ac_cv_broken_sem_getvalue], 6099 AC_RUN_IFELSE([ 6100 AC_LANG_SOURCE([ 6101@@ -5577,7 +5902,10 @@ AS_VAR_IF([ac_cv_broken_sem_getvalue], [yes], [ 6102 ) 6103 ]) 6104 6105-AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include <dlfcn.h>]]) 6106+case $host in 6107+ *-*-mingw*) ;; 6108+ *) AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include <dlfcn.h>]]);; 6109+esac 6110 6111 # determine what size digit to use for Python's longs 6112 AC_MSG_CHECKING([digit size for Python's longs]) 6113@@ -5664,6 +5992,71 @@ esac 6114 # check for endianness 6115 AC_C_BIGENDIAN 6116 6117+AC_SUBST(PYD_PLATFORM_TAG) 6118+# Special case of PYD_PLATFORM_TAG with python build with mingw. 6119+# Python can with compiled with clang or gcc and linked 6120+# to msvcrt or ucrt. To avoid conflicts between them 6121+# we are selecting the extension as based on the compiler 6122+# and the runtime they link to 6123+# gcc + x86_64 + msvcrt = cp{version number}-x86_64 6124+# gcc + i686 + msvcrt = cp{version number}-i686 6125+# gcc + x86_64 + ucrt = cp{version number}-x86_64-ucrt 6126+# clang + x86_64 + ucrt = cp{version number}-x86_64-clang 6127+# clang + i686 + ucrt = cp{version number}-i686-clang 6128+ 6129+PYD_PLATFORM_TAG="" 6130+case $host in 6131+ *-*-mingw*) 6132+ # check if we are linking to ucrt 6133+ AC_MSG_CHECKING(whether linking to ucrt) 6134+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ 6135+ #include <stdio.h> 6136+ #ifndef _UCRT 6137+ #error no ucrt 6138+ #endif 6139+ int main(){ return 0; } 6140+ ]])],[linking_to_ucrt=yes],[linking_to_ucrt=no]) 6141+ AC_MSG_RESULT($linking_to_ucrt) 6142+ ;; 6143+esac 6144+case $host_os in 6145+ mingw*) 6146+ AC_MSG_CHECKING(PYD_PLATFORM_TAG) 6147+ case $host in 6148+ i686-*-mingw*) 6149+ if test -n "${cc_is_clang}"; then 6150+ # it is CLANG32 6151+ PYD_PLATFORM_TAG="mingw_i686_clang" 6152+ else 6153+ if test $linking_to_ucrt = no; then 6154+ PYD_PLATFORM_TAG="mingw_i686" 6155+ else 6156+ PYD_PLATFORM_TAG="mingw_i686_ucrt" 6157+ fi 6158+ fi 6159+ ;; 6160+ x86_64-*-mingw*) 6161+ if test -n "${cc_is_clang}"; then 6162+ # it is CLANG64 6163+ PYD_PLATFORM_TAG="mingw_x86_64_clang" 6164+ else 6165+ if test $linking_to_ucrt = no; then 6166+ PYD_PLATFORM_TAG="mingw_x86_64" 6167+ else 6168+ PYD_PLATFORM_TAG="mingw_x86_64_ucrt" 6169+ fi 6170+ fi 6171+ ;; 6172+ aarch64-*-mingw*) 6173+ PYD_PLATFORM_TAG+="mingw_aarch64" 6174+ ;; 6175+ armv7-*-mingw*) 6176+ PYD_PLATFORM_TAG+="mingw_armv7" 6177+ ;; 6178+ esac 6179+ AC_MSG_RESULT($PYD_PLATFORM_TAG) 6180+esac 6181+ 6182 # ABI version string for Python extension modules. This appears between the 6183 # periods in shared library file names, e.g. foo.<SOABI>.so. It is calculated 6184 # from the following attributes which affect the ABI of this Python build (in 6185@@ -5696,7 +6089,12 @@ if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then 6186 fi 6187 6188 AC_SUBST(EXT_SUFFIX) 6189-EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} 6190+VERSION_NO_DOTS=$(echo $LDVERSION | tr -d .) 6191+if test -n "${PYD_PLATFORM_TAG}"; then 6192+ EXT_SUFFIX=".cp${VERSION_NO_DOTS}-${PYD_PLATFORM_TAG}${SHLIB_SUFFIX}" 6193+else 6194+ EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} 6195+fi 6196 6197 AC_MSG_CHECKING(LDVERSION) 6198 LDVERSION='$(VERSION)$(ABIFLAGS)' 6199@@ -5704,7 +6102,7 @@ AC_MSG_RESULT($LDVERSION) 6200 6201 # On Android and Cygwin the shared libraries must be linked with libpython. 6202 AC_SUBST(LIBPYTHON) 6203-if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin"; then 6204+if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin" -o "$MACHDEP" = "win32"; then 6205 LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" 6206 else 6207 LIBPYTHON='' 6208@@ -6073,11 +6471,16 @@ then 6209 [Define if you have struct stat.st_mtimensec]) 6210 fi 6211 6212+if test -n "$PKG_CONFIG"; then 6213+ NCURSESW_INCLUDEDIR="`"$PKG_CONFIG" ncursesw --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ .*$//'`" 6214+else 6215+ NCURSESW_INCLUDEDIR="" 6216+fi 6217+AC_SUBST(NCURSESW_INCLUDEDIR) 6218+ 6219 # first curses header check 6220 ac_save_cppflags="$CPPFLAGS" 6221-if test "$cross_compiling" = no; then 6222- CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" 6223-fi 6224+CPPFLAGS="$CPPFLAGS -I$NCURSESW_INCLUDEDIR" 6225 6226 AC_CHECK_HEADERS(curses.h ncurses.h) 6227 6228@@ -6243,7 +6646,10 @@ fi 6229 6230 AC_CHECK_TYPE(socklen_t,, 6231 AC_DEFINE(socklen_t,int, 6232- [Define to `int' if <sys/socket.h> does not define.]),[ 6233+ [Define to `int' if <sys/socket.h> or <ws2tcpip.h> does not define.]),[ 6234+#ifdef HAVE_WS2TCPIP_H 6235+#include <ws2tcpip.h> 6236+#endif 6237 #ifdef HAVE_SYS_TYPES_H 6238 #include <sys/types.h> 6239 #endif 6240@@ -6333,6 +6739,27 @@ do 6241 THREADHEADERS="$THREADHEADERS \$(srcdir)/$h" 6242 done 6243 6244+case $host in 6245+ *-*-mingw*) 6246+ dnl Required for windows builds as Objects/exceptions.c require 6247+ dnl "errmap.h" from $srcdir/PC. 6248+ dnl Note we cannot use BASECPPFLAGS as autogenerated pyconfig.h 6249+ dnl has to be before customized located in ../PC. 6250+ dnl (-I. at end is workaround for setup.py logic) 6251+ CPPFLAGS="-I\$(srcdir)/PC $CPPFLAGS -I." 6252+ ;; 6253+esac 6254+ 6255+dnl Python interpreter main program for frozen scripts 6256+AC_SUBST(PYTHON_OBJS_FROZENMAIN) 6257+PYTHON_OBJS_FROZENMAIN="Python/frozenmain.o" 6258+case $host in 6259+ *-*-mingw*) 6260+ dnl 'PC/frozen_dllmain.c' - not yet 6261+ PYTHON_OBJS_FROZENMAIN= 6262+ ;; 6263+esac 6264+ 6265 AC_SUBST(SRCDIRS) 6266 SRCDIRS="\ 6267 Modules \ 6268@@ -6354,6 +6781,10 @@ SRCDIRS="\ 6269 Python \ 6270 Python/frozen_modules \ 6271 Python/deepfreeze" 6272+case $host in 6273+ *-*-mingw*) SRCDIRS="$SRCDIRS PC";; 6274+esac 6275+ 6276 AC_MSG_CHECKING(for build directories) 6277 for dir in $SRCDIRS; do 6278 if test ! -d $dir; then 6279@@ -6362,6 +6793,38 @@ for dir in $SRCDIRS; do 6280 done 6281 AC_MSG_RESULT(done) 6282 6283+# For mingw build need additional library for linking 6284+case $host in 6285+ *-*-mingw*) 6286+ LIBS="$LIBS -lversion -lshlwapi -lpathcch -lbcrypt" 6287+ AC_PROG_AWK 6288+ if test "$AWK" = "gawk"; then 6289+ awk_extra_flag="--non-decimal-data" 6290+ fi 6291+ AC_MSG_CHECKING([FIELD3]) 6292+ FIELD3=$($AWK $awk_extra_flag '\ 6293+ /^#define PY_RELEASE_LEVEL_/ {levels[$2]=$3} \ 6294+ /^#define PY_MICRO_VERSION[[:space:]]+/ {micro=$3} \ 6295+ /^#define PY_RELEASE_LEVEL[[:space:]]+/ {level=levels[$3]} \ 6296+ /^#define PY_RELEASE_SERIAL[[:space:]]+/ {serial=$3} \ 6297+ END {print micro * 1000 + level * 10 + serial}' \ 6298+ $srcdir/Include/patchlevel.h 6299+ ) 6300+ 6301+ AC_MSG_RESULT([${FIELD3}]) 6302+ RCFLAGS="$RCFLAGS -DFIELD3=$FIELD3 -O COFF" 6303+ 6304+ case $host in 6305+ i686*) RCFLAGS="$RCFLAGS --target=pe-i386" ;; 6306+ x86_64*) RCFLAGS="$RCFLAGS --target=pe-x86-64" ;; 6307+ *) ;; 6308+ esac 6309+ ;; 6310+ *) 6311+ ;; 6312+esac 6313+AC_SUBST(RCFLAGS) 6314+ 6315 # Availability of -O2: 6316 AC_CACHE_CHECK([for -O2], [ac_cv_compile_o2], [ 6317 saved_cflags="$CFLAGS" 6318@@ -6971,7 +7434,6 @@ PY_STDLIB_MOD_SIMPLE([_json]) 6319 PY_STDLIB_MOD_SIMPLE([_lsprof]) 6320 PY_STDLIB_MOD_SIMPLE([_opcode]) 6321 PY_STDLIB_MOD_SIMPLE([_pickle]) 6322-PY_STDLIB_MOD_SIMPLE([_posixsubprocess]) 6323 PY_STDLIB_MOD_SIMPLE([_queue]) 6324 PY_STDLIB_MOD_SIMPLE([_random]) 6325 PY_STDLIB_MOD_SIMPLE([select]) 6326@@ -6982,7 +7444,7 @@ PY_STDLIB_MOD_SIMPLE([_zoneinfo]) 6327 6328 dnl multiprocessing modules 6329 PY_STDLIB_MOD([_multiprocessing], 6330- [], [test "$ac_cv_func_sem_unlink" = "yes"], 6331+ [], [test "$ac_cv_func_sem_unlink" = "yes" -o "$MACHDEP" = "win32"], 6332 [-I\$(srcdir)/Modules/_multiprocessing]) 6333 PY_STDLIB_MOD([_posixshmem], 6334 [], [test "$have_posix_shmem" = "yes"], 6335@@ -7002,11 +7464,15 @@ PY_STDLIB_MOD([fcntl], 6336 [], [test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes"], 6337 [], [$FCNTL_LIBS]) 6338 PY_STDLIB_MOD([mmap], 6339- [], [test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes"]) 6340+ [], m4_flatten([test "$ac_cv_header_sys_mman_h" = "yes" 6341+ -a "$ac_cv_header_sys_stat_h" = "yes" 6342+ -o "$MACHDEP" = "win32"])) 6343 PY_STDLIB_MOD([_socket], 6344 [], m4_flatten([test "$ac_cv_header_sys_socket_h" = "yes" 6345 -a "$ac_cv_header_sys_types_h" = "yes" 6346- -a "$ac_cv_header_netinet_in_h" = "yes"])) 6347+ -a "$ac_cv_header_netinet_in_h" = "yes" 6348+ -o "$MACHDEP" = "win32"]), 6349+ [], [$SOCKET_LIBS]) 6350 6351 dnl platform specific extensions 6352 PY_STDLIB_MOD([grp], [], [test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes]) 6353@@ -7021,6 +7487,7 @@ PY_STDLIB_MOD([_scproxy], 6354 PY_STDLIB_MOD([spwd], [], [test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes]) 6355 PY_STDLIB_MOD([syslog], [], [test "$ac_cv_header_syslog_h" = yes]) 6356 PY_STDLIB_MOD([termios], [], [test "$ac_cv_header_termios_h" = yes]) 6357+PY_STDLIB_MOD([_posixsubprocess], [], [test "$MACHDEP" != "win32"]) 6358 6359 dnl _elementtree loads libexpat via CAPI hook in pyexpat 6360 PY_STDLIB_MOD([pyexpat], [], [], [$LIBEXPAT_CFLAGS], [$LIBEXPAT_LDFLAGS]) 6361@@ -7083,25 +7550,35 @@ PY_STDLIB_MOD([_lzma], [], [test "$have_liblzma" = yes], 6362 6363 dnl OpenSSL bindings 6364 PY_STDLIB_MOD([_ssl], [], [test "$ac_cv_working_openssl_ssl" = yes], 6365- [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS]) 6366+ [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS -lws2_32]) 6367 PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes], 6368 [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) 6369 6370+dnl windows specific modules 6371+PY_STDLIB_MOD([msvcrt], [test "$MACHDEP" = "win32"]) 6372+PY_STDLIB_MOD([_winapi], [test "$MACHDEP" = "win32"]) 6373+PY_STDLIB_MOD([_msi], [test "$MACHDEP" = "win32"], [], [], 6374+ [-lmsi -lcabinet -lrpcrt4]) 6375+PY_STDLIB_MOD([winsound], [test "$MACHDEP" = "win32"], [], [], 6376+ [-lwinmm]) 6377+PY_STDLIB_MOD([_overlapped], [test "$MACHDEP" = "win32"], [], [], 6378+ [-lws2_32]) 6379+ 6380 dnl test modules 6381 PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes]) 6382 PY_STDLIB_MOD([_testclinic], [test "$TEST_MODULES" = yes]) 6383-PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes]) 6384+PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes], [], [-DPY3_DLLNAME="\"$DLLLIBRARY\""], []) 6385 PY_STDLIB_MOD([_testbuffer], [test "$TEST_MODULES" = yes]) 6386-PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) 6387-PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) 6388+PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes]) 6389+PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes]) 6390 PY_STDLIB_MOD([_xxtestfuzz], [test "$TEST_MODULES" = yes]) 6391-PY_STDLIB_MOD([_ctypes_test], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes], [], [-lm]) 6392+PY_STDLIB_MOD([_ctypes_test], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes], [], [-lm]) 6393 6394 dnl Limited API template modules. 6395 dnl The limited C API is not compatible with the Py_TRACE_REFS macro. 6396 dnl Emscripten does not support shared libraries yet. 6397-PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) 6398-PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) 6399+PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$have_dynamic_loading" = yes]) 6400+PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$have_dynamic_loading" = yes]) 6401 6402 # substitute multiline block, must come after last PY_STDLIB_MOD() 6403 AC_SUBST([MODULE_BLOCK]) 6404diff --git a/mingw_ignorefile.txt b/mingw_ignorefile.txt 6405new file mode 100644 6406index 0000000..54093f1 6407--- /dev/null 6408+++ b/mingw_ignorefile.txt 6409@@ -0,0 +1,42 @@ 6410+ctypes.test.test_loading.LoaderTest.test_load_dll_with_flags 6411+distutils.tests.test_bdist_dumb.BuildDumbTestCase.test_simple_built 6412+distutils.tests.test_cygwinccompiler.CygwinCCompilerTestCase.test_get_versions 6413+distutils.tests.test_util.UtilTestCase.test_change_root 6414+test.datetimetester.TestLocalTimeDisambiguation_Fast.* 6415+test.datetimetester.TestLocalTimeDisambiguation_Pure.* 6416+test.test_cmath.CMathTests.test_specific_values 6417+test.test_cmd_line_script.CmdLineTest.test_consistent_sys_path_for_direct_execution 6418+test.test_compileall.CommandLineTestsNoSourceEpoch.* 6419+test.test_compileall.CommandLineTestsWithSourceEpoch.* 6420+test.test_compileall.CompileallTestsWithoutSourceEpoch.* 6421+test.test_compileall.CompileallTestsWithSourceEpoch.* 6422+test.test_import.ImportTests.test_dll_dependency_import 6423+test.test_math.MathTests.* 6424+test.test_ntpath.NtCommonTest.test_import 6425+test.test_os.StatAttributeTests.test_stat_block_device 6426+test.test_os.TestScandir.test_attributes 6427+test.test_os.UtimeTests.test_large_time 6428+test.test_platform.PlatformTest.test_architecture_via_symlink 6429+test.test_regrtest.ProgramsTestCase.test_pcbuild_rt 6430+test.test_regrtest.ProgramsTestCase.test_tools_buildbot_test 6431+test.test_site._pthFileTests.* 6432+test.test_site.HelperFunctionsTests.* 6433+test.test_site.StartupImportTests.* 6434+test.test_ssl.* 6435+test.test_strptime.CalculationTests.* 6436+test.test_strptime.StrptimeTests.test_weekday 6437+test.test_strptime.TimeRETests.test_compile 6438+test.test_tools.test_i18n.Test_pygettext.test_POT_Creation_Date 6439+test.test_venv.BasicTest.* 6440+test.test_venv.EnsurePipTest.* 6441+test.test_sysconfig.TestSysConfig.test_user_similar 6442+test.test_tcl.TclTest.testLoadWithUNC 6443+# flaky 6444+test.test__xxsubinterpreters.* 6445+test.test_asyncio.test_subprocess.SubprocessProactorTests.test_stdin_broken_pipe 6446+test.test_asynchat.TestAsynchat.test_line_terminator2 6447+test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_gc_aclose_09 6448+test.test_concurrent_futures.ThreadPoolShutdownTest.test_interpreter_shutdown 6449+test.test_asynchat.TestNotConnected.test_disallow_negative_terminator 6450+test.test_logging.SysLogHandlerTest.* 6451+test.test_logging.IPv6SysLogHandlerTest.* 6452diff --git a/mingw_smoketests.py b/mingw_smoketests.py 6453new file mode 100644 6454index 0000000..ca1f652 6455--- /dev/null 6456+++ b/mingw_smoketests.py 6457@@ -0,0 +1,358 @@ 6458+#!/usr/bin/env python3 6459+# Copyright 2017 Christoph Reiter 6460+# 6461+# Permission is hereby granted, free of charge, to any person obtaining 6462+# a copy of this software and associated documentation files (the 6463+# "Software"), to deal in the Software without restriction, including 6464+# without limitation the rights to use, copy, modify, merge, publish, 6465+# distribute, sublicense, and/or sell copies of the Software, and to 6466+# permit persons to whom the Software is furnished to do so, subject to 6467+# the following conditions: 6468+# 6469+# The above copyright notice and this permission notice shall be included 6470+# in all copies or substantial portions of the Software. 6471+# 6472+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 6473+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 6474+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 6475+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 6476+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 6477+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 6478+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6479+ 6480+"""The goal of this test suite is collect tests for update regressions 6481+and to test msys2 related modifications like for path handling. 6482+Feel free to extend. 6483+""" 6484+ 6485+import os 6486+import unittest 6487+import sysconfig 6488+ 6489+if os.environ.get("MSYSTEM", ""): 6490+ SEP = "/" 6491+else: 6492+ SEP = "\\" 6493+ 6494+if sysconfig.is_python_build(): 6495+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1" 6496+ 6497+_UCRT = sysconfig.get_platform() not in ('mingw_x86_64', 'mingw_i686') 6498+ 6499+ 6500+class Tests(unittest.TestCase): 6501+ 6502+ def test_zoneinfo(self): 6503+ # https://github.com/msys2-contrib/cpython-mingw/issues/32 6504+ import zoneinfo 6505+ self.assertTrue(any(os.path.exists(p) for p in zoneinfo.TZPATH)) 6506+ zoneinfo.ZoneInfo("America/Sao_Paulo") 6507+ 6508+ def test_userdir_path_sep(self): 6509+ # Make sure os.path and pathlib use the same path separators 6510+ from unittest import mock 6511+ from os.path import expanduser 6512+ from pathlib import Path 6513+ 6514+ profiles = ["C:\\foo", "C:/foo"] 6515+ for profile in profiles: 6516+ with mock.patch.dict(os.environ, {"USERPROFILE": profile}): 6517+ self.assertEqual(expanduser("~"), os.path.normpath(expanduser("~"))) 6518+ self.assertEqual(str(Path("~").expanduser()), expanduser("~")) 6519+ self.assertEqual(str(Path.home()), expanduser("~")) 6520+ 6521+ def test_sysconfig_schemes(self): 6522+ # https://github.com/msys2/MINGW-packages/issues/9319 6523+ import sysconfig 6524+ from distutils.dist import Distribution 6525+ from distutils.command.install import install 6526+ 6527+ names = ['scripts', 'purelib', 'platlib', 'data', 'include'] 6528+ for scheme in ["nt", "nt_user"]: 6529+ for name in names: 6530+ c = install(Distribution({"name": "foobar"})) 6531+ c.user = (scheme == "nt_user") 6532+ c.finalize_options() 6533+ if name == "include": 6534+ dist_path = os.path.dirname(getattr(c, "install_" + "headers")) 6535+ else: 6536+ dist_path = getattr(c, "install_" + name) 6537+ sys_path = sysconfig.get_path(name, scheme) 6538+ self.assertEqual(dist_path, sys_path, (scheme, name)) 6539+ 6540+ def test_ctypes_find_library(self): 6541+ from ctypes.util import find_library 6542+ from ctypes import cdll 6543+ self.assertTrue(cdll.msvcrt) 6544+ if _UCRT: 6545+ self.assertIsNone(find_library('c')) 6546+ else: 6547+ self.assertEqual(find_library('c'), 'msvcrt.dll') 6548+ 6549+ def test_ctypes_dlopen(self): 6550+ import ctypes 6551+ import sys 6552+ self.assertEqual(ctypes.RTLD_GLOBAL, 0) 6553+ self.assertEqual(ctypes.RTLD_GLOBAL, ctypes.RTLD_LOCAL) 6554+ self.assertFalse(hasattr(sys, 'setdlopenflags')) 6555+ self.assertFalse(hasattr(sys, 'getdlopenflags')) 6556+ self.assertFalse([n for n in dir(os) if n.startswith("RTLD_")]) 6557+ 6558+ def test_time_no_unix_stuff(self): 6559+ import time 6560+ self.assertFalse([n for n in dir(time) if n.startswith("clock_")]) 6561+ self.assertFalse([n for n in dir(time) if n.startswith("CLOCK_")]) 6562+ self.assertFalse([n for n in dir(time) if n.startswith("pthread_")]) 6563+ self.assertFalse(hasattr(time, 'tzset')) 6564+ 6565+ def test_strftime(self): 6566+ import time 6567+ with self.assertRaises(ValueError): 6568+ time.strftime('%Y', (12345,) + (0,) * 8) 6569+ 6570+ def test_sep(self): 6571+ self.assertEqual(os.sep, SEP) 6572+ 6573+ def test_module_file_path(self): 6574+ import asyncio 6575+ import zlib 6576+ self.assertEqual(zlib.__file__, os.path.normpath(zlib.__file__)) 6577+ self.assertEqual(asyncio.__file__, os.path.normpath(asyncio.__file__)) 6578+ 6579+ def test_importlib_frozen_path_sep(self): 6580+ import importlib._bootstrap_external 6581+ self.assertEqual(importlib._bootstrap_external.path_sep, SEP) 6582+ 6583+ def test_os_commonpath(self): 6584+ self.assertEqual( 6585+ os.path.commonpath( 6586+ [os.path.join("C:", os.sep, "foo", "bar"), 6587+ os.path.join("C:", os.sep, "foo")]), 6588+ os.path.join("C:", os.sep, "foo")) 6589+ 6590+ def test_pathlib(self): 6591+ import pathlib 6592+ 6593+ p = pathlib.Path("foo") / pathlib.Path("foo") 6594+ self.assertEqual(str(p), os.path.normpath(p)) 6595+ 6596+ def test_modules_import(self): 6597+ import sqlite3 6598+ import ssl 6599+ import ctypes 6600+ import curses 6601+ 6602+ def test_c_modules_import(self): 6603+ import _decimal 6604+ 6605+ def test_socket_inet_ntop(self): 6606+ import socket 6607+ self.assertTrue(hasattr(socket, "inet_ntop")) 6608+ 6609+ def test_socket_inet_pton(self): 6610+ import socket 6611+ self.assertTrue(hasattr(socket, "inet_pton")) 6612+ 6613+ def test_multiprocessing_queue(self): 6614+ from multiprocessing import Queue 6615+ Queue(0) 6616+ 6617+ #def test_socket_timout_normal_error(self): 6618+ # import urllib.request 6619+ # from urllib.error import URLError 6620+ 6621+ # try: 6622+ # urllib.request.urlopen( 6623+ # 'http://localhost', timeout=0.0001).close() 6624+ # except URLError: 6625+ # pass 6626+ 6627+ def test_threads(self): 6628+ from concurrent.futures import ThreadPoolExecutor 6629+ 6630+ with ThreadPoolExecutor(1) as pool: 6631+ for res in pool.map(lambda *x: None, range(10000)): 6632+ pass 6633+ 6634+ def test_sysconfig(self): 6635+ import sysconfig 6636+ # This should be able to execute without exceptions 6637+ sysconfig.get_config_vars() 6638+ 6639+ def test_sqlite_enable_load_extension(self): 6640+ # Make sure --enable-loadable-sqlite-extensions is used 6641+ import sqlite3 6642+ self.assertTrue(sqlite3.Connection.enable_load_extension) 6643+ 6644+ def test_venv_creation(self): 6645+ import tempfile 6646+ import venv 6647+ import subprocess 6648+ import shutil 6649+ with tempfile.TemporaryDirectory() as tmp: 6650+ builder = venv.EnvBuilder() 6651+ builder.create(tmp) 6652+ assert os.path.exists(os.path.join(tmp, "bin", "activate")) 6653+ assert os.path.exists(os.path.join(tmp, "bin", "python.exe")) 6654+ assert os.path.exists(os.path.join(tmp, "bin", "python3.exe")) 6655+ subprocess.check_call([shutil.which("bash.exe"), os.path.join(tmp, "bin", "activate")]) 6656+ 6657+ # This will not work in in-tree build 6658+ if not sysconfig.is_python_build(): 6659+ op = subprocess.check_output( 6660+ [ 6661+ os.path.join(tmp, "bin", "python.exe"), 6662+ "-c", 6663+ "print('Hello World')" 6664+ ], 6665+ cwd=tmp, 6666+ ) 6667+ assert op.decode().strip() == "Hello World" 6668+ 6669+ def test_has_mktime(self): 6670+ from time import mktime, gmtime 6671+ mktime(gmtime()) 6672+ 6673+ def test_platform_things(self): 6674+ import sys 6675+ import sysconfig 6676+ import platform 6677+ import importlib.machinery 6678+ self.assertEqual(sys.implementation.name, "cpython") 6679+ self.assertEqual(sys.platform, "win32") 6680+ self.assertTrue(sysconfig.get_platform().startswith("mingw")) 6681+ self.assertTrue(sysconfig.get_config_var('SOABI').startswith("cpython-")) 6682+ ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') 6683+ self.assertTrue(ext_suffix.endswith(".pyd")) 6684+ self.assertTrue("mingw" in ext_suffix) 6685+ self.assertEqual(sysconfig.get_config_var('SHLIB_SUFFIX'), ".pyd") 6686+ ext_suffixes = importlib.machinery.EXTENSION_SUFFIXES 6687+ self.assertTrue(ext_suffix in ext_suffixes) 6688+ self.assertTrue(".pyd" in ext_suffixes) 6689+ if sysconfig.get_platform().startswith('mingw_i686'): 6690+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-32') 6691+ elif sysconfig.get_platform().startswith('mingw_aarch64'): 6692+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-arm64') 6693+ elif sysconfig.get_platform().startswith('mingw_armv7'): 6694+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-arm32') 6695+ else: 6696+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2]))) 6697+ self.assertEqual(platform.python_implementation(), "CPython") 6698+ self.assertEqual(platform.system(), "Windows") 6699+ self.assertTrue(isinstance(sys.api_version, int) and sys.api_version > 0) 6700+ 6701+ def test_sys_getpath(self): 6702+ # everything sourced from getpath.py 6703+ import sys 6704+ 6705+ def assertNormpath(path): 6706+ self.assertEqual(path, os.path.normpath(path)) 6707+ 6708+ assertNormpath(sys.executable) 6709+ assertNormpath(sys._base_executable) 6710+ assertNormpath(sys.prefix) 6711+ assertNormpath(sys.base_prefix) 6712+ assertNormpath(sys.exec_prefix) 6713+ assertNormpath(sys.base_exec_prefix) 6714+ assertNormpath(sys.platlibdir) 6715+ assertNormpath(sys._stdlib_dir) 6716+ for p in sys.path: 6717+ assertNormpath(p) 6718+ 6719+ def test_site(self): 6720+ import site 6721+ 6722+ self.assertEqual(len(site.getsitepackages()), 1) 6723+ 6724+ def test_c_ext_build(self): 6725+ import tempfile 6726+ import sys 6727+ import subprocess 6728+ import textwrap 6729+ from pathlib import Path 6730+ 6731+ with tempfile.TemporaryDirectory() as tmppro: 6732+ subprocess.check_call([sys.executable, "-m", "ensurepip", "--user"]) 6733+ with Path(tmppro, "setup.py").open("w") as f: 6734+ f.write( 6735+ textwrap.dedent( 6736+ """\ 6737+ from setuptools import setup, Extension 6738+ 6739+ setup( 6740+ name='cwrapper', 6741+ version='1.0', 6742+ ext_modules=[ 6743+ Extension( 6744+ 'cwrapper', 6745+ sources=['cwrapper.c']), 6746+ ], 6747+ ) 6748+ """ 6749+ ) 6750+ ) 6751+ with Path(tmppro, "cwrapper.c").open("w") as f: 6752+ f.write( 6753+ textwrap.dedent( 6754+ """\ 6755+ #include <Python.h> 6756+ static PyObject * 6757+ helloworld(PyObject *self, PyObject *args) 6758+ { 6759+ printf("Hello World\\n"); 6760+ Py_RETURN_NONE; 6761+ } 6762+ static PyMethodDef 6763+ myMethods[] = { 6764+ { "helloworld", helloworld, METH_NOARGS, "Prints Hello World" }, 6765+ { NULL, NULL, 0, NULL } 6766+ }; 6767+ static struct PyModuleDef cwrapper = { 6768+ PyModuleDef_HEAD_INIT, 6769+ "cwrapper", 6770+ "Test Module", 6771+ -1, 6772+ myMethods 6773+ }; 6774+ 6775+ PyMODINIT_FUNC 6776+ PyInit_cwrapper(void) 6777+ { 6778+ return PyModule_Create(&cwrapper); 6779+ } 6780+ """ 6781+ ) 6782+ ) 6783+ subprocess.check_call( 6784+ [sys.executable, "-c", "import struct"], 6785+ ) 6786+ subprocess.check_call( 6787+ [ 6788+ sys.executable, 6789+ "-m", 6790+ "pip", 6791+ "install", 6792+ "wheel", 6793+ ], 6794+ ) 6795+ subprocess.check_call( 6796+ [ 6797+ sys.executable, 6798+ "-m", 6799+ "pip", 6800+ "install", 6801+ tmppro, 6802+ ], 6803+ ) 6804+ subprocess.check_call( 6805+ [sys.executable, "-c", "import cwrapper"], 6806+ ) 6807+ 6808+ 6809+ 6810+def suite(): 6811+ return unittest.TestLoader().loadTestsFromName(__name__) 6812+ 6813+ 6814+if __name__ == '__main__': 6815+ unittest.main(defaultTest='suite') 6816diff --git a/pyconfig.h.in b/pyconfig.h.in 6817index 75f1d90..3b89b9e 100644 6818--- a/pyconfig.h.in 6819+++ b/pyconfig.h.in 6820@@ -60,7 +60,7 @@ 6821 /* Define to 1 if you have the `acosh' function. */ 6822 #undef HAVE_ACOSH 6823 6824-/* struct addrinfo (netdb.h) */ 6825+/* struct addrinfo */ 6826 #undef HAVE_ADDRINFO 6827 6828 /* Define to 1 if you have the `alarm' function. */ 6829@@ -1521,6 +1521,9 @@ 6830 /* Define if mvwdelch in curses.h is an expression. */ 6831 #undef MVWDELCH_IS_EXPRESSION 6832 6833+/* Define to 1 if you want to use native NT threads */ 6834+#undef NT_THREADS 6835+ 6836 /* Define to the address where bug reports for this package should be sent. */ 6837 #undef PACKAGE_BUGREPORT 6838 6839@@ -1836,7 +1839,7 @@ 6840 /* Define to `unsigned int' if <sys/types.h> does not define. */ 6841 #undef size_t 6842 6843-/* Define to `int' if <sys/socket.h> does not define. */ 6844+/* Define to `int' if <sys/socket.h> or <ws2tcpip.h> does not define. */ 6845 #undef socklen_t 6846 6847 /* Define to `int' if <sys/types.h> doesn't define. */ 6848diff --git a/setup.py b/setup.py 6849index 4f122b6..bf93153 100644 6850--- a/setup.py 6851+++ b/setup.py 6852@@ -77,9 +77,29 @@ def get_platform(): 6853 return sys.platform 6854 6855 6856+# On MSYS, os.system needs to be wrapped with sh.exe 6857+# as otherwise all the io redirection will fail. 6858+# Arguably, this could happen inside the real os.system 6859+# rather than this monkey patch. 6860+if sys.platform == "win32" and os.environ.get("MSYSTEM", ""): 6861+ os_system = os.system 6862+ def msys_system(command): 6863+ command_in_sh = 'sh.exe -c "%s"' % command.replace("\\", "\\\\") 6864+ return os_system(command_in_sh) 6865+ os.system = msys_system 6866+ 6867+ # set PYTHONLEGACYWINDOWSDLLLOADING to 1 to load DLLs from PATH 6868+ # This is needed while building core extensions of Python 6869+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1" 6870+ 6871+ 6872 CROSS_COMPILING = ("_PYTHON_HOST_PLATFORM" in os.environ) 6873 HOST_PLATFORM = get_platform() 6874-MS_WINDOWS = (HOST_PLATFORM == 'win32') 6875+MS_WINDOWS = (HOST_PLATFORM == 'win32' or HOST_PLATFORM == 'mingw') 6876+ 6877+if MS_WINDOWS: 6878+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1" 6879+ 6880 CYGWIN = (HOST_PLATFORM == 'cygwin') 6881 MACOS = (HOST_PLATFORM == 'darwin') 6882 AIX = (HOST_PLATFORM.startswith('aix')) 6883@@ -687,7 +707,7 @@ def check_extension_import(self, ext): 6884 def add_multiarch_paths(self): 6885 # Debian/Ubuntu multiarch support. 6886 # https://wiki.ubuntu.com/MultiarchSpec 6887- tmpfile = os.path.join(self.build_temp, 'multiarch') 6888+ tmpfile = os.path.join(self.build_temp, 'multiarch').replace('\\','/') 6889 if not os.path.exists(self.build_temp): 6890 os.makedirs(self.build_temp) 6891 ret = run_command( 6892@@ -712,7 +732,7 @@ def add_multiarch_paths(self): 6893 opt = '' 6894 if CROSS_COMPILING: 6895 opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE') 6896- tmpfile = os.path.join(self.build_temp, 'multiarch') 6897+ tmpfile = os.path.join(self.build_temp, 'multiarch').replace('\\','/') 6898 if not os.path.exists(self.build_temp): 6899 os.makedirs(self.build_temp) 6900 ret = run_command( 6901@@ -774,7 +794,7 @@ def add_search_path(line): 6902 pass 6903 6904 def add_cross_compiling_paths(self): 6905- tmpfile = os.path.join(self.build_temp, 'ccpaths') 6906+ tmpfile = os.path.join(self.build_temp, 'ccpaths').replace('\\','/') 6907 if not os.path.exists(self.build_temp): 6908 os.makedirs(self.build_temp) 6909 # bpo-38472: With a German locale, GCC returns "gcc-Version 9.1.0 6910@@ -796,14 +816,25 @@ def add_cross_compiling_paths(self): 6911 elif line.startswith("End of search list"): 6912 in_incdirs = False 6913 elif (is_gcc or is_clang) and line.startswith("LIBRARY_PATH"): 6914- for d in line.strip().split("=")[1].split(":"): 6915+ for d in line.strip().split("=")[1].split(os.pathsep): 6916 d = os.path.normpath(d) 6917- if '/gcc/' not in d: 6918+ if '/gcc/' not in d and '/clang/' not in d: 6919 add_dir_to_list(self.compiler.library_dirs, 6920 d) 6921 elif (is_gcc or is_clang) and in_incdirs and '/gcc/' not in line and '/clang/' not in line: 6922 add_dir_to_list(self.compiler.include_dirs, 6923 line.strip()) 6924+ if is_clang: 6925+ ret = run_command('%s -print-search-dirs >%s' % (CC, tmpfile)) 6926+ if ret == 0: 6927+ with open(tmpfile) as fp: 6928+ for line in fp.readlines(): 6929+ if line.startswith("libraries:"): 6930+ for d in line.strip().split("=")[1].split(os.pathsep): 6931+ d = os.path.normpath(d) 6932+ if '/gcc/' not in d and '/clang/' not in d: 6933+ add_dir_to_list(self.compiler.library_dirs, 6934+ d) 6935 finally: 6936 os.unlink(tmpfile) 6937 6938@@ -849,6 +880,7 @@ def configure_compiler(self): 6939 if not CROSS_COMPILING: 6940 add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') 6941 add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') 6942+ self.add_multiarch_paths() 6943 # only change this for cross builds for 3.3, issues on Mageia 6944 if CROSS_COMPILING: 6945 self.add_cross_compiling_paths() 6946@@ -867,7 +899,6 @@ def init_inc_lib_dirs(self): 6947 sysconfig.get_config_var("LIBDIR")) 6948 add_dir_to_list(self.compiler.include_dirs, 6949 sysconfig.get_config_var("INCLUDEDIR")) 6950- 6951 system_lib_dirs = ['/lib64', '/usr/lib64', '/lib', '/usr/lib'] 6952 system_include_dirs = ['/usr/include'] 6953 # lib_dirs and inc_dirs are used to search for files; 6954@@ -898,7 +929,7 @@ def init_inc_lib_dirs(self): 6955 if HOST_PLATFORM == 'hp-ux11': 6956 self.lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32'] 6957 6958- if MACOS: 6959+ if MACOS or MS_WINDOWS: 6960 # This should work on any unixy platform ;-) 6961 # If the user has bothered specifying additional -I and -L flags 6962 # in OPT and LDFLAGS we might as well use them here. 6963@@ -915,7 +946,21 @@ def init_inc_lib_dirs(self): 6964 for item in ldflags.split(): 6965 if item.startswith('-L'): 6966 self.lib_dirs.append(item[2:]) 6967- 6968+ to_remove_inc = ['/usr/include', '/usr/include/x86_64-linux-gnu', '/usr/local/include'] 6969+ for path in to_remove_inc: 6970+ if path in self.inc_dirs: 6971+ self.inc_dirs.remove(path) 6972+ self.compiler.include_dirs.remove(path) 6973+ to_remove_lib = ['/usr/lib', '/lib', '/usr/lib/x86_64-linux-gnu', '/lib64', '/lib/x86_64-linux-gnu', '/usr/lib64'] 6974+ for path in to_remove_lib: 6975+ if path in self.lib_dirs: 6976+ self.lib_dirs.remove(path) 6977+ self.compiler.library_dirs.remove(path) 6978+ 6979+ log.info(f'Print compiler.include_dirs:{self.compiler.include_dirs}') 6980+ log.info(f'Print compiler.library_dirs:{self.compiler.library_dirs}') 6981+ 6982+ 6983 def detect_simple_extensions(self): 6984 # 6985 # The following modules are all pretty straightforward, and compile 6986@@ -970,11 +1015,15 @@ def detect_simple_extensions(self): 6987 # grp(3) 6988 self.addext(Extension('grp', ['grpmodule.c'])) 6989 6990- self.addext(Extension('_socket', ['socketmodule.c'])) 6991+ self.addext(Extension( 6992+ '_socket', ['socketmodule.c'], 6993+ libraries=(['ws2_32', 'iphlpapi'] if MS_WINDOWS else None))) 6994 self.addext(Extension('spwd', ['spwdmodule.c'])) 6995 6996 # select(2); not on ancient System V 6997- self.addext(Extension('select', ['selectmodule.c'])) 6998+ self.addext(Extension( 6999+ 'select', ['selectmodule.c'], 7000+ libraries=(['ws2_32'] if MS_WINDOWS else None))) 7001 7002 # Memory-mapped files (also works on Win32). 7003 self.addext(Extension('mmap', ['mmapmodule.c'])) 7004@@ -1033,12 +1082,15 @@ def detect_test_extensions(self): 7005 ['_xxtestfuzz/_xxtestfuzz.c', '_xxtestfuzz/fuzzer.c'] 7006 )) 7007 7008+ if MS_WINDOWS: 7009+ self.add(Extension('_testconsole', ['../PC/_testconsole.c'])) 7010+ 7011 def detect_readline_curses(self): 7012 # readline 7013 readline_termcap_library = "" 7014 curses_library = "" 7015 # Cannot use os.popen here in py3k. 7016- tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') 7017+ tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib').replace('\\','/') 7018 if not os.path.exists(self.build_temp): 7019 os.makedirs(self.build_temp) 7020 # Determine if readline is already linked against curses or tinfo. 7021@@ -1101,6 +1153,8 @@ def detect_readline_curses(self): 7022 # readline package 7023 if find_file('readline/rlconf.h', self.inc_dirs, []) is None: 7024 do_readline = False 7025+ if MS_WINDOWS: 7026+ do_readline = False 7027 if do_readline: 7028 readline_libs = [readline_lib] 7029 if readline_termcap_library: 7030@@ -1124,8 +1178,7 @@ def detect_readline_curses(self): 7031 panel_library = 'panel' 7032 if curses_library == 'ncursesw': 7033 curses_defines.append(('HAVE_NCURSESW', '1')) 7034- if not CROSS_COMPILING: 7035- curses_includes.append('/usr/include/ncursesw') 7036+ curses_includes.append(sysconfig.get_config_var("NCURSESW_INCLUDEDIR")) 7037 # Bug 1464056: If _curses.so links with ncursesw, 7038 # _curses_panel.so must link with panelw. 7039 panel_library = 'panelw' 7040@@ -1209,7 +1262,7 @@ def detect_dbm_gdbm(self): 7041 if dbm_args: 7042 dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":") 7043 else: 7044- dbm_order = "gdbm:ndbm:bdb".split(":") 7045+ dbm_order = [] 7046 dbmext = None 7047 for cand in dbm_order: 7048 if cand == "ndbm": 7049@@ -1282,6 +1335,19 @@ def detect_platform_specific_exts(self): 7050 # macOS-only, needs SystemConfiguration and CoreFoundation framework 7051 self.addext(Extension('_scproxy', ['_scproxy.c'])) 7052 7053+ # Windows-only modules 7054+ if MS_WINDOWS: 7055+ srcdir = sysconfig.get_config_var('srcdir') 7056+ pc_srcdir = os.path.abspath(os.path.join(srcdir, 'PC')) 7057+ 7058+ self.addext(Extension('_msi', 7059+ [os.path.join(pc_srcdir, '_msi.c')])) 7060+ 7061+ self.addext(Extension('winsound', 7062+ [os.path.join(pc_srcdir, 'winsound.c')])) 7063+ 7064+ self.addext(Extension('_overlapped', ['overlapped.c'])) 7065+ 7066 def detect_compress_exts(self): 7067 # Andrew Kuchling's zlib module. 7068 self.addext(Extension('zlib', ['zlibmodule.c'])) 7069@@ -1329,9 +1395,10 @@ def detect_multiprocessing(self): 7070 if ( 7071 sysconfig.get_config_var('HAVE_SEM_OPEN') and not 7072 sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED') 7073- ): 7074+ ) or MS_WINDOWS: 7075 multiprocessing_srcs.append('_multiprocessing/semaphore.c') 7076- self.addext(Extension('_multiprocessing', multiprocessing_srcs)) 7077+ self.addext(Extension('_multiprocessing', multiprocessing_srcs, 7078+ libraries=(['ws2_32'] if MS_WINDOWS else None), include_dirs=["Modules/_multiprocessing"])) 7079 self.addext(Extension('_posixshmem', ['_multiprocessing/posixshmem.c'])) 7080 7081 def detect_uuid(self): 7082@@ -1414,11 +1481,16 @@ def detect_ctypes(self): 7083 include_dirs=include_dirs, 7084 extra_compile_args=extra_compile_args, 7085 extra_link_args=extra_link_args, 7086- libraries=[], 7087+ libraries=(['ole32', 'oleaut32', 'uuid'] if MS_WINDOWS else []), 7088+ export_symbols=( 7089+ ['DllGetClassObject PRIVATE', 'DllCanUnloadNow PRIVATE'] 7090+ if MS_WINDOWS else None 7091+ ), 7092 sources=sources) 7093 self.add(ext) 7094 # function my_sqrt() needs libm for sqrt() 7095- self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'])) 7096+ self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'], 7097+ libraries=(['oleaut32'] if MS_WINDOWS else []))) 7098 7099 ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR") 7100 ffi_lib = None 7101@@ -1568,7 +1640,7 @@ def copy_scripts(self): 7102 else: 7103 newfilename = filename + minoronly 7104 log.info(f'renaming {filename} to {newfilename}') 7105- os.rename(filename, newfilename) 7106+ os.replace(filename, newfilename) 7107 newoutfiles.append(newfilename) 7108 if filename in updated_files: 7109 newupdated_files.append(newfilename) 7110-- 71112.34.1 7112 7113