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