1diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml 2new file mode 100755 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 100755 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 0444b0f..0bc5956 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@@ -719,6 +731,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@@ -729,12 +742,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@@ -789,13 +801,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 ebac1d6..cac0c37 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 6bce308..1cd57d0 100644 2208--- a/Lib/venv/__init__.py 2209+++ b/Lib/venv/__init__.py 2210@@ -11,7 +11,7 @@ 2211 import sys 2212 import sysconfig 2213 import types 2214- 2215+from sysconfig import _POSIX_BUILD 2216 2217 CORE_VENV_DEPS = ('pip', 'setuptools') 2218 logger = logging.getLogger(__name__) 2219@@ -301,7 +301,7 @@ def setup_python(self, context): 2220 if not os.path.islink(path): 2221 os.chmod(path, 0o755) 2222 else: 2223- if self.symlinks: 2224+ if self.symlinks and not _POSIX_BUILD: 2225 # For symlinking, we need a complete copy of the root directory 2226 # If symlinks fail, you'll get unnecessary copies of files, but 2227 # we assume that if you've opted into symlinks on Windows then 2228@@ -325,6 +325,12 @@ def setup_python(self, context): 2229 if os.path.lexists(src): 2230 copier(src, os.path.join(binpath, suffix)) 2231 2232+ if _POSIX_BUILD: 2233+ # copy from python/pythonw so the venvlauncher magic in symlink_or_copy triggers 2234+ copier(os.path.join(dirname, 'python.exe'), os.path.join(binpath, 'python3.exe')) 2235+ copier(os.path.join(dirname, 'python.exe'), os.path.join(binpath, 'python%d.%d.exe' % sys.version_info[:2])) 2236+ copier(os.path.join(dirname, 'pythonw.exe'), os.path.join(binpath, 'python3w.exe')) 2237+ 2238 if sysconfig.is_python_build(): 2239 # copy init.tcl 2240 for root, dirs, files in os.walk(context.python_dir): 2241@@ -349,6 +355,7 @@ def _call_new_python(self, context, *py_args, **kwargs): 2242 env['VIRTUAL_ENV'] = context.env_dir 2243 env.pop('PYTHONHOME', None) 2244 env.pop('PYTHONPATH', None) 2245+ env.pop("MSYSTEM", None) 2246 kwargs['cwd'] = context.env_dir 2247 kwargs['executable'] = context.env_exec_cmd 2248 subprocess.check_output(args, **kwargs) 2249diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate 2250index 6fbc2b8..9c3d58d 100644 2251--- a/Lib/venv/scripts/common/activate 2252+++ b/Lib/venv/scripts/common/activate 2253@@ -38,7 +38,7 @@ deactivate () { 2254 # unset irrelevant variables 2255 deactivate nondestructive 2256 2257-VIRTUAL_ENV="__VENV_DIR__" 2258+VIRTUAL_ENV=$(cygpath "__VENV_DIR__") 2259 export VIRTUAL_ENV 2260 2261 _OLD_VIRTUAL_PATH="$PATH" 2262diff --git a/Makefile.pre.in b/Makefile.pre.in 2263index 3ea8653..2707d04 100644 2264--- a/Makefile.pre.in 2265+++ b/Makefile.pre.in 2266@@ -39,6 +39,7 @@ CXX= @CXX@ 2267 MAINCC= @MAINCC@ 2268 LINKCC= @LINKCC@ 2269 AR= @AR@ 2270+WINDRES= @WINDRES@ 2271 READELF= @READELF@ 2272 SOABI= @SOABI@ 2273 LDVERSION= @LDVERSION@ 2274@@ -123,6 +124,7 @@ PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE 2275 PY_CORE_LDFLAGS=$(PY_LDFLAGS) $(PY_LDFLAGS_NODIST) 2276 # Strict or non-strict aliasing flags used to compile dtoa.c, see above 2277 CFLAGS_ALIASING=@CFLAGS_ALIASING@ 2278+RCFLAGS=@RCFLAGS@ 2279 2280 2281 # Machine-dependent subdirectories 2282@@ -141,6 +143,12 @@ exec_prefix= @exec_prefix@ 2283 # Install prefix for data files 2284 datarootdir= @datarootdir@ 2285 2286+# Locations needed for semi-native fixup of sysconfig. 2287+srcdir_b2h= @srcdir_b2h@ 2288+abs_srcdir_b2h= @abs_srcdir_b2h@ 2289+abs_builddir_b2h= @abs_builddir_b2h@ 2290+prefix_b2h= @prefix_b2h@ 2291+ 2292 # Expanded directories 2293 BINDIR= @bindir@ 2294 LIBDIR= @libdir@ 2295@@ -158,10 +166,12 @@ BINLIBDEST= @BINLIBDEST@ 2296 LIBDEST= $(SCRIPTDIR)/python$(VERSION) 2297 INCLUDEPY= $(INCLUDEDIR)/python$(LDVERSION) 2298 CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(LDVERSION) 2299+VENVLAUNCHERDIR= $(BINLIBDEST)/venv/scripts/nt 2300 2301 # Symbols used for using shared libraries 2302 SHLIB_SUFFIX= @SHLIB_SUFFIX@ 2303 EXT_SUFFIX= @EXT_SUFFIX@ 2304+PYD_PLATFORM_TAG = @PYD_PLATFORM_TAG@ 2305 LDSHARED= @LDSHARED@ $(PY_LDFLAGS) 2306 BLDSHARED= @BLDSHARED@ $(PY_CORE_LDFLAGS) 2307 LDCXXSHARED= @LDCXXSHARED@ 2308@@ -268,6 +278,8 @@ LIBRARY_DEPS= @LIBRARY_DEPS@ 2309 LINK_PYTHON_DEPS=@LINK_PYTHON_DEPS@ 2310 PY_ENABLE_SHARED= @PY_ENABLE_SHARED@ 2311 STATIC_LIBPYTHON= @STATIC_LIBPYTHON@ 2312+ABI3DLLLIBRARY= libpython3.dll 2313+ABI3LDLIBRARY= libpython3.dll.a 2314 2315 2316 LIBS= @LIBS@ 2317@@ -284,6 +296,7 @@ LIBOBJS= @LIBOBJS@ 2318 2319 PYTHON= python$(EXE) 2320 BUILDPYTHON= python$(BUILDEXE) 2321+BUILDPYTHONW= pythonw$(BUILDEXE) 2322 2323 HOSTRUNNER= @HOSTRUNNER@ 2324 2325@@ -344,6 +357,7 @@ IO_OBJS= \ 2326 ########################################################################## 2327 2328 LIBFFI_INCLUDEDIR= @LIBFFI_INCLUDEDIR@ 2329+NCURSESW_INCLUDEDIR= @NCURSESW_INCLUDEDIR@ 2330 2331 ########################################################################## 2332 # Parser 2333@@ -390,7 +404,7 @@ PYTHON_OBJS= \ 2334 Python/dynamic_annotations.o \ 2335 Python/errors.o \ 2336 Python/frame.o \ 2337- Python/frozenmain.o \ 2338+ @PYTHON_OBJS_FROZENMAIN@ \ 2339 Python/future.o \ 2340 Python/getargs.o \ 2341 Python/getcompiler.o \ 2342@@ -402,6 +416,7 @@ PYTHON_OBJS= \ 2343 Python/import.o \ 2344 Python/importdl.o \ 2345 Python/initconfig.o \ 2346+ Python/iscygpty.o \ 2347 Python/marshal.o \ 2348 Python/modsupport.o \ 2349 Python/mysnprintf.o \ 2350@@ -584,8 +599,8 @@ LIBEXPAT_HEADERS= \ 2351 2352 # Default target 2353 all: @DEF_MAKE_ALL_RULE@ 2354-build_all: check-clean-src $(BUILDPYTHON) platform oldsharedmods sharedmods \ 2355- gdbhooks Programs/_testembed python-config 2356+build_all: check-clean-src $(BUILDPYTHON) $(BUILDPYTHONW) platform oldsharedmods sharedmods \ 2357+ gdbhooks Programs/_testembed python-config $(ABI3DLLLIBRARY) $(ABI3LDLIBRARY) 2358 build_wasm: check-clean-src $(BUILDPYTHON) platform oldsharedmods python-config 2359 2360 # Check that the source is clean when building out of source. 2361@@ -700,9 +715,30 @@ coverage-report: regen-token regen-frozen 2362 clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c 2363 $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) 2364 2365+python_exe.o: $(srcdir)/PC/python_exe.rc 2366+ $(WINDRES) $(RCFLAGS) -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_exe.rc $@ 2367+ 2368+pythonw_exe.o: $(srcdir)/PC/pythonw_exe.rc 2369+ $(WINDRES) $(RCFLAGS) -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pythonw_exe.rc $@ 2370+ 2371+python_nt.o: $(srcdir)/PC/python_nt.rc 2372+ $(WINDRES) $(RCFLAGS) -DORIGINAL_FILENAME=\\\"$(DLLLIBRARY)\\\" -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_nt.rc $@ 2373+ 2374+python3dll_nt.o: $(srcdir)/PC/python_nt.rc 2375+ $(WINDRES) $(RCFLAGS) -DORIGINAL_FILENAME=\\\"$(ABI3DLLLIBRARY)\\\" -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_nt.rc $@ 2376+ 2377+venvlauncher.o: $(srcdir)/PC/pylauncher.rc 2378+ $(WINDRES) $(RCFLAGS) -DPY_ICON -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pylauncher.rc $@ 2379+ 2380+venvwlauncher.o: $(srcdir)/PC/pylauncher.rc 2381+ $(WINDRES) $(RCFLAGS) -DPYW_ICON -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pylauncher.rc $@ 2382+ 2383+$(BUILDPYTHONW): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) pythonw_exe.o 2384+ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -municode -mwindows -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) pythonw_exe.o 2385+ 2386 # Build the interpreter 2387-$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) 2388- $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) 2389+$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) python_exe.o 2390+ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -municode -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) python_exe.o 2391 2392 platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt 2393 $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform 2394@@ -806,13 +842,17 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \ 2395 2396 # This rule builds the Cygwin Python DLL and import library if configured 2397 # for a shared core library; otherwise, this rule is a noop. 2398-$(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS) 2399+$(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS) python_nt.o 2400 if test -n "$(DLLLIBRARY)"; then \ 2401 $(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \ 2402- $(LIBS) $(MODLIBS) $(SYSLIBS); \ 2403+ $(LIBS) $(LDFLAGS_NODIST) $(MODLIBS) $(SYSLIBS) python_nt.o; \ 2404 else true; \ 2405 fi 2406 2407+$(ABI3DLLLIBRARY) $(ABI3LDLIBRARY): python3dll_nt.o $(srcdir)/PC/launcher.c 2408+ $(LDSHARED) -DPYTHON_DLL_NAME=\"$(DLLLIBRARY)\" $(srcdir)/PC/python3dll.c -Wl,--out-implib=$(ABI3LDLIBRARY) -o $(ABI3DLLLIBRARY) python3dll_nt.o \ 2409+ $(LDFLAGS_NODIST); 2410+ 2411 # wasm32-emscripten browser build 2412 # wasm assets directory is relative to current build dir, e.g. "./usr/local". 2413 # --preload-file turns a relative asset path into an absolute path. 2414@@ -974,7 +1014,7 @@ BOOTSTRAP_HEADERS = \ 2415 Programs/_bootstrap_python.o: Programs/_bootstrap_python.c $(BOOTSTRAP_HEADERS) $(PYTHON_HEADERS) 2416 2417 _bootstrap_python: $(LIBRARY_OBJS_OMIT_FROZEN) Programs/_bootstrap_python.o Modules/getpath.o Modules/Setup.local 2418- $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ $(LIBRARY_OBJS_OMIT_FROZEN) \ 2419+ $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ -municode -mwindows $(LIBRARY_OBJS_OMIT_FROZEN) \ 2420 Programs/_bootstrap_python.o Modules/getpath.o $(LIBS) $(MODLIBS) $(SYSLIBS) 2421 2422 2423@@ -1276,9 +1316,15 @@ Python/dynload_hpux.o: $(srcdir)/Python/dynload_hpux.c Makefile 2424 -DSHLIB_EXT='"$(EXT_SUFFIX)"' \ 2425 -o $@ $(srcdir)/Python/dynload_hpux.c 2426 2427+Python/dynload_win.o: $(srcdir)/Python/dynload_win.c Makefile 2428+ $(CC) -c $(PY_CORE_CFLAGS) \ 2429+ -DPYD_PLATFORM_TAG='"$(PYD_PLATFORM_TAG)"' \ 2430+ -o $@ $(srcdir)/Python/dynload_win.c 2431+ 2432 Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h 2433 $(CC) -c $(PY_CORE_CFLAGS) \ 2434 -DABIFLAGS='"$(ABIFLAGS)"' \ 2435+ -DVPATH='"$(VPATH)"' \ 2436 $(MULTIARCH_CPPFLAGS) \ 2437 -o $@ $(srcdir)/Python/sysmodule.c 2438 2439@@ -1496,6 +1542,7 @@ PYTHON_HEADERS= \ 2440 $(srcdir)/Include/frameobject.h \ 2441 $(srcdir)/Include/import.h \ 2442 $(srcdir)/Include/intrcheck.h \ 2443+ $(srcdir)/Include/iscygpty.h \ 2444 $(srcdir)/Include/iterobject.h \ 2445 $(srcdir)/Include/listobject.h \ 2446 $(srcdir)/Include/longobject.h \ 2447@@ -1791,7 +1838,7 @@ $(DESTSHARED): 2448 # Install the interpreter with $(VERSION) affixed 2449 # This goes into $(exec_prefix) 2450 altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ 2451- @for i in $(BINDIR) $(LIBDIR); \ 2452+ @for i in $(BINDIR) $(LIBDIR) $(VENVLAUNCHERDIR); \ 2453 do \ 2454 if test ! -d $(DESTDIR)$$i; then \ 2455 echo "Creating directory $$i"; \ 2456@@ -1801,6 +1848,7 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ 2457 done 2458 if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ 2459 $(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ 2460+ $(INSTALL_PROGRAM) $(BUILDPYTHONW) $(DESTDIR)$(BINDIR)/python3w$(EXE); \ 2461 else \ 2462 $(INSTALL_PROGRAM) $(STRIPFLAG) Mac/pythonw $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ 2463 fi 2464@@ -1814,6 +1862,7 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ 2465 if test -f $(LDLIBRARY) && test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ 2466 if test -n "$(DLLLIBRARY)" ; then \ 2467 $(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \ 2468+ $(INSTALL_SHARED) $(ABI3DLLLIBRARY) $(DESTDIR)$(BINDIR); \ 2469 else \ 2470 $(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ 2471 if test $(LDLIBRARY) != $(INSTSONAME); then \ 2472@@ -1924,6 +1973,7 @@ LIBSUBDIRS= asyncio \ 2473 tkinter \ 2474 tomllib \ 2475 turtledemo \ 2476+ msilib \ 2477 unittest \ 2478 urllib \ 2479 venv venv/scripts venv/scripts/common venv/scripts/posix \ 2480@@ -2223,8 +2273,9 @@ libainstall: all python-config 2481 @if test "$(STATIC_LIBPYTHON)" = 1; then \ 2482 if test -d $(LIBRARY); then :; else \ 2483 if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ 2484- if test "$(SHLIB_SUFFIX)" = .dll; then \ 2485- $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \ 2486+ if test "$(SHLIB_SUFFIX)" = .dll -o "$(SHLIB_SUFFIX)" = .pyd; then \ 2487+ $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBDIR) ; \ 2488+ $(INSTALL_DATA) $(ABI3LDLIBRARY) $(DESTDIR)$(LIBDIR) ; \ 2489 else \ 2490 $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ 2491 fi; \ 2492@@ -2263,16 +2314,23 @@ libainstall: all python-config 2493 else true; \ 2494 fi 2495 2496+ifeq ($(shell uname -o),Msys) 2497+DESTDIRFINAL=$(DESTDIR) 2498+else 2499+DESTDIRFINAL=$(DESTDIR)/ 2500+endif 2501+ 2502 # Install the dynamically loadable modules 2503 # This goes into $(exec_prefix) 2504 sharedinstall: all 2505+ MSYS2_ARG_CONV_EXCL="--prefix=;--install-scripts=;--install-platlib=" \ 2506 $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \ 2507 --prefix=$(prefix) \ 2508 --install-scripts=$(BINDIR) \ 2509 --install-platlib=$(DESTSHARED) \ 2510- --root=$(DESTDIR)/ 2511- -rm $(DESTDIR)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py 2512- -rm -r $(DESTDIR)$(DESTSHARED)/__pycache__ 2513+ --root=$(DESTDIRFINAL) 2514+ -rm $(DESTDIRFINAL)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py 2515+ -rm -r $(DESTDIRFINAL)$(DESTSHARED)/__pycache__ 2516 2517 # Here are a couple of targets for MacOSX again, to install a full 2518 # framework-based Python. frameworkinstall installs everything, the 2519@@ -2464,7 +2522,7 @@ clean: clean-retain-profile 2520 fi 2521 2522 clobber: clean 2523- -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \ 2524+ -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY)$(ABI3LDLIBRARY) $(ABI3DLLLIBRARY) \ 2525 tags TAGS \ 2526 config.cache config.log pyconfig.h Modules/config.c 2527 -rm -rf build platform 2528diff --git a/Misc/NEWS.d/3.11.4.rst b/Misc/NEWS.d/3.11.4.rst 2529new file mode 100755 2530index 0000000..71ed43d 2531--- /dev/null 2532+++ b/Misc/NEWS.d/3.11.4.rst 2533@@ -0,0 +1,785 @@ 2534+.. date: 2023-06-01-03-24-58 2535+.. gh-issue: 103142 2536+.. nonce: GLWDMX 2537+.. release date: 2023-06-06 2538+.. section: Security 2539+ 2540+The version of OpenSSL used in our binary builds has been upgraded to 1.1.1u 2541+to address several CVEs. 2542+ 2543+.. 2544+ 2545+.. date: 2023-05-02-17-56-32 2546+.. gh-issue: 99889 2547+.. nonce: l664SU 2548+.. section: Security 2549+ 2550+Fixed a security in flaw in :func:`uu.decode` that could allow for directory 2551+traversal based on the input if no ``out_file`` was specified. 2552+ 2553+.. 2554+ 2555+.. date: 2023-05-01-15-03-25 2556+.. gh-issue: 104049 2557+.. nonce: b01Y3g 2558+.. section: Security 2559+ 2560+Do not expose the local on-disk location in directory indexes produced by 2561+:class:`http.client.SimpleHTTPRequestHandler`. 2562+ 2563+.. 2564+ 2565+.. date: 2023-03-07-20-59-17 2566+.. gh-issue: 102153 2567+.. nonce: 14CLSZ 2568+.. section: Security 2569+ 2570+:func:`urllib.parse.urlsplit` now strips leading C0 control and space 2571+characters following the specification for URLs defined by WHATWG in 2572+response to CVE-2023-24329. Patch by Illia Volochii. 2573+ 2574+.. 2575+ 2576+.. date: 2023-05-31-19-35-22 2577+.. gh-issue: 105164 2578+.. nonce: 6Wajph 2579+.. section: Core and Builtins 2580+ 2581+Ensure annotations are set up correctly if the only annotation in a block is 2582+within a :keyword:`match` block. Patch by Jelle Zijlstra. 2583+ 2584+.. 2585+ 2586+.. date: 2023-05-18-13-00-21 2587+.. gh-issue: 104615 2588+.. nonce: h_rtw2 2589+.. section: Core and Builtins 2590+ 2591+Fix wrong ordering of assignments in code like ``a, a = x, y``. Contributed 2592+by Carl Meyer. 2593+ 2594+.. 2595+ 2596+.. date: 2023-05-14-18-56-54 2597+.. gh-issue: 104482 2598+.. nonce: yaQsv8 2599+.. section: Core and Builtins 2600+ 2601+Fix three error handling bugs in ast.c's validation of pattern matching 2602+statements. 2603+ 2604+.. 2605+ 2606+.. date: 2023-05-13-06-22-52 2607+.. gh-issue: 102818 2608+.. nonce: HIX1Dr 2609+.. section: Core and Builtins 2610+ 2611+Do not add a frame to the traceback in the ``sys.setprofile`` and 2612+``sys.settrace`` trampoline functions. This ensures that frames are not 2613+duplicated if an exception is raised in the callback function, and ensures 2614+that frames are not omitted if a C callback is used and that does not add 2615+the frame. 2616+ 2617+.. 2618+ 2619+.. date: 2023-05-12-00-19-02 2620+.. gh-issue: 104405 2621+.. nonce: tXV5fn 2622+.. section: Core and Builtins 2623+ 2624+Fix an issue where some :term:`bytecode` instructions could ignore 2625+:pep:`523` when "inlining" calls. 2626+ 2627+.. 2628+ 2629+.. date: 2023-05-01-12-03-52 2630+.. gh-issue: 104018 2631+.. nonce: PFxGS4 2632+.. section: Core and Builtins 2633+ 2634+Disallow the "z" format specifier in %-format of bytes objects. 2635+ 2636+.. 2637+ 2638+.. date: 2023-04-28-18-57-13 2639+.. gh-issue: 103971 2640+.. nonce: Q3U9lv 2641+.. section: Core and Builtins 2642+ 2643+Fix an issue where incorrect locations numbers could be assigned to code 2644+following ``case`` blocks. 2645+ 2646+.. 2647+ 2648+.. date: 2023-04-21-17-03-14 2649+.. gh-issue: 102310 2650+.. nonce: anLjDx 2651+.. section: Core and Builtins 2652+ 2653+Change the error range for invalid bytes literals. 2654+ 2655+.. 2656+ 2657+.. date: 2023-04-21-16-12-41 2658+.. gh-issue: 103590 2659+.. nonce: 7DHDOE 2660+.. section: Core and Builtins 2661+ 2662+Do not wrap a single exception raised from a ``try-except*`` construct in an 2663+:exc:`ExceptionGroup`. 2664+ 2665+.. 2666+ 2667+.. date: 2023-04-14-22-35-23 2668+.. gh-issue: 101517 2669+.. nonce: 5EqM-S 2670+.. section: Core and Builtins 2671+ 2672+Fix bug in line numbers of instructions emitted for :keyword:`except* 2673+<except_star>`. 2674+ 2675+.. 2676+ 2677+.. date: 2023-04-08-17-13-07 2678+.. gh-issue: 103242 2679+.. nonce: ysI1b3 2680+.. section: Core and Builtins 2681+ 2682+Migrate :meth:`~ssl.SSLContext.set_ecdh_curve` method not to use deprecated 2683+OpenSSL APIs. Patch by Dong-hee Na. 2684+ 2685+.. 2686+ 2687+.. date: 2023-04-01-00-46-31 2688+.. gh-issue: 102700 2689+.. nonce: 493NB4 2690+.. section: Core and Builtins 2691+ 2692+Allow built-in modules to be submodules. This allows submodules to be 2693+statically linked into a CPython binary. 2694+ 2695+.. 2696+ 2697+.. date: 2023-02-12-22-40-22 2698+.. gh-issue: 101857 2699+.. nonce: _bribG 2700+.. section: Core and Builtins 2701+ 2702+Fix xattr support detection on Linux systems by widening the check to linux, 2703+not just glibc. This fixes support for musl. 2704+ 2705+.. 2706+ 2707+.. date: 2022-11-08-12-36-25 2708+.. gh-issue: 99184 2709+.. nonce: KIaqzz 2710+.. section: Core and Builtins 2711+ 2712+Bypass instance attribute access of ``__name__`` in ``repr`` of 2713+:class:`weakref.ref`. 2714+ 2715+.. 2716+ 2717+.. date: 2022-09-27-11-59-13 2718+.. gh-issue: 96670 2719+.. nonce: XrBBit 2720+.. section: Core and Builtins 2721+ 2722+The parser now raises :exc:`SyntaxError` when parsing source code containing 2723+null bytes. Backported from ``aab01e3``. Patch by Pablo Galindo 2724+ 2725+.. 2726+ 2727+.. bpo: 31821 2728+.. date: 2019-12-01-12-58-31 2729+.. nonce: 1FNmwk 2730+.. section: Core and Builtins 2731+ 2732+Fix :func:`!pause_reading` to work when called from :func:`!connection_made` 2733+in :mod:`asyncio`. 2734+ 2735+.. 2736+ 2737+.. date: 2023-06-02-02-38-26 2738+.. gh-issue: 105080 2739+.. nonce: 2imGMg 2740+.. section: Library 2741+ 2742+Fixed inconsistent signature on derived classes for 2743+:func:`inspect.signature` 2744+ 2745+.. 2746+ 2747+.. date: 2023-05-24-09-34-23 2748+.. gh-issue: 104874 2749+.. nonce: oqyJSy 2750+.. section: Library 2751+ 2752+Document the ``__name__`` and ``__supertype__`` attributes of 2753+:class:`typing.NewType`. Patch by Jelle Zijlstra. 2754+ 2755+.. 2756+ 2757+.. date: 2023-05-17-20-03-01 2758+.. gh-issue: 104340 2759+.. nonce: kp_XmX 2760+.. section: Library 2761+ 2762+When an ``asyncio`` pipe protocol loses its connection due to an error, and 2763+the caller doesn't await ``wait_closed()`` on the corresponding 2764+``StreamWriter``, don't log a warning about an exception that was never 2765+retrieved. After all, according to the ``StreamWriter.close()`` docs, the 2766+``wait_closed()`` call is optional ("not mandatory"). 2767+ 2768+.. 2769+ 2770+.. date: 2023-05-17-08-01-36 2771+.. gh-issue: 104372 2772+.. nonce: jpoWs6 2773+.. section: Library 2774+ 2775+Refactored the ``_posixsubprocess`` internals to avoid Python C API usage 2776+between fork and exec when marking ``pass_fds=`` file descriptors 2777+inheritable. 2778+ 2779+.. 2780+ 2781+.. date: 2023-05-16-11-02-44 2782+.. gh-issue: 75367 2783+.. nonce: qLWR35 2784+.. section: Library 2785+ 2786+Fix data descriptor detection in :func:`inspect.getattr_static`. 2787+ 2788+.. 2789+ 2790+.. date: 2023-05-16-10-07-16 2791+.. gh-issue: 104536 2792+.. nonce: hFWD8f 2793+.. section: Library 2794+ 2795+Fix a race condition in the internal :mod:`multiprocessing.process` cleanup 2796+logic that could manifest as an unintended ``AttributeError`` when calling 2797+``process.close()``. 2798+ 2799+.. 2800+ 2801+.. date: 2023-05-11-23-03-00 2802+.. gh-issue: 104399 2803+.. nonce: MMatTP 2804+.. section: Library 2805+ 2806+Prepare the ``_tkinter`` module for building with Tcl 9.0 and future 2807+libtommath by replacing usage of deprecated functions 2808+:c:func:`mp_to_unsigned_bin_n` and :c:func:`mp_unsigned_bin_size` when 2809+necessary. 2810+ 2811+.. 2812+ 2813+.. date: 2023-05-08-20-57-17 2814+.. gh-issue: 104307 2815+.. nonce: DSB93G 2816+.. section: Library 2817+ 2818+:func:`socket.getnameinfo` now releases the GIL while contacting the DNS 2819+server 2820+ 2821+.. 2822+ 2823+.. date: 2023-05-08-15-39-00 2824+.. gh-issue: 87695 2825+.. nonce: f6iO7v 2826+.. section: Library 2827+ 2828+Fix issue where :meth:`pathlib.Path.glob` raised :exc:`OSError` when it 2829+encountered a symlink to an overly long path. 2830+ 2831+.. 2832+ 2833+.. date: 2023-05-07-19-56-45 2834+.. gh-issue: 104265 2835+.. nonce: fVblry 2836+.. section: Library 2837+ 2838+Prevent possible crash by disallowing instantiation of the 2839+:class:`!_csv.Reader` and :class:`!_csv.Writer` types. The regression was 2840+introduced in 3.10.0a4 with PR 23224 (:issue:`14935`). Patch by Radislav 2841+Chugunov. 2842+ 2843+.. 2844+ 2845+.. date: 2023-05-01-16-43-28 2846+.. gh-issue: 104035 2847+.. nonce: MrJBw8 2848+.. section: Library 2849+ 2850+Do not ignore user-defined ``__getstate__`` and ``__setstate__`` methods for 2851+slotted frozen dataclasses. 2852+ 2853+.. 2854+ 2855+.. date: 2023-04-29-18-23-16 2856+.. gh-issue: 103987 2857+.. nonce: sRgALL 2858+.. section: Library 2859+ 2860+In :mod:`mmap`, fix several bugs that could lead to access to memory-mapped 2861+files after they have been invalidated. 2862+ 2863+.. 2864+ 2865+.. date: 2023-04-27-20-03-08 2866+.. gh-issue: 103935 2867+.. nonce: Uaf2M0 2868+.. section: Library 2869+ 2870+Use :func:`io.open_code` for files to be executed instead of raw 2871+:func:`open` 2872+ 2873+.. 2874+ 2875+.. date: 2023-04-27-00-45-41 2876+.. gh-issue: 100370 2877+.. nonce: MgZ3KY 2878+.. section: Library 2879+ 2880+Fix potential :exc:`OverflowError` in :meth:`sqlite3.Connection.blobopen` 2881+for 32-bit builds. Patch by Erlend E. Aasland. 2882+ 2883+.. 2884+ 2885+.. date: 2023-04-26-09-54-25 2886+.. gh-issue: 103848 2887+.. nonce: aDSnpR 2888+.. section: Library 2889+ 2890+Add checks to ensure that ``[`` bracketed ``]`` hosts found by 2891+:func:`urllib.parse.urlsplit` are of IPv6 or IPvFuture format. 2892+ 2893+.. 2894+ 2895+.. date: 2023-04-26-09-38-47 2896+.. gh-issue: 103872 2897+.. nonce: 8LBsDz 2898+.. section: Library 2899+ 2900+Update the bundled copy of pip to version 23.1.2. 2901+ 2902+.. 2903+ 2904+.. date: 2023-04-25-19-58-13 2905+.. gh-issue: 103861 2906+.. nonce: JeozgD 2907+.. section: Library 2908+ 2909+Fix ``zipfile.Zipfile`` creating invalid zip files when ``force_zip64`` was 2910+used to add files to them. Patch by Carey Metcalfe. 2911+ 2912+.. 2913+ 2914+.. date: 2023-04-24-00-34-23 2915+.. gh-issue: 103685 2916+.. nonce: U14jBM 2917+.. section: Library 2918+ 2919+Prepare :meth:`tkinter.Menu.index` for Tk 8.7 so that it does not raise 2920+``TclError: expected integer but got ""`` when it should return ``None``. 2921+ 2922+.. 2923+ 2924+.. date: 2023-04-22-22-14-09 2925+.. gh-issue: 81403 2926+.. nonce: zVz9Td 2927+.. section: Library 2928+ 2929+:class:`urllib.request.CacheFTPHandler` no longer raises :class:`URLError` 2930+if a cached FTP instance is reused. ftplib's endtransfer method calls 2931+voidresp to drain the connection to handle FTP instance reuse properly. 2932+ 2933+.. 2934+ 2935+.. date: 2023-04-16-18-29-04 2936+.. gh-issue: 103578 2937+.. nonce: fly1wc 2938+.. section: Library 2939+ 2940+Fixed a bug where :mod:`pdb` crashes when reading source file with different 2941+encoding by replacing :func:`io.open` with :func:`io.open_code`. The new 2942+method would also call into the hook set by :func:`PyFile_SetOpenCodeHook`. 2943+ 2944+.. 2945+ 2946+.. date: 2023-04-15-12-19-14 2947+.. gh-issue: 103556 2948+.. nonce: TEf-2m 2949+.. section: Library 2950+ 2951+Now creating :class:`inspect.Signature` objects with positional-only 2952+parameter with a default followed by a positional-or-keyword parameter 2953+without one is impossible. 2954+ 2955+.. 2956+ 2957+.. date: 2023-04-15-11-21-38 2958+.. gh-issue: 103559 2959+.. nonce: a9rYHG 2960+.. section: Library 2961+ 2962+Update the bundled copy of pip to version 23.1.1. 2963+ 2964+.. 2965+ 2966+.. date: 2023-04-12-17-59-55 2967+.. gh-issue: 103365 2968+.. nonce: UBEE0U 2969+.. section: Library 2970+ 2971+Set default Flag boundary to ``STRICT`` and fix bitwise operations. 2972+ 2973+.. 2974+ 2975+.. date: 2023-04-12-13-04-16 2976+.. gh-issue: 103472 2977+.. nonce: C6bOHv 2978+.. section: Library 2979+ 2980+Avoid a potential :exc:`ResourceWarning` in 2981+:class:`http.client.HTTPConnection` by closing the proxy / tunnel's CONNECT 2982+response explicitly. 2983+ 2984+.. 2985+ 2986+.. date: 2023-04-11-21-38-39 2987+.. gh-issue: 103449 2988+.. nonce: -nxmhb 2989+.. section: Library 2990+ 2991+Fix a bug in doc string generation in :func:`dataclasses.dataclass`. 2992+ 2993+.. 2994+ 2995+.. date: 2023-04-06-17-28-36 2996+.. gh-issue: 103256 2997+.. nonce: 1syxfs 2998+.. section: Library 2999+ 3000+Fixed a bug that caused :mod:`hmac` to raise an exception when the requested 3001+hash algorithm was not available in OpenSSL despite being available 3002+separately as part of ``hashlib`` itself. It now falls back properly to the 3003+built-in. This could happen when, for example, your OpenSSL does not include 3004+SHA3 support and you want to compute ``hmac.digest(b'K', b'M', 3005+'sha3_256')``. 3006+ 3007+.. 3008+ 3009+.. date: 2023-04-05-01-28-53 3010+.. gh-issue: 103225 3011+.. nonce: QD3JVU 3012+.. section: Library 3013+ 3014+Fix a bug in :mod:`pdb` when displaying line numbers of module-level source 3015+code. 3016+ 3017+.. 3018+ 3019+.. date: 2023-04-04-12-43-38 3020+.. gh-issue: 93910 3021+.. nonce: jurMzv 3022+.. section: Library 3023+ 3024+Remove deprecation of enum ``memmber.member`` access. 3025+ 3026+.. 3027+ 3028+.. date: 2023-04-03-23-44-34 3029+.. gh-issue: 102978 3030+.. nonce: gy9eVk 3031+.. section: Library 3032+ 3033+Fixes :func:`unittest.mock.patch` not enforcing function signatures for 3034+methods decorated with ``@classmethod`` or ``@staticmethod`` when patch is 3035+called with ``autospec=True``. 3036+ 3037+.. 3038+ 3039+.. date: 2023-04-02-23-05-22 3040+.. gh-issue: 103204 3041+.. nonce: bbDmu0 3042+.. section: Library 3043+ 3044+Fixes :mod:`http.server` accepting HTTP requests with HTTP version numbers 3045+preceded by '+', or '-', or with digit-separating '_' characters. The 3046+length of the version numbers is also constrained. 3047+ 3048+.. 3049+ 3050+.. date: 2023-03-23-15-24-38 3051+.. gh-issue: 102953 3052+.. nonce: YR4KaK 3053+.. section: Library 3054+ 3055+The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`, 3056+have a new a *filter* argument that allows limiting tar features than may be 3057+surprising or dangerous, such as creating files outside the destination 3058+directory. See :ref:`tarfile-extraction-filter` for details. 3059+ 3060+.. 3061+ 3062+.. date: 2023-02-09-22-24-34 3063+.. gh-issue: 101640 3064+.. nonce: oFuEpB 3065+.. section: Library 3066+ 3067+:class:`argparse.ArgumentParser` now catches errors when writing messages, 3068+such as when :data:`sys.stderr` is ``None``. Patch by Oleg Iarygin. 3069+ 3070+.. 3071+ 3072+.. date: 2022-09-07-09-32-07 3073+.. gh-issue: 96522 3074+.. nonce: t73oqp 3075+.. section: Library 3076+ 3077+Fix potential deadlock in pty.spawn() 3078+ 3079+.. 3080+ 3081+.. date: 2022-08-27-21-41-41 3082+.. gh-issue: 87474 3083+.. nonce: 9X-kxt 3084+.. section: Library 3085+ 3086+Fix potential file descriptor leaks in :class:`subprocess.Popen`. 3087+ 3088+.. 3089+ 3090+.. date: 2023-05-28-21-01-00 3091+.. gh-issue: 89455 3092+.. nonce: qAKRrA 3093+.. section: Documentation 3094+ 3095+Add missing documentation for the ``max_group_depth`` and 3096+``max_group_width`` parameters and the ``exceptions`` attribute of the 3097+:class:`traceback.TracebackException` class. 3098+ 3099+.. 3100+ 3101+.. date: 2023-05-28-19-08-42 3102+.. gh-issue: 89412 3103+.. nonce: j4cg7K 3104+.. section: Documentation 3105+ 3106+Add missing documentation for the ``end_lineno`` and ``end_offset`` 3107+attributes of the :class:`traceback.TracebackException` class. 3108+ 3109+.. 3110+ 3111+.. date: 2023-05-25-22-34-31 3112+.. gh-issue: 104943 3113+.. nonce: J2v1Pc 3114+.. section: Documentation 3115+ 3116+Remove mentions of old Python versions in :class:`typing.NamedTuple`. 3117+ 3118+.. 3119+ 3120+.. date: 2023-05-14-12-11-28 3121+.. gh-issue: 67056 3122+.. nonce: nVC2Rf 3123+.. section: Documentation 3124+ 3125+Document that the effect of registering or unregistering an :mod:`atexit` 3126+cleanup function from within a registered cleanup function is undefined. 3127+ 3128+.. 3129+ 3130+.. date: 2023-04-25-22-58-08 3131+.. gh-issue: 48241 3132+.. nonce: l1Gxxh 3133+.. section: Documentation 3134+ 3135+Clarifying documentation about the url parameter to urllib.request.urlopen 3136+and urllib.request.Requst needing to be encoded properly. 3137+ 3138+.. 3139+ 3140+.. date: 2023-05-15-02-22-44 3141+.. gh-issue: 104494 3142+.. nonce: Bkrbfn 3143+.. section: Tests 3144+ 3145+Update ``test_pack_configure_in`` and ``test_place_configure_in`` for 3146+changes to error message formatting in Tk 8.7. 3147+ 3148+.. 3149+ 3150+.. date: 2023-05-14-03-00-00 3151+.. gh-issue: 104461 3152+.. nonce: Rmex11 3153+.. section: Tests 3154+ 3155+Run test_configure_screen on X11 only, since the ``DISPLAY`` environment 3156+variable and ``-screen`` option for toplevels are not useful on Tk for Win32 3157+or Aqua. 3158+ 3159+.. 3160+ 3161+.. date: 2023-04-08-00-50-23 3162+.. gh-issue: 103329 3163+.. nonce: M38tqF 3164+.. section: Tests 3165+ 3166+Regression tests for the behaviour of ``unittest.mock.PropertyMock`` were 3167+added. 3168+ 3169+.. 3170+ 3171+.. date: 2023-02-11-22-36-10 3172+.. gh-issue: 85984 3173+.. nonce: EVXjT9 3174+.. section: Tests 3175+ 3176+Utilize new "winsize" functions from termios in pty tests. 3177+ 3178+.. 3179+ 3180+.. date: 2022-11-06-18-42-38 3181+.. gh-issue: 75729 3182+.. nonce: uGYJrv 3183+.. section: Tests 3184+ 3185+Fix the :func:`os.spawn* <os.spawnl>` tests failing on Windows when the 3186+working directory or interpreter path contains spaces. 3187+ 3188+.. 3189+ 3190+.. date: 2023-06-06-09-08-10 3191+.. gh-issue: 90005 3192+.. nonce: 8mmeJQ 3193+.. section: Build 3194+ 3195+Fix a regression in :file:`configure` where we could end up unintentionally 3196+linking with ``libbsd``. 3197+ 3198+.. 3199+ 3200+.. date: 2023-05-04-10-56-14 3201+.. gh-issue: 104106 3202+.. nonce: -W9BJS 3203+.. section: Build 3204+ 3205+Add gcc fallback of mkfifoat/mknodat for macOS. Patch by Dong-hee Na. 3206+ 3207+.. 3208+ 3209+.. date: 2023-02-11-05-31-05 3210+.. gh-issue: 99069 3211+.. nonce: X4LDvY 3212+.. section: Build 3213+ 3214+Extended workaround defining ``static_assert`` when missing from the libc 3215+headers to all clang and gcc builds. In particular, this fixes building on 3216+macOS <= 10.10. 3217+ 3218+.. 3219+ 3220+.. date: 2023-05-31-16-14-31 3221+.. gh-issue: 105146 3222+.. nonce: gNjqq8 3223+.. section: Windows 3224+ 3225+Updated the links at the end of the installer to point to Discourse rather 3226+than the mailing lists. 3227+ 3228+.. 3229+ 3230+.. date: 2023-05-18-22-46-03 3231+.. gh-issue: 104623 3232+.. nonce: HJZhm1 3233+.. section: Windows 3234+ 3235+Update Windows installer to use SQLite 3.42.0. 3236+ 3237+.. 3238+ 3239+.. date: 2023-03-24-11-25-28 3240+.. gh-issue: 102997 3241+.. nonce: dredy2 3242+.. section: Windows 3243+ 3244+Update Windows installer to use SQLite 3.41.2. 3245+ 3246+.. 3247+ 3248+.. date: 2023-03-18-21-38-00 3249+.. gh-issue: 88013 3250+.. nonce: Z3loxC 3251+.. section: Windows 3252+ 3253+Fixed a bug where :exc:`TypeError` was raised when calling 3254+:func:`ntpath.realpath` with a bytes parameter in some cases. 3255+ 3256+.. 3257+ 3258+.. date: 2023-05-30-23-30-46 3259+.. gh-issue: 103142 3260+.. nonce: 55lMXQ 3261+.. section: macOS 3262+ 3263+Update macOS installer to use OpenSSL 1.1.1u. 3264+ 3265+.. 3266+ 3267+.. date: 2023-05-18-22-31-49 3268+.. gh-issue: 104623 3269+.. nonce: 6h7Xfx 3270+.. section: macOS 3271+ 3272+Update macOS installer to SQLite 3.42.0. 3273+ 3274+.. 3275+ 3276+.. date: 2023-03-24-11-20-47 3277+.. gh-issue: 102997 3278+.. nonce: ZgQkbq 3279+.. section: macOS 3280+ 3281+Update macOS installer to SQLite 3.41.2. 3282+ 3283+.. 3284+ 3285+.. date: 2023-05-23-17-19-49 3286+.. gh-issue: 104719 3287+.. nonce: rvYXH- 3288+.. section: IDLE 3289+ 3290+Remove IDLE's modification of tokenize.tabsize and test other uses of 3291+tokenize data and methods. 3292+ 3293+.. 3294+ 3295+.. date: 2023-05-17-17-32-21 3296+.. gh-issue: 104499 3297+.. nonce: hNeqV4 3298+.. section: IDLE 3299+ 3300+Fix completions for Tk Aqua 8.7 (currently blank). 3301+ 3302+.. 3303+ 3304+.. date: 2023-05-17-15-11-11 3305+.. gh-issue: 104496 3306+.. nonce: wjav-y 3307+.. section: IDLE 3308+ 3309+About prints both tcl and tk versions if different (expected someday). 3310+ 3311+.. 3312+ 3313+.. date: 2023-04-30-20-01-18 3314+.. gh-issue: 88496 3315+.. nonce: y65vUb 3316+.. section: IDLE 3317+ 3318+Fix IDLE test hang on macOS. 3319diff --git a/Misc/config_mingw b/Misc/config_mingw 3320new file mode 100755 3321index 0000000..9be43fd 3322--- /dev/null 3323+++ b/Misc/config_mingw 3324@@ -0,0 +1,15 @@ 3325+# configure defaults for mingw* hosts 3326+ 3327+# mingw functions to ignore 3328+ac_cv_func_ftruncate=ignore # implement it as _chsize 3329+ 3330+# mingw-w64 functions to ignore 3331+ac_cv_func_truncate=ignore 3332+ac_cv_func_alarm=ignore 3333+ 3334+# files to ignore 3335+ac_cv_file__dev_ptmx=ignore #NOTE: under MSYS environment device exist 3336+ac_cv_file__dev_ptc=no 3337+ 3338+# force detection of winsock2 functionality - require wxp or newer 3339+ac_cv_func_getpeername=yes 3340diff --git a/Misc/cross_mingw32 b/Misc/cross_mingw32 3341new file mode 100755 3342index 0000000..03fde9e 3343--- /dev/null 3344+++ b/Misc/cross_mingw32 3345@@ -0,0 +1,11 @@ 3346+# configure defaults for mingw32 host if cross-build 3347+ 3348+ac_cv_little_endian_double=yes 3349+ac_cv_big_endian_double=no 3350+ac_cv_mixed_endian_double=no 3351+ 3352+ac_cv_tanh_preserves_zero_sign=yes 3353+ 3354+ac_cv_wchar_t_signed=no 3355+ 3356+ac_cv_have_size_t_format=no 3357diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in 3358index 2602fe2..e0e048a 100644 3359--- a/Misc/python-config.sh.in 3360+++ b/Misc/python-config.sh.in 3361@@ -1,32 +1,44 @@ 3362 #!/bin/sh 3363 3364-# Keep this script in sync with python-config.in 3365- 3366 exit_with_usage () 3367 { 3368 echo "Usage: $0 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir|--embed" 3369- exit $1 3370+ exit 1 3371 } 3372 3373+# Really, python-config.py (and thus .sh) should be called directly, but 3374+# sometimes software (e.g. GDB) calls python-config.sh as if it were the 3375+# Python executable, passing python-config.py as the first argument. 3376+# Work around that oddness by ignoring any .py passed as first arg. 3377+case "$1" in 3378+ *.py) 3379+ shift 3380+ ;; 3381+esac 3382+ 3383 if [ "$1" = "" ] ; then 3384- exit_with_usage 1 3385+ exit_with_usage 3386 fi 3387 3388 # Returns the actual prefix where this script was installed to. 3389 installed_prefix () 3390 { 3391- RESULT=$(dirname $(cd $(dirname "$1") && pwd -P)) 3392- if which readlink >/dev/null 2>&1 ; then 3393- if readlink -f "$RESULT" >/dev/null 2>&1; then 3394- RESULT=$(readlink -f "$RESULT") 3395- fi 3396+ local RESULT=$(dirname $(cd $(dirname "$1") && pwd -P)) 3397+ if [ $(which readlink) ] ; then 3398+ RESULT=$(readlink -f "$RESULT") 3399+ fi 3400+ # Since we don't know where the output from this script will end up 3401+ # we keep all paths in Windows-land since MSYS2 can handle that 3402+ # while native tools can't handle paths in MSYS2-land. 3403+ if [ "$OSTYPE" = "msys" ]; then 3404+ RESULT=$(cd "$RESULT" && pwd -W) 3405 fi 3406 echo $RESULT 3407 } 3408 3409 prefix_real=$(installed_prefix "$0") 3410 3411-# Use sed to fix paths from their built-to locations to their installed-to 3412+# Use sed to fix paths from their built-to locations to their installed to 3413 # locations. Keep prefix & exec_prefix using their original values in case 3414 # they are referenced in other configure variables, to prevent double 3415 # substitution, issue #22140. 3416@@ -41,13 +53,17 @@ LIBM="@LIBM@" 3417 LIBC="@LIBC@" 3418 SYSLIBS="$LIBM $LIBC" 3419 ABIFLAGS="@ABIFLAGS@" 3420+# Protect against lack of substitution. 3421+if [ "$ABIFLAGS" = "@""ABIFLAGS""@" ] ; then 3422+ ABIFLAGS= 3423+fi 3424 LIBS="@LIBPYTHON@ @LIBS@ $SYSLIBS" 3425 LIBS_EMBED="-lpython${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS" 3426 BASECFLAGS="@BASECFLAGS@" 3427-LDLIBRARY="@LDLIBRARY@" 3428 OPT="@OPT@" 3429 PY_ENABLE_SHARED="@PY_ENABLE_SHARED@" 3430 LDVERSION="@LDVERSION@" 3431+LDLIBRARY="@LDLIBRARY@" 3432 LIBDEST=${prefix_real}/lib/python${VERSION} 3433 LIBPL=$(echo "@LIBPL@" | sed "s#$prefix#$prefix_real#") 3434 SO="@EXT_SUFFIX@" 3435@@ -61,7 +77,7 @@ for ARG in $* 3436 do 3437 case $ARG in 3438 --help) 3439- exit_with_usage 0 3440+ exit_with_usage 3441 ;; 3442 --embed) 3443 PY_EMBED=1 3444@@ -69,7 +85,7 @@ do 3445 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--abiflags|--configdir) 3446 ;; 3447 *) 3448- exit_with_usage 1 3449+ exit_with_usage 3450 ;; 3451 esac 3452 done 3453@@ -80,37 +96,37 @@ fi 3454 3455 for ARG in "$@" 3456 do 3457- case "$ARG" in 3458+ case $ARG in 3459 --prefix) 3460- echo "$prefix_real" 3461+ echo -ne "$prefix_real" 3462 ;; 3463 --exec-prefix) 3464- echo "$exec_prefix_real" 3465+ echo -ne "$exec_prefix_real " 3466 ;; 3467 --includes) 3468- echo "$INCDIR $PLATINCDIR" 3469+ echo -ne "$INCDIR $PLATINCDIR" 3470 ;; 3471 --cflags) 3472- echo "$INCDIR $PLATINCDIR $BASECFLAGS $CFLAGS $OPT" 3473+ echo -ne "$INCDIR $PLATINCDIR $BASECFLAGS $CFLAGS $OPT" 3474 ;; 3475 --libs) 3476- echo "$LIBS" 3477+ echo -ne "$LIBS" 3478 ;; 3479 --ldflags) 3480 LIBPLUSED= 3481 if [ "$PY_ENABLE_SHARED" = "0" ] ; then 3482 LIBPLUSED="-L$LIBPL" 3483 fi 3484- echo "$LIBPLUSED -L$libdir $LIBS" 3485+ echo -ne "$LIBPLUSED -L$libdir $LIBS " 3486 ;; 3487 --extension-suffix) 3488- echo "$SO" 3489+ echo -ne "$SO " 3490 ;; 3491 --abiflags) 3492- echo "$ABIFLAGS" 3493+ echo -ne "$ABIFLAGS " 3494 ;; 3495 --configdir) 3496- echo "$LIBPL" 3497+ echo -ne "$LIBPL " 3498 ;; 3499 esac 3500 done 3501diff --git a/Misc/python.pc.in b/Misc/python.pc.in 3502index 87e04de..3900190 100644 3503--- a/Misc/python.pc.in 3504+++ b/Misc/python.pc.in 3505@@ -9,5 +9,5 @@ Description: Build a C extension for Python 3506 Requires: 3507 Version: @VERSION@ 3508 Libs.private: @LIBS@ 3509-Libs: 3510+Libs: -L${libdir} -lpython@VERSION@@ABIFLAGS@ 3511 Cflags: -I${includedir}/python@VERSION@@ABIFLAGS@ 3512diff --git a/Modules/Setup.bootstrap.in b/Modules/Setup.bootstrap.in 3513index e3e9b96..6986290 100644 3514--- a/Modules/Setup.bootstrap.in 3515+++ b/Modules/Setup.bootstrap.in 3516@@ -8,15 +8,15 @@ 3517 # module C APIs are used in core 3518 atexit atexitmodule.c 3519 faulthandler faulthandler.c 3520-posix posixmodule.c 3521-_signal signalmodule.c 3522+@INITSYS@ posixmodule.c 3523+_signal signalmodule.c -lws2_32 3524 _tracemalloc _tracemalloc.c 3525 3526 # modules used by importlib, deepfreeze, freeze, runpy, and sysconfig 3527 _codecs _codecsmodule.c 3528 _collections _collectionsmodule.c 3529 errno errnomodule.c 3530-_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c 3531+_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 3532 itertools itertoolsmodule.c 3533 _sre _sre/sre.c 3534 _thread _threadmodule.c 3535@@ -33,3 +33,8 @@ _symtable symtablemodule.c 3536 3537 # for systems without $HOME env, used by site._getuserbase() 3538 @MODULE_PWD_TRUE@pwd pwdmodule.c 3539+ 3540+# build-in modules for windows platform: 3541+@USE_WIN32_MODULE@winreg ../PC/winreg.c 3542+@MODULE_MSVCRT_TRUE@msvcrt -DPy_BUILD_CORE ../PC/msvcrtmodule.c 3543+@MODULE__WINAPI_TRUE@_winapi _winapi.c 3544diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c 3545index fc73264..6ed71fa 100644 3546--- a/Modules/_ctypes/_ctypes.c 3547+++ b/Modules/_ctypes/_ctypes.c 3548@@ -3403,6 +3403,18 @@ static PPROC FindAddress(void *handle, const char *name, PyObject *type) 3549 mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */ 3550 if (!mangled_name) 3551 return NULL; 3552+ /* Issue: for stdcall decorated export functions MSVC compiler adds 3553+ * underscore, but GCC compiler create them without. This is 3554+ * visible by example for _ctypes_test.pyd module. 3555+ * As well functions from system libraries are without underscore. 3556+ * Solutions: 3557+ * - If a python module is build with gcc option --add-stdcall-alias 3558+ * the module will contain XXX as alias for function XXX@ as result 3559+ * first search in this method will succeed. 3560+ * - Distutil may use compiler to create def-file, to modify it as 3561+ * add underscore alias and with new def file to create module. 3562+ * - Or may be just to search for function without underscore. 3563+ */ 3564 for (i = 0; i < 32; ++i) { 3565 sprintf(mangled_name, "_%s@%d", name, i*4); 3566 Py_BEGIN_ALLOW_THREADS 3567@@ -3410,6 +3422,13 @@ static PPROC FindAddress(void *handle, const char *name, PyObject *type) 3568 Py_END_ALLOW_THREADS 3569 if (address) 3570 return address; 3571+ /* search for function without underscore as weel */ 3572+ sprintf(mangled_name, "%s@%d", name, i*4); 3573+ Py_BEGIN_ALLOW_THREADS 3574+ address = (PPROC)GetProcAddress(handle, mangled_name); 3575+ Py_END_ALLOW_THREADS 3576+ if (address) 3577+ return address; 3578 } 3579 return NULL; 3580 #endif 3581diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c 3582index e6440fa..f42714a 100644 3583--- a/Modules/_gdbmmodule.c 3584+++ b/Modules/_gdbmmodule.c 3585@@ -12,7 +12,7 @@ 3586 #include <sys/stat.h> 3587 #include <sys/types.h> 3588 3589-#if defined(WIN32) && !defined(__CYGWIN__) 3590+#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__) 3591 #include "gdbmerrno.h" 3592 extern const char * gdbm_strerror(gdbm_error); 3593 #endif 3594diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c 3595index 4496609..80cc6f9 100644 3596--- a/Modules/_io/fileio.c 3597+++ b/Modules/_io/fileio.c 3598@@ -20,6 +20,7 @@ 3599 #endif 3600 #include <stddef.h> /* For offsetof */ 3601 #include "_iomodule.h" 3602+#include "iscygpty.h" 3603 3604 /* 3605 * Known likely problems: 3606@@ -1129,7 +1130,7 @@ _io_FileIO_isatty_impl(fileio *self) 3607 return err_closed(); 3608 Py_BEGIN_ALLOW_THREADS 3609 _Py_BEGIN_SUPPRESS_IPH 3610- res = isatty(self->fd); 3611+ res = isatty(self->fd) || is_cygpty(self->fd); 3612 _Py_END_SUPPRESS_IPH 3613 Py_END_ALLOW_THREADS 3614 return PyBool_FromLong(res); 3615diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c 3616index 23c38e1..dfb6c7e 100644 3617--- a/Modules/_localemodule.c 3618+++ b/Modules/_localemodule.c 3619@@ -12,6 +12,13 @@ This software comes with no warranty. Use at your own risk. 3620 #define PY_SSIZE_T_CLEAN 3621 #include "Python.h" 3622 #include "pycore_fileutils.h" 3623+#ifdef __MINGW32__ 3624+/* The header libintl.h and library libintl may exist on mingw host. 3625+ * To be compatible with MSVC build we has to undef some defines. 3626+ */ 3627+#undef HAVE_LIBINTL_H 3628+#undef HAVE_BIND_TEXTDOMAIN_CODESET 3629+#endif 3630 3631 #include <stdio.h> 3632 #include <locale.h> 3633diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c 3634index 0809c24..bbb1b38 100644 3635--- a/Modules/_multiprocessing/multiprocessing.c 3636+++ b/Modules/_multiprocessing/multiprocessing.c 3637@@ -172,7 +172,7 @@ static PyMethodDef module_methods[] = { 3638 _MULTIPROCESSING_RECV_METHODDEF 3639 _MULTIPROCESSING_SEND_METHODDEF 3640 #endif 3641-#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__) 3642+#if defined(MS_WINDOWS) || (!defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)) 3643 _MULTIPROCESSING_SEM_UNLINK_METHODDEF 3644 #endif 3645 {NULL} 3646diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h 3647index 3a8314b..c07cfe8 100644 3648--- a/Modules/_multiprocessing/multiprocessing.h 3649+++ b/Modules/_multiprocessing/multiprocessing.h 3650@@ -21,7 +21,10 @@ 3651 # endif 3652 # define SEM_HANDLE HANDLE 3653 # define SEM_VALUE_MAX LONG_MAX 3654-# define HAVE_MP_SEMAPHORE 3655+# define HAVE_MP_SEMAPHORE 3656+# if defined(HAVE_SEM_OPEN) && defined(_POSIX_THREADS) 3657+# include <semaphore.h> 3658+# endif 3659 #else 3660 # include <fcntl.h> /* O_CREAT and O_EXCL */ 3661 # if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) 3662diff --git a/Modules/_winapi.c b/Modules/_winapi.c 3663index f6bb07f..56f3306 100644 3664--- a/Modules/_winapi.c 3665+++ b/Modules/_winapi.c 3666@@ -41,7 +41,9 @@ 3667 3668 #define WINDOWS_LEAN_AND_MEAN 3669 #include "windows.h" 3670+#if defined(Py_DEBUG) 3671 #include <crtdbg.h> 3672+#endif 3673 #include "winreparse.h" 3674 3675 #if defined(MS_WIN32) && !defined(MS_WIN64) 3676@@ -957,7 +959,7 @@ getattributelist(PyObject *obj, const char *name, AttributeList *attribute_list) 3677 DWORD err; 3678 BOOL result; 3679 PyObject *value; 3680- Py_ssize_t handle_list_size; 3681+ Py_ssize_t handle_list_size = 0; 3682 DWORD attribute_count = 0; 3683 SIZE_T attribute_list_size = 0; 3684 3685diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c 3686index e5b96be..0e5ab45 100644 3687--- a/Modules/_xxsubinterpretersmodule.c 3688+++ b/Modules/_xxsubinterpretersmodule.c 3689@@ -1765,7 +1765,7 @@ PyDoc_STRVAR(channelid_doc, 3690 "A channel ID identifies a channel and may be used as an int."); 3691 3692 static PyTypeObject ChannelIDtype = { 3693- PyVarObject_HEAD_INIT(&PyType_Type, 0) 3694+ PyVarObject_HEAD_INIT(NULL, 0) 3695 "_xxsubinterpreters.ChannelID", /* tp_name */ 3696 sizeof(channelid), /* tp_basicsize */ 3697 0, /* tp_itemsize */ 3698diff --git a/Modules/getpath.c b/Modules/getpath.c 3699index bc730fc..0419c2a 100644 3700--- a/Modules/getpath.c 3701+++ b/Modules/getpath.c 3702@@ -54,6 +54,25 @@ 3703 3704 /* HELPER FUNCTIONS for getpath.py */ 3705 3706+static PyObject * 3707+getpath_normpath(PyObject *Py_UNUSED(self), PyObject *args) 3708+{ 3709+ PyObject *r = NULL; 3710+ PyObject *pathobj; 3711+ wchar_t *path; 3712+ if (!PyArg_ParseTuple(args, "U", &pathobj)) { 3713+ return NULL; 3714+ } 3715+ Py_ssize_t len; 3716+ wchar_t *buffer = PyUnicode_AsWideCharString(pathobj, &len); 3717+ if (!buffer) { 3718+ return NULL; 3719+ } 3720+ r = PyUnicode_FromWideChar(_Py_normpath(buffer, len), -1); 3721+ PyMem_Free(buffer); 3722+ return r; 3723+} 3724+ 3725 static PyObject * 3726 getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args) 3727 { 3728@@ -88,6 +107,12 @@ getpath_basename(PyObject *Py_UNUSED(self), PyObject *args) 3729 } 3730 Py_ssize_t end = PyUnicode_GET_LENGTH(path); 3731 Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1); 3732+#ifdef ALTSEP 3733+ if (pos < 0) { 3734+ // try using altsep 3735+ pos = PyUnicode_FindChar(path, ALTSEP, 0, end, -1); 3736+ } 3737+#endif 3738 if (pos < 0) { 3739 return Py_NewRef(path); 3740 } 3741@@ -104,6 +129,12 @@ getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args) 3742 } 3743 Py_ssize_t end = PyUnicode_GET_LENGTH(path); 3744 Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1); 3745+#ifdef ALTSEP 3746+ if (pos < 0) { 3747+ // try using altsep 3748+ pos = PyUnicode_FindChar(path, ALTSEP, 0, end, -1); 3749+ } 3750+#endif 3751 if (pos < 0) { 3752 return PyUnicode_FromStringAndSize(NULL, 0); 3753 } 3754@@ -513,6 +544,7 @@ getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args) 3755 3756 3757 static PyMethodDef getpath_methods[] = { 3758+ {"normpath", getpath_normpath, METH_VARARGS, NULL}, 3759 {"abspath", getpath_abspath, METH_VARARGS, NULL}, 3760 {"basename", getpath_basename, METH_VARARGS, NULL}, 3761 {"dirname", getpath_dirname, METH_VARARGS, NULL}, 3762@@ -884,6 +916,11 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) 3763 #else 3764 !decode_to_dict(dict, "os_name", "posix") || 3765 #endif 3766+#ifdef __MINGW32__ 3767+ !int_to_dict(dict, "is_mingw", 1) || 3768+#else 3769+ !int_to_dict(dict, "is_mingw", 0) || 3770+#endif 3771 #ifdef WITH_NEXT_FRAMEWORK 3772 !int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 1) || 3773 #else 3774@@ -910,6 +947,9 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) 3775 !funcs_to_dict(dict, config->pathconfig_warnings) || 3776 #ifndef MS_WINDOWS 3777 PyDict_SetItemString(dict, "winreg", Py_None) < 0 || 3778+#endif 3779+#ifdef __MINGW32__ 3780+ !env_to_dict(dict, "ENV_MSYSTEM", 0) || 3781 #endif 3782 PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins()) < 0 3783 ) { 3784diff --git a/Modules/getpath.py b/Modules/getpath.py 3785index 74f918c..c98cb1f 100644 3786--- a/Modules/getpath.py 3787+++ b/Modules/getpath.py 3788@@ -30,6 +30,7 @@ 3789 3790 # ** Values known at compile time ** 3791 # os_name -- [in] one of 'nt', 'posix', 'darwin' 3792+# is_mingw -- [in] True if targeting MinGW 3793 # PREFIX -- [in] sysconfig.get_config_var(...) 3794 # EXEC_PREFIX -- [in] sysconfig.get_config_var(...) 3795 # PYTHONPATH -- [in] sysconfig.get_config_var(...) 3796@@ -51,6 +52,7 @@ 3797 # ENV_PYTHONHOME -- [in] getenv(...) 3798 # ENV_PYTHONEXECUTABLE -- [in] getenv(...) 3799 # ENV___PYVENV_LAUNCHER__ -- [in] getenv(...) 3800+# ENV_MSYSTEM -- [in] getenv(...) 3801 3802 # ** Values calculated at runtime ** 3803 # config -- [in/out] dict of the PyConfig structure 3804@@ -185,8 +187,27 @@ 3805 ZIP_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}{VERSION_MINOR}.zip' 3806 DELIM = ':' 3807 SEP = '/' 3808+ ALTSEP = None 3809 3810-elif os_name == 'nt': 3811+elif os_name == 'nt' and is_mingw: 3812+ BUILDDIR_TXT = 'pybuilddir.txt' 3813+ BUILD_LANDMARK = 'Modules/Setup.local' 3814+ DEFAULT_PROGRAM_NAME = f'python{VERSION_MAJOR}' 3815+ STDLIB_SUBDIR = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}' 3816+ STDLIB_LANDMARKS = [f'{STDLIB_SUBDIR}/os.py', f'{STDLIB_SUBDIR}/os.pyc'] 3817+ PLATSTDLIB_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}/lib-dynload' 3818+ BUILDSTDLIB_LANDMARKS = ['Lib/os.py'] 3819+ VENV_LANDMARK = 'pyvenv.cfg' 3820+ ZIP_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}{VERSION_MINOR}.zip' 3821+ DELIM = ';' 3822+ if ENV_MSYSTEM: 3823+ SEP = '/' 3824+ ALTSEP = '\\' 3825+ else: 3826+ SEP = '\\' 3827+ ALTSEP = '/' 3828+ 3829+elif os_name == 'nt': # MSVC 3830 BUILDDIR_TXT = 'pybuilddir.txt' 3831 BUILD_LANDMARK = f'{VPATH}\\Modules\\Setup.local' 3832 DEFAULT_PROGRAM_NAME = f'python' 3833@@ -199,6 +220,7 @@ 3834 WINREG_KEY = f'SOFTWARE\\Python\\PythonCore\\{PYWINVER}\\PythonPath' 3835 DELIM = ';' 3836 SEP = '\\' 3837+ ALTSEP = '/' 3838 3839 3840 # ****************************************************************************** 3841@@ -211,6 +233,8 @@ def search_up(prefix, *landmarks, test=isfile): 3842 return prefix 3843 prefix = dirname(prefix) 3844 3845+def _normpath(p): 3846+ return normpath(p) if p is not None else None 3847 3848 # ****************************************************************************** 3849 # READ VARIABLES FROM config 3850@@ -263,10 +287,10 @@ def search_up(prefix, *landmarks, test=isfile): 3851 if not executable: 3852 executable = real_executable 3853 3854-if not executable and SEP in program_name: 3855+if not executable and (SEP in program_name or 3856+ (ALTSEP and ALTSEP in program_name)): 3857 # Resolve partial path program_name against current directory 3858 executable = abspath(program_name) 3859- 3860 if not executable: 3861 # All platforms default to real_executable if known at this 3862 # stage. POSIX does not set this value. 3863@@ -497,15 +521,15 @@ def search_up(prefix, *landmarks, test=isfile): 3864 except (FileNotFoundError, PermissionError): 3865 if isfile(joinpath(real_executable_dir, BUILD_LANDMARK)): 3866 build_prefix = joinpath(real_executable_dir, VPATH) 3867- if os_name == 'nt': 3868+ if os_name == 'nt' and not is_mingw: 3869 # QUIRK: Windows builds need platstdlib_dir to be the executable 3870 # dir. Normally the builddir marker handles this, but in this 3871 # case we need to correct manually. 3872 platstdlib_dir = real_executable_dir 3873 3874 if build_prefix: 3875- if os_name == 'nt': 3876- # QUIRK: No searching for more landmarks on Windows 3877+ if os_name == 'nt' and not is_mingw: 3878+ # QUIRK: No searching for more landmarks on MSVC 3879 build_stdlib_prefix = build_prefix 3880 else: 3881 build_stdlib_prefix = search_up(build_prefix, *BUILDSTDLIB_LANDMARKS) 3882@@ -552,6 +576,9 @@ def search_up(prefix, *landmarks, test=isfile): 3883 # First try to detect prefix by looking alongside our runtime library, if known 3884 if library and not prefix: 3885 library_dir = dirname(library) 3886+ if os_name == 'nt' and is_mingw: 3887+ # QUIRK: On Windows, mingw Python DLLs are in the bin directory 3888+ library_dir = joinpath(library_dir, '..') 3889 if ZIP_LANDMARK: 3890 if os_name == 'nt': 3891 # QUIRK: Windows does not search up for ZIP file 3892@@ -597,7 +624,7 @@ def search_up(prefix, *landmarks, test=isfile): 3893 3894 # Detect exec_prefix by searching from executable for the platstdlib_dir 3895 if PLATSTDLIB_LANDMARK and not exec_prefix: 3896- if os_name == 'nt': 3897+ if os_name == 'nt' and (not is_mingw): 3898 # QUIRK: Windows always assumed these were the same 3899 # gh-100320: Our PYDs are assumed to be relative to the Lib directory 3900 # (that is, prefix) rather than the executable (that is, executable_dir) 3901@@ -607,7 +634,7 @@ def search_up(prefix, *landmarks, test=isfile): 3902 if not exec_prefix and EXEC_PREFIX: 3903 exec_prefix = EXEC_PREFIX 3904 if not exec_prefix or not isdir(joinpath(exec_prefix, PLATSTDLIB_LANDMARK)): 3905- if os_name == 'nt': 3906+ if os_name == 'nt' and (not is_mingw): 3907 # QUIRK: If DLLs is missing on Windows, don't warn, just assume 3908 # that they're in exec_prefix 3909 if not platstdlib_dir: 3910@@ -645,7 +672,7 @@ def search_up(prefix, *landmarks, test=isfile): 3911 3912 if py_setpath: 3913 # If Py_SetPath was called then it overrides any existing search path 3914- config['module_search_paths'] = py_setpath.split(DELIM) 3915+ config['module_search_paths'] = [_normpath(p) for p in py_setpath.split(DELIM)] 3916 config['module_search_paths_set'] = 1 3917 3918 elif not pythonpath_was_set: 3919@@ -660,7 +687,7 @@ def search_up(prefix, *landmarks, test=isfile): 3920 pythonpath.append(abspath(p)) 3921 3922 # Then add the default zip file 3923- if os_name == 'nt': 3924+ if os_name == 'nt' and (not is_mingw): 3925 # QUIRK: Windows uses the library directory rather than the prefix 3926 if library: 3927 library_dir = dirname(library) 3928@@ -673,7 +700,7 @@ def search_up(prefix, *landmarks, test=isfile): 3929 else: 3930 pythonpath.append(joinpath(prefix, ZIP_LANDMARK)) 3931 3932- if os_name == 'nt' and use_environment and winreg: 3933+ if (not is_mingw) and os_name == 'nt' and use_environment and winreg: 3934 # QUIRK: Windows also lists paths in the registry. Paths are stored 3935 # as the default value of each subkey of 3936 # {HKCU,HKLM}\Software\Python\PythonCore\{winver}\PythonPath 3937@@ -714,7 +741,7 @@ def search_up(prefix, *landmarks, test=isfile): 3938 if not platstdlib_dir and exec_prefix: 3939 platstdlib_dir = joinpath(exec_prefix, PLATSTDLIB_LANDMARK) 3940 3941- if os_name == 'nt': 3942+ if os_name == 'nt' and (not is_mingw): 3943 # QUIRK: Windows generates paths differently 3944 if platstdlib_dir: 3945 pythonpath.append(platstdlib_dir) 3946@@ -732,7 +759,7 @@ def search_up(prefix, *landmarks, test=isfile): 3947 if platstdlib_dir: 3948 pythonpath.append(platstdlib_dir) 3949 3950- config['module_search_paths'] = pythonpath 3951+ config['module_search_paths'] = [_normpath(p) for p in pythonpath] 3952 config['module_search_paths_set'] = 1 3953 3954 3955@@ -742,8 +769,8 @@ def search_up(prefix, *landmarks, test=isfile): 3956 3957 # QUIRK: Non-Windows replaces prefix/exec_prefix with defaults when running 3958 # in build directory. This happens after pythonpath calculation. 3959-if os_name != 'nt' and build_prefix: 3960- prefix = config.get('prefix') or PREFIX 3961+if (os_name != 'nt' or is_mingw) and build_prefix: 3962+ prefix = config.get('prefix') or abspath(PREFIX) 3963 exec_prefix = config.get('exec_prefix') or EXEC_PREFIX or prefix 3964 3965 3966@@ -767,23 +794,23 @@ def search_up(prefix, *landmarks, test=isfile): 3967 warn("unsupported 'import' line in ._pth file") 3968 else: 3969 pythonpath.append(joinpath(pth_dir, line)) 3970- config['module_search_paths'] = pythonpath 3971+ config['module_search_paths'] = [_normpath(p) for p in pythonpath] 3972 config['module_search_paths_set'] = 1 3973 3974 # ****************************************************************************** 3975 # UPDATE config FROM CALCULATED VALUES 3976 # ****************************************************************************** 3977 3978-config['program_name'] = program_name 3979-config['home'] = home 3980-config['executable'] = executable 3981-config['base_executable'] = base_executable 3982-config['prefix'] = prefix 3983-config['exec_prefix'] = exec_prefix 3984-config['base_prefix'] = base_prefix or prefix 3985-config['base_exec_prefix'] = base_exec_prefix or exec_prefix 3986+config['program_name'] = _normpath(program_name) 3987+config['home'] = _normpath(home) 3988+config['executable'] = _normpath(executable) 3989+config['base_executable'] = _normpath(base_executable) 3990+config['prefix'] = _normpath(prefix) 3991+config['exec_prefix'] = _normpath(exec_prefix) 3992+config['base_prefix'] = _normpath(base_prefix or prefix) 3993+config['base_exec_prefix'] = _normpath(base_exec_prefix or exec_prefix) 3994 3995-config['platlibdir'] = platlibdir 3996+config['platlibdir'] = _normpath(platlibdir) 3997 # test_embed expects empty strings, not None 3998-config['stdlib_dir'] = stdlib_dir or '' 3999-config['platstdlib_dir'] = platstdlib_dir or '' 4000+config['stdlib_dir'] = _normpath(stdlib_dir or '') 4001+config['platstdlib_dir'] = _normpath(platstdlib_dir or '') 4002diff --git a/Modules/main.c b/Modules/main.c 4003index 6904e3f..5c8708e 100644 4004--- a/Modules/main.c 4005+++ b/Modules/main.c 4006@@ -7,6 +7,7 @@ 4007 #include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() 4008 #include "pycore_pylifecycle.h" // _Py_PreInitializeFromPyArgv() 4009 #include "pycore_pystate.h" // _PyInterpreterState_GET() 4010+#include "iscygpty.h" 4011 4012 /* Includes for exit_sigint() */ 4013 #include <stdio.h> // perror() 4014@@ -92,7 +93,7 @@ static inline int config_run_code(const PyConfig *config) 4015 static int 4016 stdin_is_interactive(const PyConfig *config) 4017 { 4018- return (isatty(fileno(stdin)) || config->interactive); 4019+ return (isatty(fileno(stdin)) || config->interactive || is_cygpty(fileno(stdin))); 4020 } 4021 4022 4023diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c 4024index a01662d..c2362a6 100644 4025--- a/Modules/posixmodule.c 4026+++ b/Modules/posixmodule.c 4027@@ -50,6 +50,7 @@ 4028 #ifdef __ANDROID__ 4029 # undef HAVE_FACCESSAT 4030 #endif 4031+#include "iscygpty.h" 4032 4033 #include <stdio.h> // ctermid() 4034 #include <stdlib.h> // system() 4035@@ -350,6 +351,32 @@ corresponding Unix manual entries for more information on calls."); 4036 # define HAVE_CWAIT 1 4037 # define HAVE_FSYNC 1 4038 # define fsync _commit 4039+# elif defined(__MINGW32__) /* GCC for windows hosts */ 4040+/* getlogin is detected by configure on mingw-w64 */ 4041+# undef HAVE_GETLOGIN 4042+/* opendir is detected by configure on mingw-w64, and for some reason 4043+things don't work as expected. For example, os.listdir always returns 4044+the cwd's directory listing instead of the one specified. By 4045+un-defining, this, os.listdir will use the one which uses native 4046+windows API. */ 4047+# undef HAVE_OPENDIR 4048+/*# define HAVE_GETCWD 1 - detected by configure*/ 4049+# define HAVE_GETPPID 1 4050+# define HAVE_GETLOGIN 1 4051+# define HAVE_SPAWNV 1 4052+# define HAVE_WSPAWNV 1 4053+# define HAVE_WEXECV 1 4054+/*# define HAVE_EXECV 1 - detected by configure*/ 4055+# define HAVE_PIPE 1 4056+# define HAVE_POPEN 1 4057+# define HAVE_SYSTEM 1 4058+# define HAVE_CWAIT 1 4059+# define HAVE_FSYNC 1 4060+# define fsync _commit 4061+# include <winioctl.h> 4062+# ifndef _MAX_ENV 4063+# define _MAX_ENV 32767 4064+# endif 4065 # endif /* _MSC_VER */ 4066 #endif /* ! __WATCOMC__ || __QNX__ */ 4067 4068@@ -428,7 +455,7 @@ extern char *ctermid_r(char *); 4069 # endif 4070 #endif 4071 4072-#ifdef _MSC_VER 4073+#ifdef MS_WINDOWS 4074 # ifdef HAVE_DIRECT_H 4075 # include <direct.h> 4076 # endif 4077@@ -439,7 +466,7 @@ extern char *ctermid_r(char *); 4078 # include <process.h> 4079 # endif 4080 # include <malloc.h> 4081-#endif /* _MSC_VER */ 4082+#endif /* MS_WINDOWS */ 4083 4084 #ifndef MAXPATHLEN 4085 # if defined(PATH_MAX) && PATH_MAX > 1024 4086@@ -1593,9 +1620,9 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) 4087 ** man environ(7). 4088 */ 4089 #include <crt_externs.h> 4090-#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__)) 4091+#elif !defined(MS_WINDOWS) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__)) 4092 extern char **environ; 4093-#endif /* !_MSC_VER */ 4094+#endif /* !MS_WINDOWS */ 4095 4096 static PyObject * 4097 convertenviron(void) 4098@@ -3815,6 +3842,7 @@ posix_getcwd(int use_bytes) 4099 return PyErr_SetFromWindowsErr(0); 4100 } 4101 4102+ Py_NormalizeSepsW(wbuf2); 4103 PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len); 4104 if (wbuf2 != wbuf) { 4105 PyMem_RawFree(wbuf2); 4106@@ -4419,6 +4447,7 @@ os__getfinalpathname_impl(PyObject *module, path_t *path) 4107 target_path = tmp; 4108 } 4109 4110+ Py_NormalizeSepsW(target_path); 4111 result = PyUnicode_FromWideChar(target_path, result_length); 4112 if (result && path->narrow) { 4113 Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); 4114@@ -5467,7 +5496,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, 4115 /*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/ 4116 { 4117 #ifdef MS_WINDOWS 4118- HANDLE hFile; 4119+ HANDLE hFile = 0; 4120 FILETIME atime, mtime; 4121 #else 4122 int result; 4123@@ -10194,7 +10223,7 @@ os_isatty_impl(PyObject *module, int fd) 4124 int return_value; 4125 Py_BEGIN_ALLOW_THREADS 4126 _Py_BEGIN_SUPPRESS_IPH 4127- return_value = isatty(fd); 4128+ return_value = isatty(fd) || is_cygpty(fd); 4129 _Py_END_SUPPRESS_IPH 4130 Py_END_ALLOW_THREADS 4131 return return_value; 4132@@ -14682,7 +14711,7 @@ os__add_dll_directory_impl(PyObject *module, path_t *path) 4133 loaded. */ 4134 Py_BEGIN_ALLOW_THREADS 4135 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || 4136- !(AddDllDirectory = (PAddDllDirectory)GetProcAddress( 4137+ !(AddDllDirectory = (PAddDllDirectory)(void *)GetProcAddress( 4138 hKernel32, "AddDllDirectory")) || 4139 !(cookie = (*AddDllDirectory)(path->wide))) { 4140 err = GetLastError(); 4141@@ -14732,7 +14761,7 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) 4142 loaded. */ 4143 Py_BEGIN_ALLOW_THREADS 4144 if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || 4145- !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress( 4146+ !(RemoveDllDirectory = (PRemoveDllDirectory)(void *)GetProcAddress( 4147 hKernel32, "RemoveDllDirectory")) || 4148 !(*RemoveDllDirectory)(cookieValue)) { 4149 err = GetLastError(); 4150diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c 4151index 4eea928..6be3582 100644 4152--- a/Modules/selectmodule.c 4153+++ b/Modules/selectmodule.c 4154@@ -146,9 +146,9 @@ seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) 4155 v = PyObject_AsFileDescriptor( o ); 4156 if (v == -1) goto finally; 4157 4158-#if defined(_MSC_VER) 4159+#if defined(MS_WIN32) 4160 max = 0; /* not used for Win32 */ 4161-#else /* !_MSC_VER */ 4162+#else /* !MS_WIN32 */ 4163 if (!_PyIsSelectable_fd(v)) { 4164 PyErr_SetString(PyExc_ValueError, 4165 "filedescriptor out of range in select()"); 4166@@ -156,7 +156,7 @@ seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1]) 4167 } 4168 if (v > max) 4169 max = v; 4170-#endif /* _MSC_VER */ 4171+#endif /* MS_WIN32 */ 4172 FD_SET(v, set); 4173 4174 /* add object and its file descriptor to the list */ 4175diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c 4176index 65d0e10..d1bfe3d 100644 4177--- a/Modules/socketmodule.c 4178+++ b/Modules/socketmodule.c 4179@@ -274,7 +274,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\ 4180 # endif 4181 4182 /* Macros based on the IPPROTO enum, see: https://bugs.python.org/issue29515 */ 4183-#ifdef MS_WINDOWS 4184+#ifdef _MSC_VER 4185 #define IPPROTO_ICMP IPPROTO_ICMP 4186 #define IPPROTO_IGMP IPPROTO_IGMP 4187 #define IPPROTO_GGP IPPROTO_GGP 4188@@ -305,7 +305,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\ 4189 #define IPPROTO_PGM IPPROTO_PGM // WinSock2 only 4190 #define IPPROTO_L2TP IPPROTO_L2TP // WinSock2 only 4191 #define IPPROTO_SCTP IPPROTO_SCTP // WinSock2 only 4192-#endif /* MS_WINDOWS */ 4193+#endif /* _MSC_VER */ 4194 4195 /* Provides the IsWindows7SP1OrGreater() function */ 4196 #include <versionhelpers.h> 4197@@ -404,6 +404,10 @@ remove_unusable_flags(PyObject *m) 4198 /* Do not include addrinfo.h for MSVC7 or greater. 'addrinfo' and 4199 * EAI_* constants are defined in (the already included) ws2tcpip.h. 4200 */ 4201+#elif defined(__MINGW32__) 4202+ /* Do not include addrinfo.h as minimum supported version is 4203+ * _WIN32_WINNT >= WindowsXP(0x0501) 4204+ */ 4205 #else 4206 # include "addrinfo.h" 4207 #endif 4208diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h 4209index 1b35b11..cff1f1d 100644 4210--- a/Modules/socketmodule.h 4211+++ b/Modules/socketmodule.h 4212@@ -68,8 +68,10 @@ struct SOCKADDR_BTH_REDEF { 4213 */ 4214 # ifdef SIO_GET_MULTICAST_FILTER 4215 # include <mstcpip.h> /* for SIO_RCVALL */ 4216+#ifndef __MINGW32__ /* resolve by configure */ 4217 # define HAVE_ADDRINFO 4218 # define HAVE_SOCKADDR_STORAGE 4219+#endif 4220 # define HAVE_GETADDRINFO 4221 # define HAVE_GETNAMEINFO 4222 # define ENABLE_IPV6 4223diff --git a/Modules/timemodule.c b/Modules/timemodule.c 4224index 18f9ddb..4edc2e7 100644 4225--- a/Modules/timemodule.c 4226+++ b/Modules/timemodule.c 4227@@ -783,7 +783,7 @@ time_strftime(PyObject *module, PyObject *args) 4228 return NULL; 4229 } 4230 4231-#if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__) 4232+#if defined(MS_WINDOWS) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__) 4233 if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) { 4234 PyErr_SetString(PyExc_ValueError, 4235 "strftime() requires year in [1; 9999]"); 4236diff --git a/Objects/fileobject.c b/Objects/fileobject.c 4237index ffe55eb..1d73c09 100644 4238--- a/Objects/fileobject.c 4239+++ b/Objects/fileobject.c 4240@@ -3,6 +3,7 @@ 4241 #define PY_SSIZE_T_CLEAN 4242 #include "Python.h" 4243 #include "pycore_call.h" // _PyObject_CallNoArgs() 4244+#include "iscygpty.h" 4245 #include "pycore_runtime.h" // _PyRuntime 4246 4247 #if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER) 4248@@ -387,7 +388,7 @@ stdprinter_isatty(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored)) 4249 } 4250 4251 Py_BEGIN_ALLOW_THREADS 4252- res = isatty(self->fd); 4253+ res = isatty(self->fd) || is_cygpty(self->fd); 4254 Py_END_ALLOW_THREADS 4255 4256 return PyBool_FromLong(res); 4257diff --git a/PC/_testconsole.c b/PC/_testconsole.c 4258index a830883..52aca33 100644 4259--- a/PC/_testconsole.c 4260+++ b/PC/_testconsole.c 4261@@ -10,7 +10,7 @@ 4262 #ifdef MS_WINDOWS 4263 4264 #include "pycore_fileutils.h" // _Py_get_osfhandle() 4265-#include "..\modules\_io\_iomodule.h" 4266+#include "../Modules/_io/_iomodule.h" 4267 4268 #define WIN32_LEAN_AND_MEAN 4269 #include <windows.h> 4270@@ -108,7 +108,7 @@ _testconsole_read_output_impl(PyObject *module, PyObject *file) 4271 Py_RETURN_NONE; 4272 } 4273 4274-#include "clinic\_testconsole.c.h" 4275+#include "clinic/_testconsole.c.h" 4276 4277 PyMethodDef testconsole_methods[] = { 4278 _TESTCONSOLE_WRITE_INPUT_METHODDEF 4279diff --git a/PC/launcher.c b/PC/launcher.c 4280index da566a1..09ac7d9 100644 4281--- a/PC/launcher.c 4282+++ b/PC/launcher.c 4283@@ -155,12 +155,12 @@ static wchar_t * get_env(wchar_t * key) 4284 #else 4285 #if defined(_WINDOWS) 4286 4287-#define PYTHON_EXECUTABLE L"pythonw.exe" 4288+#define PYTHON_EXECUTABLE PYTHON_EXECUTABLE_WITH_VERSION 4289 #define EXECUTABLEPATH_VALUE L"WindowedExecutablePath" 4290 4291 #else 4292 4293-#define PYTHON_EXECUTABLE L"python.exe" 4294+#define PYTHON_EXECUTABLE PYTHON_EXECUTABLE_WITH_VERSION 4295 #define EXECUTABLEPATH_VALUE L"ExecutablePath" 4296 4297 #endif 4298@@ -925,7 +925,7 @@ static COMMAND path_command; 4299 static COMMAND * find_on_path(wchar_t * name) 4300 { 4301 wchar_t * pathext; 4302- size_t varsize; 4303+ size_t requiredSize; 4304 wchar_t * context = NULL; 4305 wchar_t * extension; 4306 COMMAND * result = NULL; 4307@@ -942,18 +942,23 @@ static COMMAND * find_on_path(wchar_t * name) 4308 } 4309 else { 4310 /* No extension - search using registered extensions. */ 4311- rc = _wdupenv_s(&pathext, &varsize, L"PATHEXT"); 4312- if (rc == 0) { 4313- extension = wcstok_s(pathext, L";", &context); 4314- while (extension) { 4315- len = SearchPathW(NULL, name, extension, MSGSIZE, path_command.value, NULL); 4316- if (len) { 4317- result = &path_command; 4318- break; 4319+ _wgetenv_s(&requiredSize, NULL, 0, L"PATHEXT"); 4320+ if (requiredSize > 0) { 4321+ pathext = (wchar_t *)malloc(requiredSize * sizeof(wchar_t)); 4322+ /* No extension - search using registered extensions. */ 4323+ rc = _wgetenv_s(&requiredSize, pathext, requiredSize, L"PATHEXT"); 4324+ if (rc == 0) { 4325+ extension = wcstok_s(pathext, L";", &context); 4326+ while (extension) { 4327+ len = SearchPathW(NULL, name, extension, MSGSIZE, path_command.value, NULL); 4328+ if (len) { 4329+ result = &path_command; 4330+ break; 4331+ } 4332+ extension = wcstok_s(NULL, L";", &context); 4333 } 4334- extension = wcstok_s(NULL, L";", &context); 4335+ free(pathext); 4336 } 4337- free(pathext); 4338 } 4339 } 4340 return result; 4341@@ -1913,7 +1918,7 @@ process(int argc, wchar_t ** argv) 4342 if (_wfopen_s(&f, venv_cfg_path, L"r")) { 4343 error(RC_BAD_VENV_CFG, L"Cannot read '%ls'", venv_cfg_path); 4344 } 4345- cb = fread_s(buffer, sizeof(buffer), sizeof(buffer[0]), 4346+ cb = fread(buffer, sizeof(buffer[0]), 4347 sizeof(buffer) / sizeof(buffer[0]), f); 4348 fclose(f); 4349 4350diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c 4351index 1f78d99..0f2da80 100644 4352--- a/PC/msvcrtmodule.c 4353+++ b/PC/msvcrtmodule.c 4354@@ -22,7 +22,9 @@ 4355 #include <io.h> 4356 #include <conio.h> 4357 #include <sys/locking.h> 4358+#ifdef _DEBUG 4359 #include <crtdbg.h> 4360+#endif 4361 #include <windows.h> 4362 4363 #ifdef _MSC_VER 4364diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc 4365index 1186264..84b2917 100644 4366--- a/PC/pylauncher.rc 4367+++ b/PC/pylauncher.rc 4368@@ -12,17 +12,17 @@ 4369 1 RT_MANIFEST "python.manifest" 4370 4371 #if defined(PY_ICON) 4372-1 ICON DISCARDABLE "icons\python.ico" 4373+1 ICON DISCARDABLE "icons/python.ico" 4374 #elif defined(PYW_ICON) 4375-1 ICON DISCARDABLE "icons\pythonw.ico" 4376+1 ICON DISCARDABLE "icons/pythonw.ico" 4377 #else 4378-1 ICON DISCARDABLE "icons\launcher.ico" 4379-2 ICON DISCARDABLE "icons\py.ico" 4380-3 ICON DISCARDABLE "icons\pyc.ico" 4381-4 ICON DISCARDABLE "icons\pyd.ico" 4382-5 ICON DISCARDABLE "icons\python.ico" 4383-6 ICON DISCARDABLE "icons\pythonw.ico" 4384-7 ICON DISCARDABLE "icons\setup.ico" 4385+1 ICON DISCARDABLE "icons/launcher.ico" 4386+2 ICON DISCARDABLE "icons/py.ico" 4387+3 ICON DISCARDABLE "icons/pyc.ico" 4388+4 ICON DISCARDABLE "icons/pyd.ico" 4389+5 ICON DISCARDABLE "icons/python.ico" 4390+6 ICON DISCARDABLE "icons/pythonw.ico" 4391+7 ICON DISCARDABLE "icons/setup.ico" 4392 #endif 4393 4394 1 USAGE "launcher-usage.txt" 4395@@ -64,4 +64,4 @@ BEGIN 4396 BEGIN 4397 VALUE "Translation", 0x0, 1200 4398 END 4399-END 4400\ No newline at end of file 4401+END 4402diff --git a/PC/python3dll.c b/PC/python3dll.c 4403index 50e7a96..8b524fd 100755 4404--- a/PC/python3dll.c 4405+++ b/PC/python3dll.c 4406@@ -3,6 +3,7 @@ 4407 4408 /* Generated by Tools/scripts/stable_abi.py */ 4409 4410+#ifdef _MSC_VER 4411 #ifdef _M_IX86 4412 #define DECORATE "_" 4413 #else 4414@@ -13,6 +14,13 @@ 4415 __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name)) 4416 #define EXPORT_DATA(name) \ 4417 __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name ",DATA")) 4418+#else 4419+// XXX: Why do we need the .dll extension and no DECORATE compared to the MSVC case? 4420+#define EXPORT_FUNC(name) \ 4421+ asm(".section .drectve\n\t.ascii \" -export:" #name "=\\\"" PYTHON_DLL_NAME "." #name "\\\" \""); 4422+#define EXPORT_DATA(name) \ 4423+ asm(".section .drectve\n\t.ascii \" -export:" #name "=\\\"" PYTHON_DLL_NAME "." #name "\\\",DATA \""); 4424+#endif 4425 4426 EXPORT_FUNC(_Py_BuildValue_SizeT) 4427 EXPORT_FUNC(_Py_CheckRecursiveCall) 4428diff --git a/PC/python_exe.rc b/PC/python_exe.rc 4429index c3d3bff..dde0e53 100644 4430--- a/PC/python_exe.rc 4431+++ b/PC/python_exe.rc 4432@@ -12,7 +12,7 @@ 4433 // current versions of Windows. 4434 1 RT_MANIFEST "python.manifest" 4435 4436-1 ICON DISCARDABLE "icons\python.ico" 4437+1 ICON DISCARDABLE "icons/python.ico" 4438 4439 4440 ///////////////////////////////////////////////////////////////////////////// 4441diff --git a/PC/pythonw_exe.rc b/PC/pythonw_exe.rc 4442index 38570b7..7ce1043 100644 4443--- a/PC/pythonw_exe.rc 4444+++ b/PC/pythonw_exe.rc 4445@@ -12,7 +12,7 @@ 4446 // current versions of Windows. 4447 1 RT_MANIFEST "python.manifest" 4448 4449-1 ICON DISCARDABLE "icons\pythonw.ico" 4450+1 ICON DISCARDABLE "icons/pythonw.ico" 4451 4452 4453 ///////////////////////////////////////////////////////////////////////////// 4454diff --git a/PC/winreg.c b/PC/winreg.c 4455index f668cf3..08548a7 100644 4456--- a/PC/winreg.c 4457+++ b/PC/winreg.c 4458@@ -18,6 +18,25 @@ 4459 #include "structmember.h" // PyMemberDef 4460 #include <windows.h> 4461 4462+#ifndef SIZEOF_HKEY 4463+/* used only here */ 4464+#if defined(MS_WIN64) 4465+# define SIZEOF_HKEY 8 4466+#elif defined(MS_WIN32) 4467+# define SIZEOF_HKEY 4 4468+#else 4469+# error "SIZEOF_HKEY is not defined" 4470+#endif 4471+#endif 4472+ 4473+#ifndef REG_LEGAL_CHANGE_FILTER 4474+#define REG_LEGAL_CHANGE_FILTER (\ 4475+ REG_NOTIFY_CHANGE_NAME |\ 4476+ REG_NOTIFY_CHANGE_ATTRIBUTES |\ 4477+ REG_NOTIFY_CHANGE_LAST_SET |\ 4478+ REG_NOTIFY_CHANGE_SECURITY ) 4479+#endif 4480+ 4481 static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK); 4482 static BOOL clinic_HKEY_converter(PyObject *ob, void *p); 4483 static PyObject *PyHKEY_FromHKEY(HKEY h); 4484@@ -806,6 +825,7 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) 4485 case REG_BINARY: 4486 /* ALSO handle ALL unknown data types here. Even if we can't 4487 support it natively, we should handle the bits. */ 4488+ /* fallthrough */ 4489 default: 4490 if (retDataSize == 0) { 4491 Py_INCREF(Py_None); 4492diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c 4493index e20bd53..c035b6b 100644 4494--- a/Python/bltinmodule.c 4495+++ b/Python/bltinmodule.c 4496@@ -1,6 +1,7 @@ 4497 /* Built-in functions */ 4498 4499 #include "Python.h" 4500+#include "iscygpty.h" 4501 #include <ctype.h> 4502 #include "pycore_ast.h" // _PyAST_Validate() 4503 #include "pycore_call.h" // _PyObject_CallNoArgs() 4504@@ -2135,7 +2136,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) 4505 Py_DECREF(tmp); 4506 if (fd < 0 && PyErr_Occurred()) 4507 return NULL; 4508- tty = fd == fileno(stdin) && isatty(fd); 4509+ tty = fd == fileno(stdin) && (isatty(fd) || is_cygpty(fd)); 4510 } 4511 if (tty) { 4512 tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(fileno)); 4513@@ -2148,7 +2149,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) 4514 Py_DECREF(tmp); 4515 if (fd < 0 && PyErr_Occurred()) 4516 return NULL; 4517- tty = fd == fileno(stdout) && isatty(fd); 4518+ tty = fd == fileno(stdout) && (isatty(fd) || is_cygpty(fd)); 4519 } 4520 } 4521 4522diff --git a/Python/dynamic_annotations.c b/Python/dynamic_annotations.c 4523index 7febaa0..70d5b3d 100644 4524--- a/Python/dynamic_annotations.c 4525+++ b/Python/dynamic_annotations.c 4526@@ -27,7 +27,7 @@ 4527 * Author: Kostya Serebryany 4528 */ 4529 4530-#ifdef _MSC_VER 4531+#ifdef MS_WINDOWS 4532 # include <windows.h> 4533 #endif 4534 4535diff --git a/Python/dynload_win.c b/Python/dynload_win.c 4536index 5dc4095..fcb7321 100644 4537--- a/Python/dynload_win.c 4538+++ b/Python/dynload_win.c 4539@@ -4,6 +4,7 @@ 4540 #include "Python.h" 4541 #include "pycore_fileutils.h" // _Py_add_relfile() 4542 #include "pycore_pystate.h" // _PyInterpreterState_GET() 4543+#include "pycore_initconfig.h" 4544 4545 #ifdef HAVE_DIRECT_H 4546 #include <direct.h> 4547@@ -170,8 +171,7 @@ static char *GetPythonImport (HINSTANCE hModule) 4548 Return whether the DLL was found. 4549 */ 4550 extern HMODULE PyWin_DLLhModule; 4551-static int 4552-_Py_CheckPython3(void) 4553+int _Py_CheckPython3(void) 4554 { 4555 static int python3_checked = 0; 4556 static HANDLE hPython3; 4557@@ -224,7 +224,21 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, 4558 dl_funcptr p; 4559 char funcname[258], *import_python; 4560 4561- _Py_CheckPython3(); 4562+ int use_legacy = 0; 4563+ DWORD load_library_flags = 0; 4564+ 4565+ _Py_get_env_flag(1, &use_legacy, "PYTHONLEGACYWINDOWSDLLLOADING"); 4566+ 4567+ if (use_legacy) { 4568+ load_library_flags = LOAD_WITH_ALTERED_SEARCH_PATH; 4569+ } else { 4570+ load_library_flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | 4571+ LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR; 4572+ } 4573+ 4574+#ifdef _MSC_VER 4575+ _Py_CheckPython3(); 4576+#endif 4577 4578 #if USE_UNICODE_WCHAR_CACHE 4579 const wchar_t *wpathname = _PyUnicode_AsUnicode(pathname); 4580@@ -248,9 +262,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, 4581 AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to 4582 ensure DLLs adjacent to the PYD are preferred. */ 4583 Py_BEGIN_ALLOW_THREADS 4584- hDLL = LoadLibraryExW(wpathname, NULL, 4585- LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | 4586- LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); 4587+ hDLL = LoadLibraryExW(wpathname, NULL, load_library_flags); 4588 Py_END_ALLOW_THREADS 4589 #if !USE_UNICODE_WCHAR_CACHE 4590 PyMem_Free(wpathname); 4591diff --git a/Python/fileutils.c b/Python/fileutils.c 4592index c86ed40..e459255 100644 4593--- a/Python/fileutils.c 4594+++ b/Python/fileutils.c 4595@@ -1,4 +1,5 @@ 4596 #include "Python.h" 4597+#include "iscygpty.h" 4598 #include "pycore_fileutils.h" // fileutils definitions 4599 #include "pycore_runtime.h" // _PyRuntime 4600 #include "osdefs.h" // SEP 4601@@ -71,7 +72,7 @@ _Py_device_encoding(int fd) 4602 int valid; 4603 Py_BEGIN_ALLOW_THREADS 4604 _Py_BEGIN_SUPPRESS_IPH 4605- valid = isatty(fd); 4606+ valid = isatty(fd) || is_cygpty(fd); 4607 _Py_END_SUPPRESS_IPH 4608 Py_END_ALLOW_THREADS 4609 if (!valid) 4610@@ -1809,12 +1810,12 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held) 4611 depending on heap usage). */ 4612 if (gil_held) { 4613 Py_BEGIN_ALLOW_THREADS 4614- if (isatty(fd)) { 4615+ if (isatty(fd) || is_cygpty(fd)) { 4616 count = 32767; 4617 } 4618 Py_END_ALLOW_THREADS 4619 } else { 4620- if (isatty(fd)) { 4621+ if (isatty(fd) || is_cygpty(fd)) { 4622 count = 32767; 4623 } 4624 } 4625@@ -2004,19 +2005,31 @@ int 4626 _Py_isabs(const wchar_t *path) 4627 { 4628 #ifdef MS_WINDOWS 4629+ // create a copy of path and replace all forward slashes with backslashes 4630+ // pathccskiproot does not handle forward slashes 4631+ wchar_t *path_copy = _wcsdup(path); 4632+ if (path_copy == NULL) { 4633+ return 0; 4634+ } 4635+ Py_NormalizeSepsPathcchW(path_copy); 4636+ 4637 const wchar_t *tail; 4638- HRESULT hr = PathCchSkipRoot(path, &tail); 4639- if (FAILED(hr) || path == tail) { 4640+ HRESULT hr = PathCchSkipRoot(path_copy, &tail); 4641+ if (FAILED(hr) || path_copy == tail) { 4642+ free(path_copy); 4643 return 0; 4644 } 4645- if (tail == &path[1] && (path[0] == SEP || path[0] == ALTSEP)) { 4646+ if (tail == &path_copy[1] && (path_copy[0] == SEP || path_copy[0] == ALTSEP)) { 4647 // Exclude paths with leading SEP 4648+ free(path_copy); 4649 return 0; 4650 } 4651- if (tail == &path[2] && path[1] == L':') { 4652+ if (tail == &path_copy[2] && path_copy[1] == L':') { 4653 // Exclude drive-relative paths (e.g. C:filename.ext) 4654+ free(path_copy); 4655 return 0; 4656 } 4657+ free(path_copy); 4658 return 1; 4659 #else 4660 return (path[0] == SEP); 4661@@ -2049,7 +2062,11 @@ _Py_abspath(const wchar_t *path, wchar_t **abspath_p) 4662 } 4663 4664 #ifdef MS_WINDOWS 4665- return _PyOS_getfullpathname(path, abspath_p); 4666+ if (_PyOS_getfullpathname(path, abspath_p) < 0){ 4667+ return -1; 4668+ } 4669+ *abspath_p = _Py_normpath(*abspath_p, -1); 4670+ return 0; 4671 #else 4672 wchar_t cwd[MAXPATHLEN + 1]; 4673 cwd[Py_ARRAY_LENGTH(cwd) - 1] = 0; 4674@@ -2093,6 +2110,8 @@ join_relfile(wchar_t *buffer, size_t bufsize, 4675 const wchar_t *dirname, const wchar_t *relfile) 4676 { 4677 #ifdef MS_WINDOWS 4678+ Py_NormalizeSepsPathcchW(dirname); 4679+ Py_NormalizeSepsPathcchW(relfile); 4680 if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile, 4681 PATHCCH_ALLOW_LONG_PATHS))) { 4682 return -1; 4683@@ -2195,11 +2214,16 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4684 wchar_t *minP2 = path; // the beginning of the destination range 4685 wchar_t lastC = L'\0'; // the last ljusted character, p2[-1] in most cases 4686 4687+ const wchar_t sep = Py_GetSepW(NULL); 4688+#ifdef ALTSEP 4689+ const wchar_t altsep = Py_GetAltSepW(NULL); 4690+#endif 4691+ 4692 #define IS_END(x) (pEnd ? (x) == pEnd : !*(x)) 4693 #ifdef ALTSEP 4694-#define IS_SEP(x) (*(x) == SEP || *(x) == ALTSEP) 4695+#define IS_SEP(x) (*(x) == sep || *(x) == altsep) 4696 #else 4697-#define IS_SEP(x) (*(x) == SEP) 4698+#define IS_SEP(x) (*(x) == sep) 4699 #endif 4700 #define SEP_OR_END(x) (IS_SEP(x) || IS_END(x)) 4701 4702@@ -2210,7 +2234,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4703 path++; 4704 } 4705 p1 = p2 = minP2 = path; 4706- lastC = SEP; 4707+ lastC = sep; 4708 } 4709 #ifdef MS_WINDOWS 4710 // Skip past drive segment and update minP2 4711@@ -2224,13 +2248,13 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4712 // and network paths, including the first segment. 4713 else if (IS_SEP(&p1[0]) && IS_SEP(&p1[1])) { 4714 int sepCount = 2; 4715- *p2++ = SEP; 4716- *p2++ = SEP; 4717+ *p2++ = sep; 4718+ *p2++ = sep; 4719 p1 += 2; 4720 for (; !IS_END(p1) && sepCount; ++p1) { 4721 if (IS_SEP(p1)) { 4722 --sepCount; 4723- *p2++ = lastC = SEP; 4724+ *p2++ = lastC = sep; 4725 } else { 4726 *p2++ = lastC = *p1; 4727 } 4728@@ -2243,7 +2267,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4729 *p2++ = *p1++; 4730 *p2++ = *p1++; 4731 minP2 = p2 - 1; // Absolute path has SEP at minP2 4732- lastC = SEP; 4733+ lastC = sep; 4734 } 4735 #endif /* MS_WINDOWS */ 4736 4737@@ -2251,18 +2275,18 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4738 for (; !IS_END(p1); ++p1) { 4739 wchar_t c = *p1; 4740 #ifdef ALTSEP 4741- if (c == ALTSEP) { 4742- c = SEP; 4743+ if (c == altsep) { 4744+ c = sep; 4745 } 4746 #endif 4747- if (lastC == SEP) { 4748+ if (lastC == sep) { 4749 if (c == L'.') { 4750 int sep_at_1 = SEP_OR_END(&p1[1]); 4751 int sep_at_2 = !sep_at_1 && SEP_OR_END(&p1[2]); 4752 if (sep_at_2 && p1[1] == L'.') { 4753 wchar_t *p3 = p2; 4754- while (p3 != minP2 && *--p3 == SEP) { } 4755- while (p3 != minP2 && *(p3 - 1) != SEP) { --p3; } 4756+ while (p3 != minP2 && *--p3 == sep) { } 4757+ while (p3 != minP2 && *(p3 - 1) != sep) { --p3; } 4758 if (p2 == minP2 4759 || (p3[0] == L'.' && p3[1] == L'.' && IS_SEP(&p3[2]))) 4760 { 4761@@ -2271,7 +2295,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4762 *p2++ = L'.'; 4763 *p2++ = L'.'; 4764 lastC = L'.'; 4765- } else if (p3[0] == SEP) { 4766+ } else if (p3[0] == sep) { 4767 // Absolute path, so absorb segment 4768 p2 = p3 + 1; 4769 } else { 4770@@ -2282,7 +2306,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4771 } else { 4772 *p2++ = lastC = c; 4773 } 4774- } else if (c == SEP) { 4775+ } else if (c == sep) { 4776 } else { 4777 *p2++ = lastC = c; 4778 } 4779@@ -2292,7 +2316,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) 4780 } 4781 *p2 = L'\0'; 4782 if (p2 != minP2) { 4783- while (--p2 != minP2 && *p2 == SEP) { 4784+ while (--p2 != minP2 && *p2 == sep) { 4785 *p2 = L'\0'; 4786 } 4787 } else { 4788diff --git a/Python/frozenmain.c b/Python/frozenmain.c 4789index 8743e08..c6f5f19 100644 4790--- a/Python/frozenmain.c 4791+++ b/Python/frozenmain.c 4792@@ -3,6 +3,7 @@ 4793 #include "Python.h" 4794 #include "pycore_runtime.h" // _PyRuntime_Initialize() 4795 #include <locale.h> 4796+#include "iscygpty.h" 4797 4798 #ifdef MS_WINDOWS 4799 extern void PyWinFreeze_ExeInit(void); 4800@@ -71,7 +72,7 @@ Py_FrozenMain(int argc, char **argv) 4801 sts = 0; 4802 } 4803 4804- if (inspect && isatty((int)fileno(stdin))) { 4805+ if (inspect && (isatty((int)fileno(stdin)) || is_cygpty((int)fileno(stdin)))) 4806 sts = PyRun_AnyFile(stdin, "<stdin>") != 0; 4807 } 4808 4809diff --git a/Python/getcompiler.c b/Python/getcompiler.c 4810index a5d2623..4b0b9b3 100644 4811--- a/Python/getcompiler.c 4812+++ b/Python/getcompiler.c 4813@@ -7,10 +7,40 @@ 4814 4815 // Note the __clang__ conditional has to come before the __GNUC__ one because 4816 // clang pretends to be GCC. 4817-#if defined(__clang__) 4818+#if defined(__clang__) && !defined(_WIN32) 4819 #define COMPILER "[Clang " __clang_version__ "]" 4820 #elif defined(__GNUC__) 4821-#define COMPILER "[GCC " __VERSION__ "]" 4822+/* To not break compatibility with things that determine 4823+ CPU arch by calling get_build_version in msvccompiler.py 4824+ (such as NumPy) add "32 bit" or "64 bit (AMD64)" on Windows 4825+ and also use a space as a separator rather than a newline. */ 4826+#if defined(_WIN32) 4827+#define COMP_SEP " " 4828+#if defined(__x86_64__) 4829+#define ARCH_SUFFIX " 64 bit (AMD64)" 4830+#elif defined(__aarch64__) 4831+#define ARCH_SUFFIX " 64 bit (ARM64)" 4832+#elif defined(__arm__) 4833+#define ARCH_SUFFIX " 32 bit (ARM)" 4834+#else 4835+#define ARCH_SUFFIX " 32 bit" 4836+#endif 4837+#else 4838+#define COMP_SEP "\n" 4839+#define ARCH_SUFFIX "" 4840+#endif 4841+#if defined(__clang__) 4842+#define str(x) #x 4843+#define xstr(x) str(x) 4844+#define COMPILER COMP_SEP "[GCC Clang " xstr(__clang_major__) "." \ 4845+ xstr(__clang_minor__) "." xstr(__clang_patchlevel__) ARCH_SUFFIX "]" 4846+#else 4847+#if defined(_UCRT) 4848+#define COMPILER COMP_SEP "[GCC UCRT " __VERSION__ ARCH_SUFFIX "]" 4849+#else 4850+#define COMPILER COMP_SEP "[GCC " __VERSION__ ARCH_SUFFIX "]" 4851+#endif 4852+#endif 4853 // Generic fallbacks. 4854 #elif defined(__cplusplus) 4855 #define COMPILER "[C++]" 4856diff --git a/Python/initconfig.c b/Python/initconfig.c 4857index d81cbaf..c54d238 100644 4858--- a/Python/initconfig.c 4859+++ b/Python/initconfig.c 4860@@ -176,7 +176,7 @@ static const char usage_envvars[] = 4861 "PYTHONVERBOSE : trace import statements (-v)\n" 4862 "PYTHONWARNINGS=arg : warning control (-W arg)\n"; 4863 4864-#if defined(MS_WINDOWS) 4865+#if defined(_MSC_VER) 4866 # define PYTHONHOMEHELP "<prefix>\\python{major}{minor}" 4867 #else 4868 # define PYTHONHOMEHELP "<prefix>/lib/pythonX.X" 4869diff --git a/Python/iscygpty.c b/Python/iscygpty.c 4870new file mode 100755 4871index 0000000..722f88f 4872--- /dev/null 4873+++ b/Python/iscygpty.c 4874@@ -0,0 +1,185 @@ 4875+/* 4876+ * iscygpty.c -- part of ptycheck 4877+ * https://github.com/k-takata/ptycheck 4878+ * 4879+ * Copyright (c) 2015-2017 K.Takata 4880+ * 4881+ * You can redistribute it and/or modify it under the terms of either 4882+ * the MIT license (as described below) or the Vim license. 4883+ * 4884+ * Permission is hereby granted, free of charge, to any person obtaining 4885+ * a copy of this software and associated documentation files (the 4886+ * "Software"), to deal in the Software without restriction, including 4887+ * without limitation the rights to use, copy, modify, merge, publish, 4888+ * distribute, sublicense, and/or sell copies of the Software, and to 4889+ * permit persons to whom the Software is furnished to do so, subject to 4890+ * the following conditions: 4891+ * 4892+ * The above copyright notice and this permission notice shall be 4893+ * included in all copies or substantial portions of the Software. 4894+ * 4895+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 4896+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 4897+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 4898+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 4899+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 4900+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 4901+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 4902+ */ 4903+ 4904+#ifdef _WIN32 4905+ 4906+#include <ctype.h> 4907+#include <io.h> 4908+#include <wchar.h> 4909+#include <windows.h> 4910+ 4911+#ifdef USE_FILEEXTD 4912+/* VC 7.1 or earlier doesn't support SAL. */ 4913+# if !defined(_MSC_VER) || (_MSC_VER < 1400) 4914+# define __out 4915+# define __in 4916+# define __in_opt 4917+# endif 4918+/* Win32 FileID API Library: 4919+ * http://www.microsoft.com/en-us/download/details.aspx?id=22599 4920+ * Needed for WinXP. */ 4921+# include <fileextd.h> 4922+#else /* USE_FILEEXTD */ 4923+/* VC 8 or earlier. */ 4924+# if defined(_MSC_VER) && (_MSC_VER < 1500) 4925+# ifdef ENABLE_STUB_IMPL 4926+# define STUB_IMPL 4927+# else 4928+# error "Win32 FileID API Library is required for VC2005 or earlier." 4929+# endif 4930+# endif 4931+#endif /* USE_FILEEXTD */ 4932+ 4933+ 4934+#include "iscygpty.h" 4935+ 4936+//#define USE_DYNFILEID 4937+#ifdef USE_DYNFILEID 4938+typedef BOOL (WINAPI *pfnGetFileInformationByHandleEx)( 4939+ HANDLE hFile, 4940+ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, 4941+ LPVOID lpFileInformation, 4942+ DWORD dwBufferSize 4943+); 4944+static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL; 4945+ 4946+# ifndef USE_FILEEXTD 4947+static BOOL WINAPI stub_GetFileInformationByHandleEx( 4948+ HANDLE hFile, 4949+ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, 4950+ LPVOID lpFileInformation, 4951+ DWORD dwBufferSize 4952+ ) 4953+{ 4954+ return FALSE; 4955+} 4956+# endif 4957+ 4958+static void setup_fileid_api(void) 4959+{ 4960+ if (pGetFileInformationByHandleEx != NULL) { 4961+ return; 4962+ } 4963+ pGetFileInformationByHandleEx = (pfnGetFileInformationByHandleEx) 4964+ GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), 4965+ "GetFileInformationByHandleEx"); 4966+ if (pGetFileInformationByHandleEx == NULL) { 4967+# ifdef USE_FILEEXTD 4968+ pGetFileInformationByHandleEx = GetFileInformationByHandleEx; 4969+# else 4970+ pGetFileInformationByHandleEx = stub_GetFileInformationByHandleEx; 4971+# endif 4972+ } 4973+} 4974+#else 4975+# define pGetFileInformationByHandleEx GetFileInformationByHandleEx 4976+# define setup_fileid_api() 4977+#endif 4978+ 4979+ 4980+#define is_wprefix(s, prefix) \ 4981+ (wcsncmp((s), (prefix), sizeof(prefix) / sizeof(WCHAR) - 1) == 0) 4982+ 4983+/* Check if the fd is a cygwin/msys's pty. */ 4984+int is_cygpty(int fd) 4985+{ 4986+#ifdef STUB_IMPL 4987+ return 0; 4988+#else 4989+ HANDLE h; 4990+ int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * (MAX_PATH - 1); 4991+ FILE_NAME_INFO *nameinfo; 4992+ WCHAR *p = NULL; 4993+ 4994+ setup_fileid_api(); 4995+ 4996+ h = (HANDLE) _get_osfhandle(fd); 4997+ if (h == INVALID_HANDLE_VALUE) { 4998+ return 0; 4999+ } 5000+ /* Cygwin/msys's pty is a pipe. */ 5001+ if (GetFileType(h) != FILE_TYPE_PIPE) { 5002+ return 0; 5003+ } 5004+ nameinfo = malloc(size + sizeof(WCHAR)); 5005+ if (nameinfo == NULL) { 5006+ return 0; 5007+ } 5008+ /* Check the name of the pipe: 5009+ * '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master' */ 5010+ if (pGetFileInformationByHandleEx(h, FileNameInfo, nameinfo, size)) { 5011+ nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0'; 5012+ p = nameinfo->FileName; 5013+ if (is_wprefix(p, L"\\cygwin-")) { /* Cygwin */ 5014+ p += 8; 5015+ } else if (is_wprefix(p, L"\\msys-")) { /* MSYS and MSYS2 */ 5016+ p += 6; 5017+ } else { 5018+ p = NULL; 5019+ } 5020+ if (p != NULL) { 5021+ while (*p && isxdigit(*p)) /* Skip 16-digit hexadecimal. */ 5022+ ++p; 5023+ if (is_wprefix(p, L"-pty")) { 5024+ p += 4; 5025+ } else { 5026+ p = NULL; 5027+ } 5028+ } 5029+ if (p != NULL) { 5030+ while (*p && isdigit(*p)) /* Skip pty number. */ 5031+ ++p; 5032+ if (is_wprefix(p, L"-from-master")) { 5033+ //p += 12; 5034+ } else if (is_wprefix(p, L"-to-master")) { 5035+ //p += 10; 5036+ } else { 5037+ p = NULL; 5038+ } 5039+ } 5040+ } 5041+ free(nameinfo); 5042+ return (p != NULL); 5043+#endif /* STUB_IMPL */ 5044+} 5045+ 5046+/* Check if at least one cygwin/msys pty is used. */ 5047+int is_cygpty_used(void) 5048+{ 5049+ int fd, ret = 0; 5050+ 5051+ for (fd = 0; fd < 3; fd++) { 5052+ ret |= is_cygpty(fd); 5053+ } 5054+ return ret; 5055+} 5056+ 5057+#endif /* _WIN32 */ 5058+ 5059+/* vim: set ts=4 sw=4: */ 5060diff --git a/Python/pathconfig.c b/Python/pathconfig.c 5061index be0f97c..7eb9006 100644 5062--- a/Python/pathconfig.c 5063+++ b/Python/pathconfig.c 5064@@ -2,7 +2,7 @@ 5065 5066 #include "Python.h" 5067 #include "marshal.h" // PyMarshal_ReadObjectFromString 5068-#include "osdefs.h" // DELIM 5069+#include "osdefs.h" // DELIM, SEP 5070 #include "pycore_initconfig.h" 5071 #include "pycore_fileutils.h" 5072 #include "pycore_pathconfig.h" 5073@@ -18,6 +18,158 @@ 5074 extern "C" { 5075 #endif 5076 5077+#ifdef __MINGW32__ 5078+#define wcstok wcstok_s 5079+#include <windows.h> 5080+#endif 5081+ 5082+static int 5083+Py_StartsWithA(const char * str, const char * prefix) 5084+{ 5085+ while(*prefix) 5086+ { 5087+ if(*prefix++ != *str++) 5088+ return 0; 5089+ } 5090+ 5091+ return 1; 5092+} 5093+ 5094+static int 5095+Py_StartsWithW(const wchar_t * str, const wchar_t * prefix) 5096+{ 5097+ while(*prefix) 5098+ { 5099+ if(*prefix++ != *str++) 5100+ return 0; 5101+ } 5102+ 5103+ return 1; 5104+} 5105+ 5106+char 5107+Py_GetSepA(const char *name) 5108+{ 5109+ static char sep = '\0'; 5110+#ifdef _WIN32 5111+ /* https://msdn.microsoft.com/en-gb/library/windows/desktop/aa365247%28v=vs.85%29.aspx 5112+ * The "\\?\" prefix .. indicate that the path should be passed to the system with minimal 5113+ * modification, which means that you cannot use forward slashes to represent path separators 5114+ */ 5115+ if (name != NULL && Py_StartsWithA(name, "\\\\?\\") != 0) 5116+ { 5117+ return '\\'; 5118+ } 5119+#endif 5120+ if (sep != '\0') 5121+ return sep; 5122+#if defined(__MINGW32__) 5123+ char* msystem = getenv("MSYSTEM"); 5124+ if (msystem != NULL && strcmp(msystem, "") != 0) 5125+ sep = '/'; 5126+ else 5127+ sep = '\\'; 5128+#else 5129+ sep = SEP; 5130+#endif 5131+ return sep; 5132+} 5133+ 5134+static char 5135+Py_GetAltSepA(const char *name) 5136+{ 5137+ char sep = Py_GetSepA(name); 5138+ if (sep == '/') 5139+ return '\\'; 5140+ return '/'; 5141+} 5142+ 5143+void 5144+Py_NormalizeSepsA(char *name) 5145+{ 5146+ assert(name != NULL); 5147+ char sep = Py_GetSepA(name); 5148+ char altsep = Py_GetAltSepA(name); 5149+ char* seps; 5150+ if (name[0] != '\0' && name[1] == ':') { 5151+ name[0] = toupper(name[0]); 5152+ } 5153+ seps = strchr(name, altsep); 5154+ while(seps) { 5155+ *seps = sep; 5156+ seps = strchr(seps, altsep); 5157+ } 5158+} 5159+ 5160+wchar_t 5161+Py_GetSepW(const wchar_t *name) 5162+{ 5163+ static wchar_t sep = L'\0'; 5164+#ifdef _WIN32 5165+ /* https://msdn.microsoft.com/en-gb/library/windows/desktop/aa365247%28v=vs.85%29.aspx 5166+ * The "\\?\" prefix .. indicate that the path should be passed to the system with minimal 5167+ * modification, which means that you cannot use forward slashes to represent path separators 5168+ */ 5169+ if (name != NULL && Py_StartsWithW(name, L"\\\\?\\") != 0) 5170+ { 5171+ return L'\\'; 5172+ } 5173+#endif 5174+ if (sep != L'\0') 5175+ return sep; 5176+#if defined(__MINGW32__) 5177+ char* msystem = getenv("MSYSTEM"); 5178+ if (msystem != NULL && strcmp(msystem, "") != 0) 5179+ sep = L'/'; 5180+ else 5181+ sep = L'\\'; 5182+#else 5183+ sep = SEP; 5184+#endif 5185+ return sep; 5186+} 5187+ 5188+wchar_t 5189+Py_GetAltSepW(const wchar_t *name) 5190+{ 5191+ char sep = Py_GetSepW(name); 5192+ if (sep == L'/') 5193+ return L'\\'; 5194+ return L'/'; 5195+} 5196+ 5197+void 5198+Py_NormalizeSepsW(wchar_t *name) 5199+{ 5200+ assert(name != NULL); 5201+ wchar_t sep = Py_GetSepW(name); 5202+ wchar_t altsep = Py_GetAltSepW(name); 5203+ wchar_t* seps; 5204+ if (name[0] != L'\0' && name[1] == L':') { 5205+ name[0] = towupper(name[0]); 5206+ } 5207+ seps = wcschr(name, altsep); 5208+ while(seps) { 5209+ *seps = sep; 5210+ seps = wcschr(seps, altsep); 5211+ } 5212+} 5213+ 5214+void 5215+Py_NormalizeSepsPathcchW(wchar_t *name) 5216+{ 5217+#ifdef MS_WINDOWS 5218+ assert(name != NULL); 5219+ wchar_t sep = '\\'; 5220+ wchar_t altsep = '/'; 5221+ wchar_t* seps; 5222+ seps = wcschr(name, altsep); 5223+ while(seps) { 5224+ *seps = sep; 5225+ seps = wcschr(seps, altsep); 5226+ } 5227+#endif 5228+} 5229 5230 /* External interface */ 5231 5232@@ -317,6 +469,7 @@ _Py_SetProgramFullPath(const wchar_t *program_full_path) 5233 if (has_value && _Py_path_config.program_full_path == NULL) { 5234 path_out_of_memory(__func__); 5235 } 5236+ Py_NormalizeSepsW(_Py_path_config.program_name); 5237 } 5238 5239 5240@@ -509,7 +662,7 @@ _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) 5241 } 5242 #endif /* All others */ 5243 5244- PyObject *path0_obj = PyUnicode_FromWideChar(path0, n); 5245+ PyObject *path0_obj = PyUnicode_FromWideChar(_Py_normpath(path0, -1), n); 5246 if (path0_obj == NULL) { 5247 return -1; 5248 } 5249diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c 5250index 9248e97..1d53e12 100644 5251--- a/Python/pylifecycle.c 5252+++ b/Python/pylifecycle.c 5253@@ -31,6 +31,7 @@ 5254 5255 extern void _PyIO_Fini(void); 5256 5257+#include "iscygpty.h" 5258 #include <locale.h> // setlocale() 5259 #include <stdlib.h> // getenv() 5260 5261@@ -2954,7 +2955,7 @@ Py_Exit(int sts) 5262 int 5263 Py_FdIsInteractive(FILE *fp, const char *filename) 5264 { 5265- if (isatty((int)fileno(fp))) 5266+ if (isatty((int)fileno(fp)) || is_cygpty((int)fileno(fp))) 5267 return 1; 5268 if (!Py_InteractiveFlag) 5269 return 0; 5270@@ -2967,7 +2968,7 @@ Py_FdIsInteractive(FILE *fp, const char *filename) 5271 int 5272 _Py_FdIsInteractive(FILE *fp, PyObject *filename) 5273 { 5274- if (isatty((int)fileno(fp))) { 5275+ if (isatty((int)fileno(fp)) || is_cygpty((int)fileno(fp))) { 5276 return 1; 5277 } 5278 if (!Py_InteractiveFlag) { 5279diff --git a/Python/sysmodule.c b/Python/sysmodule.c 5280index 8bab703..fed0adb 100644 5281--- a/Python/sysmodule.c 5282+++ b/Python/sysmodule.c 5283@@ -43,7 +43,7 @@ Data members: 5284 #include <windows.h> 5285 #endif /* MS_WINDOWS */ 5286 5287-#ifdef MS_COREDLL 5288+#if defined(MS_WINDOWS) && defined(Py_ENABLE_SHARED) 5289 extern void *PyWin_DLLhModule; 5290 /* A string loaded from the DLL at startup: */ 5291 extern const char *PyWin_DLLVersionString; 5292@@ -2923,7 +2923,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) 5293 SET_SYS_FROM_STRING("byteorder", "little"); 5294 #endif 5295 5296-#ifdef MS_COREDLL 5297+#if defined(MS_WINDOWS) && defined(Py_ENABLE_SHARED) 5298 SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule)); 5299 SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString); 5300 #endif 5301diff --git a/Python/thread_nt.h b/Python/thread_nt.h 5302index 084bd58..f8a6765 100644 5303--- a/Python/thread_nt.h 5304+++ b/Python/thread_nt.h 5305@@ -360,8 +360,9 @@ PyThread_release_lock(PyThread_type_lock aLock) 5306 { 5307 dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); 5308 5309- if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) 5310+ if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) { 5311 dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError())); 5312+ } 5313 } 5314 5315 /* minimum/maximum thread stack sizes supported */ 5316diff --git a/Python/traceback.c b/Python/traceback.c 5317index 7f47349..23fda62 100644 5318--- a/Python/traceback.c 5319+++ b/Python/traceback.c 5320@@ -323,7 +323,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * 5321 filepath = PyBytes_AS_STRING(filebytes); 5322 5323 /* Search tail of filename in sys.path before giving up */ 5324- tail = strrchr(filepath, SEP); 5325+ tail = strrchr(filepath, Py_GetSepA(filepath)); 5326 if (tail == NULL) 5327 tail = filepath; 5328 else 5329diff --git a/configure.ac b/configure.ac 5330index 1c25abd..5cf7085 100644 5331--- a/configure.ac 5332+++ b/configure.ac 5333@@ -202,9 +202,11 @@ AC_SUBST([FREEZE_MODULE]) 5334 AC_SUBST([FREEZE_MODULE_DEPS]) 5335 AC_SUBST([PYTHON_FOR_BUILD_DEPS]) 5336 5337+NATIVE_PYTHON_SEARCH_PATH_MINGW=`echo $host | grep -Eq 'mingw*' && echo "$MINGW_PREFIX/bin" || echo $PATH` 5338 AC_CHECK_PROGS([PYTHON_FOR_REGEN], 5339 [python$PACKAGE_VERSION python3.10 python3.9 python3.8 python3.7 python3.6 python3 python], 5340- [python3]) 5341+ [python3], 5342+ [$NATIVE_PYTHON_SEARCH_PATH_MINGW]) 5343 AC_SUBST(PYTHON_FOR_REGEN) 5344 5345 AC_MSG_CHECKING([Python for regen version]) 5346@@ -545,6 +547,9 @@ then 5347 *-*-cygwin*) 5348 ac_sys_system=Cygwin 5349 ;; 5350+ *-*-mingw*) 5351+ ac_sys_system=MINGW 5352+ ;; 5353 *-*-vxworks*) 5354 ac_sys_system=VxWorks 5355 ;; 5356@@ -580,6 +585,7 @@ then 5357 linux*) MACHDEP="linux";; 5358 cygwin*) MACHDEP="cygwin";; 5359 darwin*) MACHDEP="darwin";; 5360+ mingw*) MACHDEP="win32";; 5361 '') MACHDEP="unknown";; 5362 esac 5363 fi 5364@@ -605,6 +611,9 @@ if test "$cross_compiling" = yes; then 5365 ;; 5366 wasm32-*-* | wasm64-*-*) 5367 _host_cpu=$host_cpu 5368+ ;; 5369+ *-*-mingw*) 5370+ _host_cpu= 5371 ;; 5372 *) 5373 # for now, limit cross builds to known configurations 5374@@ -612,6 +621,14 @@ if test "$cross_compiling" = yes; then 5375 AC_MSG_ERROR([cross build not supported for $host]) 5376 esac 5377 _PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}" 5378+ 5379+ case "$host_os" in 5380+ mingw*) 5381+ # As sys.platform() return 'win32' to build python and extantions 5382+ # we will use 'mingw' (in setup.py and etc.) 5383+ _PYTHON_HOST_PLATFORM=mingw 5384+ ;; 5385+ esac 5386 fi 5387 5388 # Some systems cannot stand _XOPEN_SOURCE being defined at all; they 5389@@ -723,6 +740,65 @@ then 5390 AC_DEFINE(_INCLUDE__STDC_A1_SOURCE, 1, Define to include mbstate_t for mbrtowc) 5391 fi 5392 5393+# On 'semi-native' build systems (MSYS*/Cygwin targeting MinGW-w64) 5394+# _sysconfigdata.py will contain paths that are correct only in the 5395+# build environment. This means external modules will fail to build 5396+# without setting up the same env and also that the build of Python 5397+# itself will fail as the paths are not correct for the host tools. 5398+# 5399+# To work around these issues a set of _b2h variables are created: 5400+# prefix_b2h, srcdir_b2h, abs_srcdir_b2h 5401+# and abs_builddir_b2h 5402+# .. where b2h stands for build to host. sysconfig.py replaces path 5403+# prefixes matching the non-b2h versions with the b2h equivalents. 5404+# 5405+# (note this assumes the host compilers are native and *not* cross 5406+# - in the 'semi-native' scenario only that is.) 5407+ 5408+AC_DEFUN([ABS_PATH_HOST], 5409+[$1=$(cd $$2 && pwd) 5410+ case $build_os in 5411+ mingw*) 5412+ case $host_os in 5413+ mingw*) $1=$(cd $$2 && pwd -W) ;; 5414+ *) ;; 5415+ esac 5416+ ;; 5417+ cygwin*) 5418+ case $host_os in 5419+ mingw*) $1=$(cygpath -w -m $$2) ;; 5420+ *) ;; 5421+ esac 5422+ ;; 5423+ esac 5424+AC_SUBST([$1]) 5425+]) 5426+ 5427+AC_MSG_CHECKING(absolute host location of prefix) 5428+ABS_PATH_HOST([prefix_b2h],[prefix]) 5429+AC_MSG_RESULT([$prefix_b2h]) 5430+ 5431+AC_MSG_CHECKING(absolute host location of srcdir) 5432+ABS_PATH_HOST([srcdir_b2h],[srcdir]) 5433+AC_MSG_RESULT([$srcdir_b2h]) 5434+ 5435+AC_MSG_CHECKING(absolute host location of abs_srcdir) 5436+ABS_PATH_HOST([abs_srcdir_b2h],[srcdir]) 5437+AC_MSG_RESULT([$abs_srcdir_b2h]) 5438+ 5439+my_builddir=. 5440+AC_MSG_CHECKING(Absolute host location of abs_builddir) 5441+ABS_PATH_HOST([abs_builddir_b2h],[my_builddir]) 5442+AC_MSG_RESULT([$abs_builddir_b2h]) 5443+ 5444+AC_MSG_CHECKING([for init system calls]) 5445+AC_SUBST(INITSYS) 5446+case $host in 5447+ *-*-mingw*) INITSYS=nt;; 5448+ *) INITSYS=posix;; 5449+esac 5450+AC_MSG_RESULT([$INITSYS]) 5451+ 5452 # Record the configure-time value of MACOSX_DEPLOYMENT_TARGET, 5453 # it may influence the way we can build extensions, so distutils 5454 # needs to check it 5455@@ -1163,6 +1239,28 @@ AC_CACHE_CHECK([for -Wl,--no-as-needed], [ac_cv_wl_no_as_needed], [ 5456 ]) 5457 AC_SUBST(NO_AS_NEEDED) 5458 5459+# initialize default configuration 5460+py_config= 5461+case $host in 5462+ *-*-mingw*) py_config=mingw ;; 5463+esac 5464+if test -n "$py_config" ; then 5465+ AC_MSG_NOTICE([loading configure defaults from .../Misc/config_$py_config"]) 5466+ . "$srcdir/Misc/config_$py_config" 5467+fi 5468+ 5469+# initialize defaults for cross-builds 5470+if test "$cross_compiling" = yes; then 5471+ py_config=$host_os 5472+ case $py_config in 5473+ mingw32*) py_config=mingw32 ;; 5474+ esac 5475+ if test -f "$srcdir/Misc/cross_$py_config" ; then 5476+ AC_MSG_NOTICE([loading cross defaults from .../Misc/cross_$py_config"]) 5477+ . "$srcdir/Misc/cross_$py_config" 5478+ fi 5479+fi 5480+ 5481 AC_MSG_CHECKING([for the Android API level]) 5482 cat > conftest.c <<EOF 5483 #ifdef __ANDROID__ 5484@@ -1275,6 +1373,7 @@ AC_ARG_WITH([suffix], 5485 [Emscripten/browser*], [EXEEXT=.js], 5486 [Emscripten/node*], [EXEEXT=.js], 5487 [WASI/*], [EXEEXT=.wasm], 5488+ [MINGW*], [EXEEXT=.exe], 5489 [EXEEXT=] 5490 ) 5491 ]) 5492@@ -1298,6 +1397,10 @@ else 5493 fi 5494 rmdir CaseSensitiveTestDir 5495 5496+AS_CASE([$ac_sys_system], 5497+ [MINGW], [BUILDEXEEXT=".exe"] 5498+) 5499+ 5500 case $ac_sys_system in 5501 hp*|HP*) 5502 case $CC in 5503@@ -1475,6 +1578,11 @@ if test $enable_shared = "yes"; then 5504 LDLIBRARY='libpython$(LDVERSION).dll.a' 5505 DLLLIBRARY='libpython$(LDVERSION).dll' 5506 ;; 5507+ MINGW*) 5508+ LDLIBRARY='libpython$(LDVERSION).dll.a' 5509+ DLLLIBRARY='libpython$(LDVERSION).dll' 5510+ BLDLIBRARY='-L. -lpython$(LDVERSION)' 5511+ ;; 5512 SunOS*) 5513 LDLIBRARY='libpython$(LDVERSION).so' 5514 BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)' 5515@@ -1525,6 +1633,9 @@ else # shared is disabled 5516 BLDLIBRARY='$(LIBRARY)' 5517 LDLIBRARY='libpython$(LDVERSION).dll.a' 5518 ;; 5519+ MINGW*) 5520+ LDLIBRARY='libpython$(LDVERSION).a' 5521+ ;; 5522 esac 5523 fi 5524 5525@@ -1618,6 +1729,10 @@ AC_SUBST(LINK_PYTHON_OBJS) 5526 AC_SUBST(AR) 5527 AC_CHECK_TOOLS(AR, ar aal, ar) 5528 5529+# windres program 5530+AC_SUBST(WINDRES) 5531+AC_CHECK_TOOL(WINDRES, windres) 5532+ 5533 # tweak ARFLAGS only if the user didn't set it on the command line 5534 AC_SUBST(ARFLAGS) 5535 if test -z "$ARFLAGS" 5536@@ -2498,6 +2613,53 @@ then 5537 BASECFLAGS="$BASECFLAGS $ac_arch_flags" 5538 fi 5539 5540+dnl NOTE: 5541+dnl - GCC 4.4+ for mingw* require and use posix threads(pthreads-w32) 5542+dnl - Host may contain installed pthreads-w32. 5543+dnl - On windows platform only NT-thread model is supported. 5544+dnl To avoid miss detection scipt first will check for NT-thread model 5545+dnl and if is not found will try to detect build options for pthread 5546+dnl model. Autodetection could be overiden if variable with_nt_threads 5547+dnl is set in "Site Configuration" (see autoconf manual). 5548+dnl If NT-thread model is enabled script skips some checks that 5549+dnl impact build process. When a new functionality is added, developers 5550+dnl are responsible to update configure script to avoid thread models 5551+dnl to be mixed. 5552+ 5553+AC_MSG_CHECKING([for --with-nt-threads]) 5554+AC_ARG_WITH(nt-threads, 5555+ AS_HELP_STRING([--with-nt-threads], [build with windows threads (default is system-dependent)]), 5556+[ 5557+ case $withval in 5558+ no) with_nt_threads=no;; 5559+ yes) with_nt_threads=yes;; 5560+ *) with_nt_threads=yes;; 5561+ esac 5562+], [ 5563+ case $host in 5564+ *-*-mingw*) with_nt_threads=yes;; 5565+ *) with_nt_threads=no;; 5566+ esac 5567+]) 5568+AC_MSG_RESULT([$with_nt_threads]) 5569+ 5570+if test $with_nt_threads = yes ; then 5571+AC_MSG_CHECKING([whether linking with nt-threads work]) 5572+AC_LINK_IFELSE([ 5573+ AC_LANG_PROGRAM([[#include <process.h>]],[[_beginthread(0, 0, 0);]]) 5574+ ], 5575+ [AC_MSG_RESULT([yes])], 5576+ [AC_MSG_ERROR([failed to link with nt-threads])]) 5577+fi 5578+ 5579+if test $with_nt_threads = yes ; then 5580+ dnl temporary default flag to avoid additional pthread checks 5581+ dnl and initilize other ac..thread flags to no 5582+ ac_cv_pthread_is_default=no 5583+ ac_cv_kthread=no 5584+ ac_cv_pthread=no 5585+ dnl ac_cv_kpthread is set to no if default is yes (see below) 5586+else 5587 # On some compilers, pthreads are available without further options 5588 # (e.g. MacOS X). On some of these systems, the compiler will not 5589 # complain if unaccepted options are passed (e.g. gcc on Mac OS X). 5590@@ -2609,6 +2771,8 @@ int main(void){ 5591 CC="$ac_save_cc"]) 5592 fi 5593 5594+fi 5595+ 5596 # If we have set a CC compiler flag for thread support then 5597 # check if it works for CXX, too. 5598 ac_cv_cxx_thread=no 5599@@ -2629,6 +2793,10 @@ elif test "$ac_cv_pthread" = "yes" 5600 then 5601 CXX="$CXX -pthread" 5602 ac_cv_cxx_thread=yes 5603+elif test $with_nt_threads = yes 5604+then 5605+ dnl set to always to skip extra pthread check below 5606+ ac_cv_cxx_thread=always 5607 fi 5608 5609 if test $ac_cv_cxx_thread = yes 5610@@ -2663,11 +2831,11 @@ AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.]) 5611 5612 # checks for header files 5613 AC_CHECK_HEADERS([ \ 5614- alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ 5615+ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h endian.h errno.h fcntl.h grp.h \ 5616 ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/memfd.h \ 5617 linux/random.h linux/soundcard.h \ 5618- linux/tipc.h linux/wait.h netdb.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ 5619- sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ 5620+ linux/tipc.h linux/wait.h netdb.h netinet/in.h netpacket/packet.h poll.h process.h pty.h \ 5621+ setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ 5622 sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ 5623 sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \ 5624 sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \ 5625@@ -2675,9 +2843,24 @@ AC_CHECK_HEADERS([ \ 5626 sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \ 5627 termios.h util.h utime.h utmp.h \ 5628 ]) 5629+ 5630+case $host in 5631+ *-*-mingw*) ;; 5632+ *) AC_CHECK_HEADERS([dlfcn.h]);; 5633+esac 5634+ 5635+ 5636 AC_HEADER_DIRENT 5637 AC_HEADER_MAJOR 5638 5639+# If using nt threads, don't look for pthread.h or thread.h 5640+if test "x$with_nt_threads" = xno ; then 5641+AC_HEADER_STDC 5642+AC_CHECK_HEADERS(pthread.h sched.h thread.h) 5643+AC_HEADER_DIRENT 5644+AC_HEADER_MAJOR 5645+fi 5646+ 5647 # bluetooth/bluetooth.h has been known to not compile with -std=c99. 5648 # http://permalink.gmane.org/gmane.linux.bluez.kernel/22294 5649 SAVE_CFLAGS=$CFLAGS 5650@@ -2852,6 +3035,10 @@ dnl LFS does not work with Emscripten 3.1 5651 AS_CASE([$ac_sys_system], 5652 [Emscripten], [have_largefile_support="no"] 5653 ) 5654+dnl Activate on windows platforms (32&64-bit) where off_t(4) < fpos_t(8) 5655+AS_CASE([$ac_sys_system], 5656+ [MINGW], [have_largefile_support="yes"] 5657+) 5658 AS_VAR_IF([have_largefile_support], [yes], [ 5659 AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, 5660 [Defined to enable large file support when an off_t is bigger than a long 5661@@ -2882,6 +3069,10 @@ elif test "$ac_cv_pthread" = "yes" 5662 then CC="$CC -pthread" 5663 fi 5664 5665+if test $with_nt_threads = yes ; then 5666+ dnl skip check for pthread_t if NT-thread model is enabled 5667+ ac_cv_have_pthread_t=skip 5668+else 5669 AC_CACHE_CHECK([for pthread_t], [ac_cv_have_pthread_t], [ 5670 AC_COMPILE_IFELSE([ 5671 AC_LANG_PROGRAM([[#include <pthread.h>]], [[pthread_t x; x = *(pthread_t*)0;]]) 5672@@ -2913,7 +3104,7 @@ AS_VAR_IF([ac_cv_pthread_key_t_is_arithmetic_type], [yes], [ 5673 AC_DEFINE(PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT, 1, 5674 [Define if pthread_key_t is compatible with int.]) 5675 ]) 5676- 5677+fi 5678 CC="$ac_save_cc" 5679 5680 AC_SUBST(OTHER_LIBTOOL_OPT) 5681@@ -3089,6 +3280,9 @@ if test -z "$SHLIB_SUFFIX"; then 5682 CYGWIN*) SHLIB_SUFFIX=.dll;; 5683 *) SHLIB_SUFFIX=.so;; 5684 esac 5685+ case $host_os in 5686+ mingw*) SHLIB_SUFFIX=.pyd;; 5687+ esac 5688 fi 5689 AC_MSG_RESULT($SHLIB_SUFFIX) 5690 5691@@ -3218,6 +3412,10 @@ then 5692 CYGWIN*) 5693 LDSHARED="gcc -shared -Wl,--enable-auto-image-base" 5694 LDCXXSHARED="g++ -shared -Wl,--enable-auto-image-base";; 5695+ MINGW*) 5696+ LDSHARED='$(CC) -shared -Wl,--enable-auto-image-base' 5697+ LDCXXSHARED='$(CXX) -shared -Wl,--enable-auto-image-base' 5698+ ;; 5699 *) LDSHARED="ld";; 5700 esac 5701 fi 5702@@ -3341,6 +3539,11 @@ then 5703 VxWorks*) 5704 LINKFORSHARED='-Wl,-export-dynamic';; 5705 esac 5706+ case $host in 5707+ *-*-mingw*) 5708+ # for https://bugs.python.org/issue40458 on MINGW 5709+ LINKFORSHARED="-Wl,--stack,2000000";; 5710+ esac 5711 fi 5712 AC_MSG_RESULT($LINKFORSHARED) 5713 5714@@ -3385,7 +3588,12 @@ AC_MSG_RESULT($SHLIBS) 5715 5716 # checks for libraries 5717 AC_CHECK_LIB(sendfile, sendfile) 5718-AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV 5719+ 5720+case $host in 5721+ *-*-mingw*) ;; 5722+ *) AC_CHECK_LIB(dl, dlopen) ;; # Dynamic linking for SunOS/Solaris and SYSV 5723+esac 5724+ 5725 AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX 5726 5727 5728@@ -3448,16 +3656,30 @@ AS_VAR_IF([have_uuid], [missing], [ 5729 5730 AS_VAR_IF([have_uuid], [missing], [have_uuid=no]) 5731 5732+if test $with_nt_threads = yes ; then 5733+ dnl do not search for sem_init if NT-thread model is enabled 5734+ : 5735+else 5736 # 'Real Time' functions on Solaris 5737 # posix4 on Solaris 2.6 5738 # pthread (first!) on Linux 5739 AC_SEARCH_LIBS(sem_init, pthread rt posix4) 5740+fi 5741 5742 # check if we need libintl for locale functions 5743+case $host in 5744+ *-*-mingw*) 5745+ dnl Native windows build don't use libintl (see _localemodule.c). 5746+ dnl Also we don't like setup.py to add "intl" library to the list 5747+ dnl when build _locale module. 5748+ ;; 5749+ *) 5750 AC_CHECK_LIB(intl, textdomain, 5751 [AC_DEFINE(WITH_LIBINTL, 1, 5752 [Define to 1 if libintl is needed for locale functions.]) 5753 LIBS="-lintl $LIBS"]) 5754+ ;; 5755+esac 5756 5757 # checks for system dependent C++ extensions support 5758 case "$ac_sys_system" in 5759@@ -3645,7 +3867,7 @@ else 5760 fi 5761 5762 if test "$with_system_ffi" = "yes" && test -n "$PKG_CONFIG"; then 5763- LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ *$//'`" 5764+ LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ .*$//'`" 5765 else 5766 LIBFFI_INCLUDEDIR="" 5767 fi 5768@@ -3780,6 +4002,12 @@ AS_CASE([$ac_sys_system], 5769 [OSSAUDIODEV_LIBS=""] 5770 ) 5771 5772+dnl On MINGW, you need to link against ws2_32 and iphlpapi for sockets to work 5773+AS_CASE([$ac_sys_system], 5774+ [MINGW], [SOCKET_LIBS="-lws2_32 -liphlpapi"], 5775+ [SOCKET_LIBS=""] 5776+) 5777+ 5778 dnl detect sqlite3 from Emscripten emport 5779 PY_CHECK_EMSCRIPTEN_PORT([LIBSQLITE3], [-sUSE_SQLITE3]) 5780 5781@@ -4042,6 +4270,18 @@ AS_VAR_IF([with_dbmliborder], [error], [ 5782 ]) 5783 AC_MSG_RESULT($with_dbmliborder) 5784 5785+case $host in 5786+ *-*-mingw*) 5787+ CFLAGS_NODIST="$CFLAGS_NODIST -D_WIN32_WINNT=0x0602";; 5788+esac 5789+ 5790+# Determine if windows modules should be used. 5791+AC_SUBST(USE_WIN32_MODULE) 5792+USE_WIN32_MODULE='#' 5793+case $host in 5794+ *-*-mingw*) USE_WIN32_MODULE=;; 5795+esac 5796+ 5797 # Templates for things AC_DEFINEd more than once. 5798 # For a single AC_DEFINE, no template is needed. 5799 AH_TEMPLATE(_REENTRANT, 5800@@ -4076,6 +4316,11 @@ then 5801 CXX="$CXX -pthread" 5802 fi 5803 posix_threads=yes 5804+elif test $with_nt_threads = yes 5805+then 5806+ posix_threads=no 5807+ AC_DEFINE(NT_THREADS, 1, 5808+ [Define to 1 if you want to use native NT threads]) 5809 else 5810 if test ! -z "$withval" -a -d "$withval" 5811 then LDFLAGS="$LDFLAGS -L$withval" 5812@@ -4450,11 +4695,14 @@ AC_MSG_RESULT($with_freelists) 5813 AC_MSG_CHECKING(for --with-c-locale-coercion) 5814 AC_ARG_WITH(c-locale-coercion, 5815 AS_HELP_STRING([--with-c-locale-coercion], 5816- [enable C locale coercion to a UTF-8 based locale (default is yes)])) 5817+ [enable C locale coercion to a UTF-8 based locale (default is yes on Unix, no on Windows)])) 5818 5819 if test -z "$with_c_locale_coercion" 5820 then 5821- with_c_locale_coercion="yes" 5822+ case $host in 5823+ *-*-mingw*) with_c_locale_coercion="no";; 5824+ *) with_c_locale_coercion="yes";; 5825+ esac 5826 fi 5827 if test "$with_c_locale_coercion" != "no" 5828 then 5829@@ -4555,12 +4803,36 @@ then 5830 fi 5831 ;; 5832 esac 5833+ case $host in 5834+ *-*-mingw*) 5835+ DYNLOADFILE="dynload_win.o" 5836+ extra_machdep_objs="$extra_machdep_objs PC/dl_nt.o" 5837+ CFLAGS_NODIST="$CFLAGS_NODIST -DPY3_DLLNAME='L\"$DLLLIBRARY\"'" 5838+ case $host in 5839+ i686*) 5840+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-32\"'" 5841+ ;; 5842+ armv7*) 5843+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-arm32\"'" 5844+ ;; 5845+ aarch64*) 5846+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-arm64\"'" 5847+ ;; 5848+ *) 5849+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"$VERSION\"'" 5850+ ;; 5851+ esac 5852+ ;; 5853+ esac 5854 fi 5855 AC_MSG_RESULT($DYNLOADFILE) 5856 if test "$DYNLOADFILE" != "dynload_stub.o" 5857 then 5858+ have_dynamic_loading=yes 5859 AC_DEFINE(HAVE_DYNAMIC_LOADING, 1, 5860 [Defined when any dynamic module loading is enabled.]) 5861+else 5862+ have_dynamic_loading=no 5863 fi 5864 5865 # MACHDEP_OBJS can be set to platform-specific object files needed by Python 5866@@ -4580,13 +4852,22 @@ else 5867 fi 5868 5869 # checks for library functions 5870+if test $with_nt_threads = yes ; then 5871+ dnl GCC(mingw) 4.4+ require and use posix threads(pthreads-w32) 5872+ dnl and host may contain installed pthreads-w32. 5873+ dnl Skip checks for some functions declared in pthreads-w32 if 5874+ dnl NT-thread model is enabled. 5875+ ac_cv_func_pthread_kill=skip 5876+ ac_cv_func_sem_open=skip 5877+ ac_cv_func_sched_setscheduler=skip 5878+fi 5879 AC_CHECK_FUNCS([ \ 5880 accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \ 5881 copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \ 5882 faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ 5883 fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ 5884 gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \ 5885- getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \ 5886+ getgrnam_r getgrouplist getgroups getitimer getloadavg getlogin \ 5887 getpeername getpgid getpid getppid getpriority _getpty \ 5888 getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ 5889 getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \ 5890@@ -4599,7 +4880,7 @@ AC_CHECK_FUNCS([ \ 5891 sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ 5892 sem_timedwait sem_unlink sendfile setegid seteuid setgid sethostname \ 5893 setitimer setlocale setpgid setpgrp setpriority setregid setresgid \ 5894- setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \ 5895+ setresuid setreuid setsid setuid setvbuf sigaction sigaltstack \ 5896 sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \ 5897 sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ 5898 sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ 5899@@ -4829,7 +5110,13 @@ PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [ 5900 ]) 5901 5902 dnl PY_CHECK_NETDB_FUNC(FUNCTION) 5903-AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [#include <netdb.h>])]) 5904+AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [ 5905+#ifdef _WIN32 5906+ #include <winsock.h> 5907+#else 5908+ #include <netdb.h> 5909+#endif 5910+])]) 5911 5912 PY_CHECK_NETDB_FUNC([hstrerror]) 5913 dnl not available in WASI yet 5914@@ -4838,13 +5125,19 @@ PY_CHECK_NETDB_FUNC([getservbyport]) 5915 PY_CHECK_NETDB_FUNC([gethostbyname]) 5916 PY_CHECK_NETDB_FUNC([gethostbyaddr]) 5917 PY_CHECK_NETDB_FUNC([getprotobyname]) 5918+PY_CHECK_NETDB_FUNC([gethostname]) 5919+PY_CHECK_NETDB_FUNC([shutdown]) 5920 5921 dnl PY_CHECK_SOCKET_FUNC(FUNCTION) 5922 AC_DEFUN([PY_CHECK_SOCKET_FUNC], [PY_CHECK_FUNC([$1], [ 5923+#ifdef _WIN32 5924+#include <ws2tcpip.h> 5925+#else 5926 #include <sys/types.h> 5927 #include <sys/socket.h> 5928 #include <netinet/in.h> 5929 #include <arpa/inet.h> 5930+#endif 5931 ])]) 5932 5933 PY_CHECK_SOCKET_FUNC([inet_aton]) 5934@@ -4945,6 +5238,9 @@ WITH_SAVE_ENV([ 5935 ]) 5936 ]) 5937 5938+case $host in 5939+ *-*-mingw*) ;; 5940+ *) 5941 AC_CHECK_FUNCS(clock_gettime, [], [ 5942 AC_CHECK_LIB(rt, clock_gettime, [ 5943 LIBS="$LIBS -lrt" 5944@@ -4965,6 +5261,8 @@ AC_CHECK_FUNCS(clock_settime, [], [ 5945 AC_DEFINE(HAVE_CLOCK_SETTIME, 1) 5946 ]) 5947 ]) 5948+ ;; 5949+esac 5950 5951 AC_CHECK_FUNCS(clock_nanosleep, [], [ 5952 AC_CHECK_LIB(rt, clock_nanosleep, [ 5953@@ -5163,18 +5461,33 @@ if test $ac_cv_header_time_altzone = yes; then 5954 AC_DEFINE(HAVE_ALTZONE, 1, [Define this if your time.h defines altzone.]) 5955 fi 5956 5957+AC_CHECK_HEADERS([ws2tcpip.h]) 5958 AC_CACHE_CHECK([for addrinfo], [ac_cv_struct_addrinfo], 5959-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <netdb.h>]], [[struct addrinfo a]])], 5960+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 5961+#ifdef HAVE_WS2TCPIP_H 5962+# include <ws2tcpip.h> 5963+#else 5964+# include <netdb.h> 5965+#endif]], 5966+ [[struct addrinfo a]])], 5967 [ac_cv_struct_addrinfo=yes], 5968 [ac_cv_struct_addrinfo=no])) 5969 if test $ac_cv_struct_addrinfo = yes; then 5970- AC_DEFINE(HAVE_ADDRINFO, 1, [struct addrinfo (netdb.h)]) 5971+ AC_DEFINE(HAVE_ADDRINFO, 1, [struct addrinfo]) 5972 fi 5973 5974 AC_CACHE_CHECK([for sockaddr_storage], [ac_cv_struct_sockaddr_storage], 5975 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 5976-# include <sys/types.h> 5977-# include <sys/socket.h>]], [[struct sockaddr_storage s]])], 5978+#ifdef HAVE_WS2TCPIP_H 5979+#include <ws2tcpip.h> 5980+#endif 5981+#ifdef HAVE_SYS_TYPES_H 5982+#include <sys/types.h> 5983+#endif 5984+#ifdef HAVE_SYS_SOCKET_H 5985+#include <sys/socket.h> 5986+#endif]], 5987+ [[struct sockaddr_storage s]])], 5988 [ac_cv_struct_sockaddr_storage=yes], 5989 [ac_cv_struct_sockaddr_storage=no])) 5990 if test $ac_cv_struct_sockaddr_storage = yes; then 5991@@ -5508,6 +5821,10 @@ dnl actually works. For FreeBSD versions <= 7.2, 5992 dnl the kernel module that provides POSIX semaphores 5993 dnl isn't loaded by default, so an attempt to call 5994 dnl sem_open results in a 'Signal 12' error. 5995+if test $with_nt_threads = yes ; then 5996+ dnl skip posix semaphores test if NT-thread model is enabled 5997+ ac_cv_posix_semaphores_enabled=no 5998+fi 5999 AC_CACHE_CHECK([whether POSIX semaphores are enabled], [ac_cv_posix_semaphores_enabled], 6000 AC_RUN_IFELSE([ 6001 AC_LANG_SOURCE([ 6002@@ -5541,6 +5858,14 @@ AS_VAR_IF([ac_cv_posix_semaphores_enabled], [no], [ 6003 ]) 6004 6005 dnl Multiprocessing check for broken sem_getvalue 6006+if test $with_nt_threads = yes ; then 6007+ dnl Skip test if NT-thread model is enabled. 6008+ dnl NOTE the test case below fail for pthreads-w32 as: 6009+ dnl - SEM_FAILED is not defined; 6010+ dnl - sem_open is a stub; 6011+ dnl - sem_getvalue work(!). 6012+ ac_cv_broken_sem_getvalue=skip 6013+fi 6014 AC_CACHE_CHECK([for broken sem_getvalue], [ac_cv_broken_sem_getvalue], 6015 AC_RUN_IFELSE([ 6016 AC_LANG_SOURCE([ 6017@@ -5577,7 +5902,10 @@ AS_VAR_IF([ac_cv_broken_sem_getvalue], [yes], [ 6018 ) 6019 ]) 6020 6021-AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include <dlfcn.h>]]) 6022+case $host in 6023+ *-*-mingw*) ;; 6024+ *) AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include <dlfcn.h>]]);; 6025+esac 6026 6027 # determine what size digit to use for Python's longs 6028 AC_MSG_CHECKING([digit size for Python's longs]) 6029@@ -5664,6 +5992,71 @@ esac 6030 # check for endianness 6031 AC_C_BIGENDIAN 6032 6033+AC_SUBST(PYD_PLATFORM_TAG) 6034+# Special case of PYD_PLATFORM_TAG with python build with mingw. 6035+# Python can with compiled with clang or gcc and linked 6036+# to msvcrt or ucrt. To avoid conflicts between them 6037+# we are selecting the extension as based on the compiler 6038+# and the runtime they link to 6039+# gcc + x86_64 + msvcrt = cp{version number}-x86_64 6040+# gcc + i686 + msvcrt = cp{version number}-i686 6041+# gcc + x86_64 + ucrt = cp{version number}-x86_64-ucrt 6042+# clang + x86_64 + ucrt = cp{version number}-x86_64-clang 6043+# clang + i686 + ucrt = cp{version number}-i686-clang 6044+ 6045+PYD_PLATFORM_TAG="" 6046+case $host in 6047+ *-*-mingw*) 6048+ # check if we are linking to ucrt 6049+ AC_MSG_CHECKING(whether linking to ucrt) 6050+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ 6051+ #include <stdio.h> 6052+ #ifndef _UCRT 6053+ #error no ucrt 6054+ #endif 6055+ int main(){ return 0; } 6056+ ]])],[linking_to_ucrt=yes],[linking_to_ucrt=no]) 6057+ AC_MSG_RESULT($linking_to_ucrt) 6058+ ;; 6059+esac 6060+case $host_os in 6061+ mingw*) 6062+ AC_MSG_CHECKING(PYD_PLATFORM_TAG) 6063+ case $host in 6064+ i686-*-mingw*) 6065+ if test -n "${cc_is_clang}"; then 6066+ # it is CLANG32 6067+ PYD_PLATFORM_TAG="mingw_i686_clang" 6068+ else 6069+ if test $linking_to_ucrt = no; then 6070+ PYD_PLATFORM_TAG="mingw_i686" 6071+ else 6072+ PYD_PLATFORM_TAG="mingw_i686_ucrt" 6073+ fi 6074+ fi 6075+ ;; 6076+ x86_64-*-mingw*) 6077+ if test -n "${cc_is_clang}"; then 6078+ # it is CLANG64 6079+ PYD_PLATFORM_TAG="mingw_x86_64_clang" 6080+ else 6081+ if test $linking_to_ucrt = no; then 6082+ PYD_PLATFORM_TAG="mingw_x86_64" 6083+ else 6084+ PYD_PLATFORM_TAG="mingw_x86_64_ucrt" 6085+ fi 6086+ fi 6087+ ;; 6088+ aarch64-*-mingw*) 6089+ PYD_PLATFORM_TAG+="mingw_aarch64" 6090+ ;; 6091+ armv7-*-mingw*) 6092+ PYD_PLATFORM_TAG+="mingw_armv7" 6093+ ;; 6094+ esac 6095+ AC_MSG_RESULT($PYD_PLATFORM_TAG) 6096+esac 6097+ 6098 # ABI version string for Python extension modules. This appears between the 6099 # periods in shared library file names, e.g. foo.<SOABI>.so. It is calculated 6100 # from the following attributes which affect the ABI of this Python build (in 6101@@ -5696,7 +6089,12 @@ if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then 6102 fi 6103 6104 AC_SUBST(EXT_SUFFIX) 6105-EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} 6106+VERSION_NO_DOTS=$(echo $LDVERSION | tr -d .) 6107+if test -n "${PYD_PLATFORM_TAG}"; then 6108+ EXT_SUFFIX=".cp${VERSION_NO_DOTS}-${PYD_PLATFORM_TAG}${SHLIB_SUFFIX}" 6109+else 6110+ EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} 6111+fi 6112 6113 AC_MSG_CHECKING(LDVERSION) 6114 LDVERSION='$(VERSION)$(ABIFLAGS)' 6115@@ -5704,7 +6102,7 @@ AC_MSG_RESULT($LDVERSION) 6116 6117 # On Android and Cygwin the shared libraries must be linked with libpython. 6118 AC_SUBST(LIBPYTHON) 6119-if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin"; then 6120+if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin" -o "$MACHDEP" = "win32"; then 6121 LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" 6122 else 6123 LIBPYTHON='' 6124@@ -6073,11 +6471,16 @@ then 6125 [Define if you have struct stat.st_mtimensec]) 6126 fi 6127 6128+if test -n "$PKG_CONFIG"; then 6129+ NCURSESW_INCLUDEDIR="`"$PKG_CONFIG" ncursesw --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ .*$//'`" 6130+else 6131+ NCURSESW_INCLUDEDIR="" 6132+fi 6133+AC_SUBST(NCURSESW_INCLUDEDIR) 6134+ 6135 # first curses header check 6136 ac_save_cppflags="$CPPFLAGS" 6137-if test "$cross_compiling" = no; then 6138- CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" 6139-fi 6140+CPPFLAGS="$CPPFLAGS -I$NCURSESW_INCLUDEDIR" 6141 6142 AC_CHECK_HEADERS(curses.h ncurses.h) 6143 6144@@ -6243,7 +6646,10 @@ fi 6145 6146 AC_CHECK_TYPE(socklen_t,, 6147 AC_DEFINE(socklen_t,int, 6148- [Define to `int' if <sys/socket.h> does not define.]),[ 6149+ [Define to `int' if <sys/socket.h> or <ws2tcpip.h> does not define.]),[ 6150+#ifdef HAVE_WS2TCPIP_H 6151+#include <ws2tcpip.h> 6152+#endif 6153 #ifdef HAVE_SYS_TYPES_H 6154 #include <sys/types.h> 6155 #endif 6156@@ -6333,6 +6739,27 @@ do 6157 THREADHEADERS="$THREADHEADERS \$(srcdir)/$h" 6158 done 6159 6160+case $host in 6161+ *-*-mingw*) 6162+ dnl Required for windows builds as Objects/exceptions.c require 6163+ dnl "errmap.h" from $srcdir/PC. 6164+ dnl Note we cannot use BASECPPFLAGS as autogenerated pyconfig.h 6165+ dnl has to be before customized located in ../PC. 6166+ dnl (-I. at end is workaround for setup.py logic) 6167+ CPPFLAGS="-I\$(srcdir)/PC $CPPFLAGS -I." 6168+ ;; 6169+esac 6170+ 6171+dnl Python interpreter main program for frozen scripts 6172+AC_SUBST(PYTHON_OBJS_FROZENMAIN) 6173+PYTHON_OBJS_FROZENMAIN="Python/frozenmain.o" 6174+case $host in 6175+ *-*-mingw*) 6176+ dnl 'PC/frozen_dllmain.c' - not yet 6177+ PYTHON_OBJS_FROZENMAIN= 6178+ ;; 6179+esac 6180+ 6181 AC_SUBST(SRCDIRS) 6182 SRCDIRS="\ 6183 Modules \ 6184@@ -6354,6 +6781,10 @@ SRCDIRS="\ 6185 Python \ 6186 Python/frozen_modules \ 6187 Python/deepfreeze" 6188+case $host in 6189+ *-*-mingw*) SRCDIRS="$SRCDIRS PC";; 6190+esac 6191+ 6192 AC_MSG_CHECKING(for build directories) 6193 for dir in $SRCDIRS; do 6194 if test ! -d $dir; then 6195@@ -6362,6 +6793,38 @@ for dir in $SRCDIRS; do 6196 done 6197 AC_MSG_RESULT(done) 6198 6199+# For mingw build need additional library for linking 6200+case $host in 6201+ *-*-mingw*) 6202+ LIBS="$LIBS -lversion -lshlwapi -lpathcch -lbcrypt" 6203+ AC_PROG_AWK 6204+ if test "$AWK" = "gawk"; then 6205+ awk_extra_flag="--non-decimal-data" 6206+ fi 6207+ AC_MSG_CHECKING([FIELD3]) 6208+ FIELD3=$($AWK $awk_extra_flag '\ 6209+ /^#define PY_RELEASE_LEVEL_/ {levels[$2]=$3} \ 6210+ /^#define PY_MICRO_VERSION[[:space:]]+/ {micro=$3} \ 6211+ /^#define PY_RELEASE_LEVEL[[:space:]]+/ {level=levels[$3]} \ 6212+ /^#define PY_RELEASE_SERIAL[[:space:]]+/ {serial=$3} \ 6213+ END {print micro * 1000 + level * 10 + serial}' \ 6214+ $srcdir/Include/patchlevel.h 6215+ ) 6216+ 6217+ AC_MSG_RESULT([${FIELD3}]) 6218+ RCFLAGS="$RCFLAGS -DFIELD3=$FIELD3 -O COFF" 6219+ 6220+ case $host in 6221+ i686*) RCFLAGS="$RCFLAGS --target=pe-i386" ;; 6222+ x86_64*) RCFLAGS="$RCFLAGS --target=pe-x86-64" ;; 6223+ *) ;; 6224+ esac 6225+ ;; 6226+ *) 6227+ ;; 6228+esac 6229+AC_SUBST(RCFLAGS) 6230+ 6231 # Availability of -O2: 6232 AC_CACHE_CHECK([for -O2], [ac_cv_compile_o2], [ 6233 saved_cflags="$CFLAGS" 6234@@ -6971,7 +7434,6 @@ PY_STDLIB_MOD_SIMPLE([_json]) 6235 PY_STDLIB_MOD_SIMPLE([_lsprof]) 6236 PY_STDLIB_MOD_SIMPLE([_opcode]) 6237 PY_STDLIB_MOD_SIMPLE([_pickle]) 6238-PY_STDLIB_MOD_SIMPLE([_posixsubprocess]) 6239 PY_STDLIB_MOD_SIMPLE([_queue]) 6240 PY_STDLIB_MOD_SIMPLE([_random]) 6241 PY_STDLIB_MOD_SIMPLE([select]) 6242@@ -6982,7 +7444,7 @@ PY_STDLIB_MOD_SIMPLE([_zoneinfo]) 6243 6244 dnl multiprocessing modules 6245 PY_STDLIB_MOD([_multiprocessing], 6246- [], [test "$ac_cv_func_sem_unlink" = "yes"], 6247+ [], [test "$ac_cv_func_sem_unlink" = "yes" -o "$MACHDEP" = "win32"], 6248 [-I\$(srcdir)/Modules/_multiprocessing]) 6249 PY_STDLIB_MOD([_posixshmem], 6250 [], [test "$have_posix_shmem" = "yes"], 6251@@ -7002,11 +7464,15 @@ PY_STDLIB_MOD([fcntl], 6252 [], [test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes"], 6253 [], [$FCNTL_LIBS]) 6254 PY_STDLIB_MOD([mmap], 6255- [], [test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes"]) 6256+ [], m4_flatten([test "$ac_cv_header_sys_mman_h" = "yes" 6257+ -a "$ac_cv_header_sys_stat_h" = "yes" 6258+ -o "$MACHDEP" = "win32"])) 6259 PY_STDLIB_MOD([_socket], 6260 [], m4_flatten([test "$ac_cv_header_sys_socket_h" = "yes" 6261 -a "$ac_cv_header_sys_types_h" = "yes" 6262- -a "$ac_cv_header_netinet_in_h" = "yes"])) 6263+ -a "$ac_cv_header_netinet_in_h" = "yes" 6264+ -o "$MACHDEP" = "win32"]), 6265+ [], [$SOCKET_LIBS]) 6266 6267 dnl platform specific extensions 6268 PY_STDLIB_MOD([grp], [], [test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes]) 6269@@ -7021,6 +7487,7 @@ PY_STDLIB_MOD([_scproxy], 6270 PY_STDLIB_MOD([spwd], [], [test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes]) 6271 PY_STDLIB_MOD([syslog], [], [test "$ac_cv_header_syslog_h" = yes]) 6272 PY_STDLIB_MOD([termios], [], [test "$ac_cv_header_termios_h" = yes]) 6273+PY_STDLIB_MOD([_posixsubprocess], [], [test "$MACHDEP" != "win32"]) 6274 6275 dnl _elementtree loads libexpat via CAPI hook in pyexpat 6276 PY_STDLIB_MOD([pyexpat], [], [], [$LIBEXPAT_CFLAGS], [$LIBEXPAT_LDFLAGS]) 6277@@ -7083,25 +7550,35 @@ PY_STDLIB_MOD([_lzma], [], [test "$have_liblzma" = yes], 6278 6279 dnl OpenSSL bindings 6280 PY_STDLIB_MOD([_ssl], [], [test "$ac_cv_working_openssl_ssl" = yes], 6281- [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS]) 6282+ [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS -lws2_32]) 6283 PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes], 6284 [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) 6285 6286+dnl windows specific modules 6287+PY_STDLIB_MOD([msvcrt], [test "$MACHDEP" = "win32"]) 6288+PY_STDLIB_MOD([_winapi], [test "$MACHDEP" = "win32"]) 6289+PY_STDLIB_MOD([_msi], [test "$MACHDEP" = "win32"], [], [], 6290+ [-lmsi -lcabinet -lrpcrt4]) 6291+PY_STDLIB_MOD([winsound], [test "$MACHDEP" = "win32"], [], [], 6292+ [-lwinmm]) 6293+PY_STDLIB_MOD([_overlapped], [test "$MACHDEP" = "win32"], [], [], 6294+ [-lws2_32]) 6295+ 6296 dnl test modules 6297 PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes]) 6298 PY_STDLIB_MOD([_testclinic], [test "$TEST_MODULES" = yes]) 6299-PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes]) 6300+PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes], [], [-DPY3_DLLNAME="\"$DLLLIBRARY\""], []) 6301 PY_STDLIB_MOD([_testbuffer], [test "$TEST_MODULES" = yes]) 6302-PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) 6303-PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) 6304+PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes]) 6305+PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes]) 6306 PY_STDLIB_MOD([_xxtestfuzz], [test "$TEST_MODULES" = yes]) 6307-PY_STDLIB_MOD([_ctypes_test], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes], [], [-lm]) 6308+PY_STDLIB_MOD([_ctypes_test], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes], [], [-lm]) 6309 6310 dnl Limited API template modules. 6311 dnl The limited C API is not compatible with the Py_TRACE_REFS macro. 6312 dnl Emscripten does not support shared libraries yet. 6313-PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) 6314-PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) 6315+PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$have_dynamic_loading" = yes]) 6316+PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$have_dynamic_loading" = yes]) 6317 6318 # substitute multiline block, must come after last PY_STDLIB_MOD() 6319 AC_SUBST([MODULE_BLOCK]) 6320diff --git a/mingw_ignorefile.txt b/mingw_ignorefile.txt 6321new file mode 100755 6322index 0000000..54093f1 6323--- /dev/null 6324+++ b/mingw_ignorefile.txt 6325@@ -0,0 +1,42 @@ 6326+ctypes.test.test_loading.LoaderTest.test_load_dll_with_flags 6327+distutils.tests.test_bdist_dumb.BuildDumbTestCase.test_simple_built 6328+distutils.tests.test_cygwinccompiler.CygwinCCompilerTestCase.test_get_versions 6329+distutils.tests.test_util.UtilTestCase.test_change_root 6330+test.datetimetester.TestLocalTimeDisambiguation_Fast.* 6331+test.datetimetester.TestLocalTimeDisambiguation_Pure.* 6332+test.test_cmath.CMathTests.test_specific_values 6333+test.test_cmd_line_script.CmdLineTest.test_consistent_sys_path_for_direct_execution 6334+test.test_compileall.CommandLineTestsNoSourceEpoch.* 6335+test.test_compileall.CommandLineTestsWithSourceEpoch.* 6336+test.test_compileall.CompileallTestsWithoutSourceEpoch.* 6337+test.test_compileall.CompileallTestsWithSourceEpoch.* 6338+test.test_import.ImportTests.test_dll_dependency_import 6339+test.test_math.MathTests.* 6340+test.test_ntpath.NtCommonTest.test_import 6341+test.test_os.StatAttributeTests.test_stat_block_device 6342+test.test_os.TestScandir.test_attributes 6343+test.test_os.UtimeTests.test_large_time 6344+test.test_platform.PlatformTest.test_architecture_via_symlink 6345+test.test_regrtest.ProgramsTestCase.test_pcbuild_rt 6346+test.test_regrtest.ProgramsTestCase.test_tools_buildbot_test 6347+test.test_site._pthFileTests.* 6348+test.test_site.HelperFunctionsTests.* 6349+test.test_site.StartupImportTests.* 6350+test.test_ssl.* 6351+test.test_strptime.CalculationTests.* 6352+test.test_strptime.StrptimeTests.test_weekday 6353+test.test_strptime.TimeRETests.test_compile 6354+test.test_tools.test_i18n.Test_pygettext.test_POT_Creation_Date 6355+test.test_venv.BasicTest.* 6356+test.test_venv.EnsurePipTest.* 6357+test.test_sysconfig.TestSysConfig.test_user_similar 6358+test.test_tcl.TclTest.testLoadWithUNC 6359+# flaky 6360+test.test__xxsubinterpreters.* 6361+test.test_asyncio.test_subprocess.SubprocessProactorTests.test_stdin_broken_pipe 6362+test.test_asynchat.TestAsynchat.test_line_terminator2 6363+test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_gc_aclose_09 6364+test.test_concurrent_futures.ThreadPoolShutdownTest.test_interpreter_shutdown 6365+test.test_asynchat.TestNotConnected.test_disallow_negative_terminator 6366+test.test_logging.SysLogHandlerTest.* 6367+test.test_logging.IPv6SysLogHandlerTest.* 6368diff --git a/mingw_smoketests.py b/mingw_smoketests.py 6369new file mode 100755 6370index 0000000..ca1f652 6371--- /dev/null 6372+++ b/mingw_smoketests.py 6373@@ -0,0 +1,358 @@ 6374+#!/usr/bin/env python3 6375+# Copyright 2017 Christoph Reiter 6376+# 6377+# Permission is hereby granted, free of charge, to any person obtaining 6378+# a copy of this software and associated documentation files (the 6379+# "Software"), to deal in the Software without restriction, including 6380+# without limitation the rights to use, copy, modify, merge, publish, 6381+# distribute, sublicense, and/or sell copies of the Software, and to 6382+# permit persons to whom the Software is furnished to do so, subject to 6383+# the following conditions: 6384+# 6385+# The above copyright notice and this permission notice shall be included 6386+# in all copies or substantial portions of the Software. 6387+# 6388+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 6389+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 6390+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 6391+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 6392+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 6393+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 6394+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6395+ 6396+"""The goal of this test suite is collect tests for update regressions 6397+and to test msys2 related modifications like for path handling. 6398+Feel free to extend. 6399+""" 6400+ 6401+import os 6402+import unittest 6403+import sysconfig 6404+ 6405+if os.environ.get("MSYSTEM", ""): 6406+ SEP = "/" 6407+else: 6408+ SEP = "\\" 6409+ 6410+if sysconfig.is_python_build(): 6411+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1" 6412+ 6413+_UCRT = sysconfig.get_platform() not in ('mingw_x86_64', 'mingw_i686') 6414+ 6415+ 6416+class Tests(unittest.TestCase): 6417+ 6418+ def test_zoneinfo(self): 6419+ # https://github.com/msys2-contrib/cpython-mingw/issues/32 6420+ import zoneinfo 6421+ self.assertTrue(any(os.path.exists(p) for p in zoneinfo.TZPATH)) 6422+ zoneinfo.ZoneInfo("America/Sao_Paulo") 6423+ 6424+ def test_userdir_path_sep(self): 6425+ # Make sure os.path and pathlib use the same path separators 6426+ from unittest import mock 6427+ from os.path import expanduser 6428+ from pathlib import Path 6429+ 6430+ profiles = ["C:\\foo", "C:/foo"] 6431+ for profile in profiles: 6432+ with mock.patch.dict(os.environ, {"USERPROFILE": profile}): 6433+ self.assertEqual(expanduser("~"), os.path.normpath(expanduser("~"))) 6434+ self.assertEqual(str(Path("~").expanduser()), expanduser("~")) 6435+ self.assertEqual(str(Path.home()), expanduser("~")) 6436+ 6437+ def test_sysconfig_schemes(self): 6438+ # https://github.com/msys2/MINGW-packages/issues/9319 6439+ import sysconfig 6440+ from distutils.dist import Distribution 6441+ from distutils.command.install import install 6442+ 6443+ names = ['scripts', 'purelib', 'platlib', 'data', 'include'] 6444+ for scheme in ["nt", "nt_user"]: 6445+ for name in names: 6446+ c = install(Distribution({"name": "foobar"})) 6447+ c.user = (scheme == "nt_user") 6448+ c.finalize_options() 6449+ if name == "include": 6450+ dist_path = os.path.dirname(getattr(c, "install_" + "headers")) 6451+ else: 6452+ dist_path = getattr(c, "install_" + name) 6453+ sys_path = sysconfig.get_path(name, scheme) 6454+ self.assertEqual(dist_path, sys_path, (scheme, name)) 6455+ 6456+ def test_ctypes_find_library(self): 6457+ from ctypes.util import find_library 6458+ from ctypes import cdll 6459+ self.assertTrue(cdll.msvcrt) 6460+ if _UCRT: 6461+ self.assertIsNone(find_library('c')) 6462+ else: 6463+ self.assertEqual(find_library('c'), 'msvcrt.dll') 6464+ 6465+ def test_ctypes_dlopen(self): 6466+ import ctypes 6467+ import sys 6468+ self.assertEqual(ctypes.RTLD_GLOBAL, 0) 6469+ self.assertEqual(ctypes.RTLD_GLOBAL, ctypes.RTLD_LOCAL) 6470+ self.assertFalse(hasattr(sys, 'setdlopenflags')) 6471+ self.assertFalse(hasattr(sys, 'getdlopenflags')) 6472+ self.assertFalse([n for n in dir(os) if n.startswith("RTLD_")]) 6473+ 6474+ def test_time_no_unix_stuff(self): 6475+ import time 6476+ self.assertFalse([n for n in dir(time) if n.startswith("clock_")]) 6477+ self.assertFalse([n for n in dir(time) if n.startswith("CLOCK_")]) 6478+ self.assertFalse([n for n in dir(time) if n.startswith("pthread_")]) 6479+ self.assertFalse(hasattr(time, 'tzset')) 6480+ 6481+ def test_strftime(self): 6482+ import time 6483+ with self.assertRaises(ValueError): 6484+ time.strftime('%Y', (12345,) + (0,) * 8) 6485+ 6486+ def test_sep(self): 6487+ self.assertEqual(os.sep, SEP) 6488+ 6489+ def test_module_file_path(self): 6490+ import asyncio 6491+ import zlib 6492+ self.assertEqual(zlib.__file__, os.path.normpath(zlib.__file__)) 6493+ self.assertEqual(asyncio.__file__, os.path.normpath(asyncio.__file__)) 6494+ 6495+ def test_importlib_frozen_path_sep(self): 6496+ import importlib._bootstrap_external 6497+ self.assertEqual(importlib._bootstrap_external.path_sep, SEP) 6498+ 6499+ def test_os_commonpath(self): 6500+ self.assertEqual( 6501+ os.path.commonpath( 6502+ [os.path.join("C:", os.sep, "foo", "bar"), 6503+ os.path.join("C:", os.sep, "foo")]), 6504+ os.path.join("C:", os.sep, "foo")) 6505+ 6506+ def test_pathlib(self): 6507+ import pathlib 6508+ 6509+ p = pathlib.Path("foo") / pathlib.Path("foo") 6510+ self.assertEqual(str(p), os.path.normpath(p)) 6511+ 6512+ def test_modules_import(self): 6513+ import sqlite3 6514+ import ssl 6515+ import ctypes 6516+ import curses 6517+ 6518+ def test_c_modules_import(self): 6519+ import _decimal 6520+ 6521+ def test_socket_inet_ntop(self): 6522+ import socket 6523+ self.assertTrue(hasattr(socket, "inet_ntop")) 6524+ 6525+ def test_socket_inet_pton(self): 6526+ import socket 6527+ self.assertTrue(hasattr(socket, "inet_pton")) 6528+ 6529+ def test_multiprocessing_queue(self): 6530+ from multiprocessing import Queue 6531+ Queue(0) 6532+ 6533+ #def test_socket_timout_normal_error(self): 6534+ # import urllib.request 6535+ # from urllib.error import URLError 6536+ 6537+ # try: 6538+ # urllib.request.urlopen( 6539+ # 'http://localhost', timeout=0.0001).close() 6540+ # except URLError: 6541+ # pass 6542+ 6543+ def test_threads(self): 6544+ from concurrent.futures import ThreadPoolExecutor 6545+ 6546+ with ThreadPoolExecutor(1) as pool: 6547+ for res in pool.map(lambda *x: None, range(10000)): 6548+ pass 6549+ 6550+ def test_sysconfig(self): 6551+ import sysconfig 6552+ # This should be able to execute without exceptions 6553+ sysconfig.get_config_vars() 6554+ 6555+ def test_sqlite_enable_load_extension(self): 6556+ # Make sure --enable-loadable-sqlite-extensions is used 6557+ import sqlite3 6558+ self.assertTrue(sqlite3.Connection.enable_load_extension) 6559+ 6560+ def test_venv_creation(self): 6561+ import tempfile 6562+ import venv 6563+ import subprocess 6564+ import shutil 6565+ with tempfile.TemporaryDirectory() as tmp: 6566+ builder = venv.EnvBuilder() 6567+ builder.create(tmp) 6568+ assert os.path.exists(os.path.join(tmp, "bin", "activate")) 6569+ assert os.path.exists(os.path.join(tmp, "bin", "python.exe")) 6570+ assert os.path.exists(os.path.join(tmp, "bin", "python3.exe")) 6571+ subprocess.check_call([shutil.which("bash.exe"), os.path.join(tmp, "bin", "activate")]) 6572+ 6573+ # This will not work in in-tree build 6574+ if not sysconfig.is_python_build(): 6575+ op = subprocess.check_output( 6576+ [ 6577+ os.path.join(tmp, "bin", "python.exe"), 6578+ "-c", 6579+ "print('Hello World')" 6580+ ], 6581+ cwd=tmp, 6582+ ) 6583+ assert op.decode().strip() == "Hello World" 6584+ 6585+ def test_has_mktime(self): 6586+ from time import mktime, gmtime 6587+ mktime(gmtime()) 6588+ 6589+ def test_platform_things(self): 6590+ import sys 6591+ import sysconfig 6592+ import platform 6593+ import importlib.machinery 6594+ self.assertEqual(sys.implementation.name, "cpython") 6595+ self.assertEqual(sys.platform, "win32") 6596+ self.assertTrue(sysconfig.get_platform().startswith("mingw")) 6597+ self.assertTrue(sysconfig.get_config_var('SOABI').startswith("cpython-")) 6598+ ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') 6599+ self.assertTrue(ext_suffix.endswith(".pyd")) 6600+ self.assertTrue("mingw" in ext_suffix) 6601+ self.assertEqual(sysconfig.get_config_var('SHLIB_SUFFIX'), ".pyd") 6602+ ext_suffixes = importlib.machinery.EXTENSION_SUFFIXES 6603+ self.assertTrue(ext_suffix in ext_suffixes) 6604+ self.assertTrue(".pyd" in ext_suffixes) 6605+ if sysconfig.get_platform().startswith('mingw_i686'): 6606+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-32') 6607+ elif sysconfig.get_platform().startswith('mingw_aarch64'): 6608+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-arm64') 6609+ elif sysconfig.get_platform().startswith('mingw_armv7'): 6610+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-arm32') 6611+ else: 6612+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2]))) 6613+ self.assertEqual(platform.python_implementation(), "CPython") 6614+ self.assertEqual(platform.system(), "Windows") 6615+ self.assertTrue(isinstance(sys.api_version, int) and sys.api_version > 0) 6616+ 6617+ def test_sys_getpath(self): 6618+ # everything sourced from getpath.py 6619+ import sys 6620+ 6621+ def assertNormpath(path): 6622+ self.assertEqual(path, os.path.normpath(path)) 6623+ 6624+ assertNormpath(sys.executable) 6625+ assertNormpath(sys._base_executable) 6626+ assertNormpath(sys.prefix) 6627+ assertNormpath(sys.base_prefix) 6628+ assertNormpath(sys.exec_prefix) 6629+ assertNormpath(sys.base_exec_prefix) 6630+ assertNormpath(sys.platlibdir) 6631+ assertNormpath(sys._stdlib_dir) 6632+ for p in sys.path: 6633+ assertNormpath(p) 6634+ 6635+ def test_site(self): 6636+ import site 6637+ 6638+ self.assertEqual(len(site.getsitepackages()), 1) 6639+ 6640+ def test_c_ext_build(self): 6641+ import tempfile 6642+ import sys 6643+ import subprocess 6644+ import textwrap 6645+ from pathlib import Path 6646+ 6647+ with tempfile.TemporaryDirectory() as tmppro: 6648+ subprocess.check_call([sys.executable, "-m", "ensurepip", "--user"]) 6649+ with Path(tmppro, "setup.py").open("w") as f: 6650+ f.write( 6651+ textwrap.dedent( 6652+ """\ 6653+ from setuptools import setup, Extension 6654+ 6655+ setup( 6656+ name='cwrapper', 6657+ version='1.0', 6658+ ext_modules=[ 6659+ Extension( 6660+ 'cwrapper', 6661+ sources=['cwrapper.c']), 6662+ ], 6663+ ) 6664+ """ 6665+ ) 6666+ ) 6667+ with Path(tmppro, "cwrapper.c").open("w") as f: 6668+ f.write( 6669+ textwrap.dedent( 6670+ """\ 6671+ #include <Python.h> 6672+ static PyObject * 6673+ helloworld(PyObject *self, PyObject *args) 6674+ { 6675+ printf("Hello World\\n"); 6676+ Py_RETURN_NONE; 6677+ } 6678+ static PyMethodDef 6679+ myMethods[] = { 6680+ { "helloworld", helloworld, METH_NOARGS, "Prints Hello World" }, 6681+ { NULL, NULL, 0, NULL } 6682+ }; 6683+ static struct PyModuleDef cwrapper = { 6684+ PyModuleDef_HEAD_INIT, 6685+ "cwrapper", 6686+ "Test Module", 6687+ -1, 6688+ myMethods 6689+ }; 6690+ 6691+ PyMODINIT_FUNC 6692+ PyInit_cwrapper(void) 6693+ { 6694+ return PyModule_Create(&cwrapper); 6695+ } 6696+ """ 6697+ ) 6698+ ) 6699+ subprocess.check_call( 6700+ [sys.executable, "-c", "import struct"], 6701+ ) 6702+ subprocess.check_call( 6703+ [ 6704+ sys.executable, 6705+ "-m", 6706+ "pip", 6707+ "install", 6708+ "wheel", 6709+ ], 6710+ ) 6711+ subprocess.check_call( 6712+ [ 6713+ sys.executable, 6714+ "-m", 6715+ "pip", 6716+ "install", 6717+ tmppro, 6718+ ], 6719+ ) 6720+ subprocess.check_call( 6721+ [sys.executable, "-c", "import cwrapper"], 6722+ ) 6723+ 6724+ 6725+ 6726+def suite(): 6727+ return unittest.TestLoader().loadTestsFromName(__name__) 6728+ 6729+ 6730+if __name__ == '__main__': 6731+ unittest.main(defaultTest='suite') 6732diff --git a/pyconfig.h.in b/pyconfig.h.in 6733index 75f1d90..3b89b9e 100644 6734--- a/pyconfig.h.in 6735+++ b/pyconfig.h.in 6736@@ -60,7 +60,7 @@ 6737 /* Define to 1 if you have the `acosh' function. */ 6738 #undef HAVE_ACOSH 6739 6740-/* struct addrinfo (netdb.h) */ 6741+/* struct addrinfo */ 6742 #undef HAVE_ADDRINFO 6743 6744 /* Define to 1 if you have the `alarm' function. */ 6745@@ -1521,6 +1521,9 @@ 6746 /* Define if mvwdelch in curses.h is an expression. */ 6747 #undef MVWDELCH_IS_EXPRESSION 6748 6749+/* Define to 1 if you want to use native NT threads */ 6750+#undef NT_THREADS 6751+ 6752 /* Define to the address where bug reports for this package should be sent. */ 6753 #undef PACKAGE_BUGREPORT 6754 6755@@ -1836,7 +1839,7 @@ 6756 /* Define to `unsigned int' if <sys/types.h> does not define. */ 6757 #undef size_t 6758 6759-/* Define to `int' if <sys/socket.h> does not define. */ 6760+/* Define to `int' if <sys/socket.h> or <ws2tcpip.h> does not define. */ 6761 #undef socklen_t 6762 6763 /* Define to `int' if <sys/types.h> doesn't define. */ 6764diff --git a/setup.py b/setup.py 6765index 4f122b6..e4f15d8 100644 6766--- a/setup.py 6767+++ b/setup.py 6768@@ -77,9 +77,24 @@ def get_platform(): 6769 return sys.platform 6770 6771 6772+# On MSYS, os.system needs to be wrapped with sh.exe 6773+# as otherwise all the io redirection will fail. 6774+# Arguably, this could happen inside the real os.system 6775+# rather than this monkey patch. 6776+if sys.platform == "win32" and os.environ.get("MSYSTEM", ""): 6777+ os_system = os.system 6778+ def msys_system(command): 6779+ command_in_sh = 'sh.exe -c "%s"' % command.replace("\\", "\\\\") 6780+ return os_system(command_in_sh) 6781+ os.system = msys_system 6782+ 6783+ # set PYTHONLEGACYWINDOWSDLLLOADING to 1 to load DLLs from PATH 6784+ # This is needed while building core extensions of Python 6785+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1" 6786+ 6787 CROSS_COMPILING = ("_PYTHON_HOST_PLATFORM" in os.environ) 6788 HOST_PLATFORM = get_platform() 6789-MS_WINDOWS = (HOST_PLATFORM == 'win32') 6790+MS_WINDOWS = (HOST_PLATFORM == 'win32' or HOST_PLATFORM == 'mingw') 6791 CYGWIN = (HOST_PLATFORM == 'cygwin') 6792 MACOS = (HOST_PLATFORM == 'darwin') 6793 AIX = (HOST_PLATFORM.startswith('aix')) 6794@@ -687,7 +702,7 @@ def check_extension_import(self, ext): 6795 def add_multiarch_paths(self): 6796 # Debian/Ubuntu multiarch support. 6797 # https://wiki.ubuntu.com/MultiarchSpec 6798- tmpfile = os.path.join(self.build_temp, 'multiarch') 6799+ tmpfile = os.path.join(self.build_temp, 'multiarch').replace('\\','/') 6800 if not os.path.exists(self.build_temp): 6801 os.makedirs(self.build_temp) 6802 ret = run_command( 6803@@ -712,7 +727,7 @@ def add_multiarch_paths(self): 6804 opt = '' 6805 if CROSS_COMPILING: 6806 opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE') 6807- tmpfile = os.path.join(self.build_temp, 'multiarch') 6808+ tmpfile = os.path.join(self.build_temp, 'multiarch').replace('\\','/') 6809 if not os.path.exists(self.build_temp): 6810 os.makedirs(self.build_temp) 6811 ret = run_command( 6812@@ -774,7 +789,7 @@ def add_search_path(line): 6813 pass 6814 6815 def add_cross_compiling_paths(self): 6816- tmpfile = os.path.join(self.build_temp, 'ccpaths') 6817+ tmpfile = os.path.join(self.build_temp, 'ccpaths').replace('\\','/') 6818 if not os.path.exists(self.build_temp): 6819 os.makedirs(self.build_temp) 6820 # bpo-38472: With a German locale, GCC returns "gcc-Version 9.1.0 6821@@ -796,14 +811,25 @@ def add_cross_compiling_paths(self): 6822 elif line.startswith("End of search list"): 6823 in_incdirs = False 6824 elif (is_gcc or is_clang) and line.startswith("LIBRARY_PATH"): 6825- for d in line.strip().split("=")[1].split(":"): 6826+ for d in line.strip().split("=")[1].split(os.pathsep): 6827 d = os.path.normpath(d) 6828- if '/gcc/' not in d: 6829+ if '/gcc/' not in d and '/clang/' not in d: 6830 add_dir_to_list(self.compiler.library_dirs, 6831 d) 6832 elif (is_gcc or is_clang) and in_incdirs and '/gcc/' not in line and '/clang/' not in line: 6833 add_dir_to_list(self.compiler.include_dirs, 6834 line.strip()) 6835+ if is_clang: 6836+ ret = run_command('%s -print-search-dirs >%s' % (CC, tmpfile)) 6837+ if ret == 0: 6838+ with open(tmpfile) as fp: 6839+ for line in fp.readlines(): 6840+ if line.startswith("libraries:"): 6841+ for d in line.strip().split("=")[1].split(os.pathsep): 6842+ d = os.path.normpath(d) 6843+ if '/gcc/' not in d and '/clang/' not in d: 6844+ add_dir_to_list(self.compiler.library_dirs, 6845+ d) 6846 finally: 6847 os.unlink(tmpfile) 6848 6849@@ -849,10 +875,10 @@ def configure_compiler(self): 6850 if not CROSS_COMPILING: 6851 add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') 6852 add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') 6853+ self.add_multiarch_paths() 6854 # only change this for cross builds for 3.3, issues on Mageia 6855 if CROSS_COMPILING: 6856 self.add_cross_compiling_paths() 6857- self.add_multiarch_paths() 6858 self.add_ldflags_cppflags() 6859 6860 def init_inc_lib_dirs(self): 6861@@ -898,7 +924,7 @@ def init_inc_lib_dirs(self): 6862 if HOST_PLATFORM == 'hp-ux11': 6863 self.lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32'] 6864 6865- if MACOS: 6866+ if MACOS or MS_WINDOWS: 6867 # This should work on any unixy platform ;-) 6868 # If the user has bothered specifying additional -I and -L flags 6869 # in OPT and LDFLAGS we might as well use them here. 6870@@ -970,11 +996,15 @@ def detect_simple_extensions(self): 6871 # grp(3) 6872 self.addext(Extension('grp', ['grpmodule.c'])) 6873 6874- self.addext(Extension('_socket', ['socketmodule.c'])) 6875+ self.addext(Extension( 6876+ '_socket', ['socketmodule.c'], 6877+ libraries=(['ws2_32', 'iphlpapi'] if MS_WINDOWS else None))) 6878 self.addext(Extension('spwd', ['spwdmodule.c'])) 6879 6880 # select(2); not on ancient System V 6881- self.addext(Extension('select', ['selectmodule.c'])) 6882+ self.addext(Extension( 6883+ 'select', ['selectmodule.c'], 6884+ libraries=(['ws2_32'] if MS_WINDOWS else None))) 6885 6886 # Memory-mapped files (also works on Win32). 6887 self.addext(Extension('mmap', ['mmapmodule.c'])) 6888@@ -1033,12 +1063,15 @@ def detect_test_extensions(self): 6889 ['_xxtestfuzz/_xxtestfuzz.c', '_xxtestfuzz/fuzzer.c'] 6890 )) 6891 6892+ if MS_WINDOWS: 6893+ self.add(Extension('_testconsole', ['../PC/_testconsole.c'])) 6894+ 6895 def detect_readline_curses(self): 6896 # readline 6897 readline_termcap_library = "" 6898 curses_library = "" 6899 # Cannot use os.popen here in py3k. 6900- tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') 6901+ tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib').replace('\\','/') 6902 if not os.path.exists(self.build_temp): 6903 os.makedirs(self.build_temp) 6904 # Determine if readline is already linked against curses or tinfo. 6905@@ -1101,6 +1134,8 @@ def detect_readline_curses(self): 6906 # readline package 6907 if find_file('readline/rlconf.h', self.inc_dirs, []) is None: 6908 do_readline = False 6909+ if MS_WINDOWS: 6910+ do_readline = False 6911 if do_readline: 6912 readline_libs = [readline_lib] 6913 if readline_termcap_library: 6914@@ -1124,8 +1159,7 @@ def detect_readline_curses(self): 6915 panel_library = 'panel' 6916 if curses_library == 'ncursesw': 6917 curses_defines.append(('HAVE_NCURSESW', '1')) 6918- if not CROSS_COMPILING: 6919- curses_includes.append('/usr/include/ncursesw') 6920+ curses_includes.append(sysconfig.get_config_var("NCURSESW_INCLUDEDIR")) 6921 # Bug 1464056: If _curses.so links with ncursesw, 6922 # _curses_panel.so must link with panelw. 6923 panel_library = 'panelw' 6924@@ -1209,7 +1243,7 @@ def detect_dbm_gdbm(self): 6925 if dbm_args: 6926 dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":") 6927 else: 6928- dbm_order = "gdbm:ndbm:bdb".split(":") 6929+ dbm_order = [] 6930 dbmext = None 6931 for cand in dbm_order: 6932 if cand == "ndbm": 6933@@ -1282,6 +1316,19 @@ def detect_platform_specific_exts(self): 6934 # macOS-only, needs SystemConfiguration and CoreFoundation framework 6935 self.addext(Extension('_scproxy', ['_scproxy.c'])) 6936 6937+ # Windows-only modules 6938+ if MS_WINDOWS: 6939+ srcdir = sysconfig.get_config_var('srcdir') 6940+ pc_srcdir = os.path.abspath(os.path.join(srcdir, 'PC')) 6941+ 6942+ self.addext(Extension('_msi', 6943+ [os.path.join(pc_srcdir, '_msi.c')])) 6944+ 6945+ self.addext(Extension('winsound', 6946+ [os.path.join(pc_srcdir, 'winsound.c')])) 6947+ 6948+ self.addext(Extension('_overlapped', ['overlapped.c'])) 6949+ 6950 def detect_compress_exts(self): 6951 # Andrew Kuchling's zlib module. 6952 self.addext(Extension('zlib', ['zlibmodule.c'])) 6953@@ -1329,9 +1376,10 @@ def detect_multiprocessing(self): 6954 if ( 6955 sysconfig.get_config_var('HAVE_SEM_OPEN') and not 6956 sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED') 6957- ): 6958+ ) or MS_WINDOWS: 6959 multiprocessing_srcs.append('_multiprocessing/semaphore.c') 6960- self.addext(Extension('_multiprocessing', multiprocessing_srcs)) 6961+ self.addext(Extension('_multiprocessing', multiprocessing_srcs, 6962+ libraries=(['ws2_32'] if MS_WINDOWS else None), include_dirs=["Modules/_multiprocessing"])) 6963 self.addext(Extension('_posixshmem', ['_multiprocessing/posixshmem.c'])) 6964 6965 def detect_uuid(self): 6966@@ -1414,11 +1462,16 @@ def detect_ctypes(self): 6967 include_dirs=include_dirs, 6968 extra_compile_args=extra_compile_args, 6969 extra_link_args=extra_link_args, 6970- libraries=[], 6971+ libraries=(['ole32', 'oleaut32', 'uuid'] if MS_WINDOWS else []), 6972+ export_symbols=( 6973+ ['DllGetClassObject PRIVATE', 'DllCanUnloadNow PRIVATE'] 6974+ if MS_WINDOWS else None 6975+ ), 6976 sources=sources) 6977 self.add(ext) 6978 # function my_sqrt() needs libm for sqrt() 6979- self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'])) 6980+ self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'], 6981+ libraries=(['oleaut32'] if MS_WINDOWS else []))) 6982 6983 ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR") 6984 ffi_lib = None 6985@@ -1568,7 +1621,7 @@ def copy_scripts(self): 6986 else: 6987 newfilename = filename + minoronly 6988 log.info(f'renaming {filename} to {newfilename}') 6989- os.rename(filename, newfilename) 6990+ os.replace(filename, newfilename) 6991 newoutfiles.append(newfilename) 6992 if filename in updated_files: 6993 newupdated_files.append(newfilename) 6994