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