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