mirror of
https://gitee.com/openharmony/third_party_python
synced 2024-11-27 01:21:06 +00:00
084de15af8
issue:https://gitee.com/openharmony/third_party_python/issues/IACDNR Signed-off-by: xwx1135370 <xuyao44@huawei.com>
6994 lines
240 KiB
Diff
6994 lines
240 KiB
Diff
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
|
|
new file mode 100755
|
|
index 0000000..c2293cb
|
|
--- /dev/null
|
|
+++ b/.github/workflows/build.yml
|
|
@@ -0,0 +1,418 @@
|
|
+name: Tests
|
|
+
|
|
+# gh-84728: "paths-ignore" is not used to skip documentation-only PRs, because
|
|
+# it prevents to mark a job as mandatory. A PR cannot be merged if a job is
|
|
+# mandatory but not scheduled because of "paths-ignore".
|
|
+on:
|
|
+ workflow_dispatch:
|
|
+ push:
|
|
+ branches:
|
|
+ - 'main'
|
|
+ - '3.11'
|
|
+ - '3.10'
|
|
+ - '3.9'
|
|
+ - '3.8'
|
|
+ - '3.7'
|
|
+ pull_request:
|
|
+ branches:
|
|
+ - 'main'
|
|
+ - '3.11'
|
|
+ - '3.10'
|
|
+ - '3.9'
|
|
+ - '3.8'
|
|
+ - '3.7'
|
|
+
|
|
+permissions:
|
|
+ contents: read
|
|
+
|
|
+concurrency:
|
|
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
+ cancel-in-progress: true
|
|
+
|
|
+jobs:
|
|
+ check_source:
|
|
+ name: 'Check for source changes'
|
|
+ runs-on: ubuntu-latest
|
|
+ timeout-minutes: 10
|
|
+ outputs:
|
|
+ run_tests: ${{ steps.check.outputs.run_tests }}
|
|
+ run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }}
|
|
+ config_hash: ${{ steps.config_hash.outputs.hash }}
|
|
+ steps:
|
|
+ - uses: actions/checkout@v3
|
|
+ - name: Check for source changes
|
|
+ id: check
|
|
+ run: |
|
|
+ if [ -z "$GITHUB_BASE_REF" ]; then
|
|
+ echo "run_tests=true" >> $GITHUB_OUTPUT
|
|
+ echo "run_ssl_tests=true" >> $GITHUB_OUTPUT
|
|
+ else
|
|
+ git fetch origin $GITHUB_BASE_REF --depth=1
|
|
+ # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more
|
|
+ # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots),
|
|
+ # but it requires to download more commits (this job uses
|
|
+ # "git fetch --depth=1").
|
|
+ #
|
|
+ # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git
|
|
+ # 2.26, but Git 2.28 is stricter and fails with "no merge base".
|
|
+ #
|
|
+ # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on
|
|
+ # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF
|
|
+ # into the PR branch anyway.
|
|
+ #
|
|
+ # https://github.com/python/core-workflow/issues/373
|
|
+ git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true
|
|
+ git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE '(ssl|hashlib|hmac|^.github)' && echo "run_ssl_tests=true" >> $GITHUB_OUTPUT || true
|
|
+ fi
|
|
+ - name: Compute hash for config cache key
|
|
+ id: config_hash
|
|
+ run: |
|
|
+ echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT
|
|
+
|
|
+ check_abi:
|
|
+ name: 'Check if the ABI has changed'
|
|
+ runs-on: ubuntu-20.04
|
|
+ needs: check_source
|
|
+ if: needs.check_source.outputs.run_tests == 'true'
|
|
+ steps:
|
|
+ - uses: actions/checkout@v2
|
|
+ - uses: actions/setup-python@v2
|
|
+ - name: Install Dependencies
|
|
+ run: |
|
|
+ sudo ./.github/workflows/posix-deps-apt.sh
|
|
+ sudo apt-get install -yq abigail-tools
|
|
+ - name: Build CPython
|
|
+ env:
|
|
+ CFLAGS: -g3 -O0
|
|
+ run: |
|
|
+ # Build Python with the libpython dynamic library
|
|
+ ./configure --enable-shared
|
|
+ make -j4
|
|
+ - name: Check for changes in the ABI
|
|
+ id: check
|
|
+ run: |
|
|
+ if ! make check-abidump; then
|
|
+ echo "Generated ABI file is not up to date."
|
|
+ echo "Please, add the release manager of this branch as a reviewer of this PR."
|
|
+ echo ""
|
|
+ echo "The up to date ABI file should be attached to this build as an artifact."
|
|
+ echo ""
|
|
+ echo "To learn more about this check: https://devguide.python.org/setup/#regenerate-the-abi-dump"
|
|
+ echo ""
|
|
+ exit 1
|
|
+ fi
|
|
+ - name: Generate updated ABI files
|
|
+ if: ${{ failure() && steps.check.conclusion == 'failure' }}
|
|
+ run: |
|
|
+ make regen-abidump
|
|
+ - uses: actions/upload-artifact@v3
|
|
+ name: Publish updated ABI files
|
|
+ if: ${{ failure() && steps.check.conclusion == 'failure' }}
|
|
+ with:
|
|
+ name: abi-data
|
|
+ path: ./Doc/data/*.abi
|
|
+
|
|
+ check_generated_files:
|
|
+ name: 'Check if generated files are up to date'
|
|
+ runs-on: ubuntu-latest
|
|
+ timeout-minutes: 60
|
|
+ needs: check_source
|
|
+ if: needs.check_source.outputs.run_tests == 'true'
|
|
+ steps:
|
|
+ - uses: actions/checkout@v3
|
|
+ - name: Restore config.cache
|
|
+ uses: actions/cache@v3
|
|
+ with:
|
|
+ path: config.cache
|
|
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
|
|
+ - uses: actions/setup-python@v3
|
|
+ - name: Install Dependencies
|
|
+ run: sudo ./.github/workflows/posix-deps-apt.sh
|
|
+ - name: Add ccache to PATH
|
|
+ run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
|
+ - name: Configure ccache action
|
|
+ uses: hendrikmuhs/ccache-action@v1.2
|
|
+ - name: Check Autoconf version 2.69 and aclocal 1.16.3
|
|
+ run: |
|
|
+ grep "Generated by GNU Autoconf 2.69" configure
|
|
+ grep "aclocal 1.16.3" aclocal.m4
|
|
+ grep -q "runstatedir" configure
|
|
+ grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4
|
|
+ - name: Configure CPython
|
|
+ run: |
|
|
+ # Build Python with the libpython dynamic library
|
|
+ ./configure --config-cache --with-pydebug --enable-shared
|
|
+ - name: Regenerate autoconf files with container image
|
|
+ run: make regen-configure
|
|
+ - name: Build CPython
|
|
+ run: |
|
|
+ # Deepfreeze will usually cause global objects to be added or removed,
|
|
+ # so we run it before regen-global-objects gets rum (in regen-all).
|
|
+ make regen-deepfreeze
|
|
+ make -j4 regen-all
|
|
+ make regen-stdlib-module-names
|
|
+ - name: Check for changes
|
|
+ run: |
|
|
+ git add -u
|
|
+ changes=$(git status --porcelain)
|
|
+ # Check for changes in regenerated files
|
|
+ if test -n "$changes"; then
|
|
+ echo "Generated files not up to date."
|
|
+ echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)"
|
|
+ echo "configure files must be regenerated with a specific version of autoconf."
|
|
+ echo "$changes"
|
|
+ echo ""
|
|
+ git diff --staged || true
|
|
+ exit 1
|
|
+ fi
|
|
+ - name: Check exported libpython symbols
|
|
+ run: make smelly
|
|
+ - name: Check limited ABI symbols
|
|
+ run: make check-limited-abi
|
|
+
|
|
+ build_win32:
|
|
+ name: 'Windows (x86)'
|
|
+ runs-on: windows-latest
|
|
+ timeout-minutes: 60
|
|
+ needs: check_source
|
|
+ if: needs.check_source.outputs.run_tests == 'true'
|
|
+ env:
|
|
+ IncludeUwp: 'true'
|
|
+ steps:
|
|
+ - uses: actions/checkout@v3
|
|
+ - name: Build CPython
|
|
+ run: .\PCbuild\build.bat -e -d -p Win32
|
|
+ - name: Display build info
|
|
+ run: .\python.bat -m test.pythoninfo
|
|
+ - name: Tests
|
|
+ run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
|
|
+
|
|
+ build_win_amd64:
|
|
+ name: 'Windows (x64)'
|
|
+ runs-on: windows-latest
|
|
+ timeout-minutes: 60
|
|
+ needs: check_source
|
|
+ if: needs.check_source.outputs.run_tests == 'true'
|
|
+ env:
|
|
+ IncludeUwp: 'true'
|
|
+ steps:
|
|
+ - uses: actions/checkout@v3
|
|
+ - name: Register MSVC problem matcher
|
|
+ run: echo "::add-matcher::.github/problem-matchers/msvc.json"
|
|
+ - name: Build CPython
|
|
+ run: .\PCbuild\build.bat -e -d -p x64
|
|
+ - name: Display build info
|
|
+ run: .\python.bat -m test.pythoninfo
|
|
+ - name: Tests
|
|
+ run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0
|
|
+
|
|
+ build_macos:
|
|
+ name: 'macOS'
|
|
+ runs-on: macos-latest
|
|
+ timeout-minutes: 60
|
|
+ needs: check_source
|
|
+ if: needs.check_source.outputs.run_tests == 'true'
|
|
+ env:
|
|
+ HOMEBREW_NO_ANALYTICS: 1
|
|
+ HOMEBREW_NO_AUTO_UPDATE: 1
|
|
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
|
|
+ PYTHONSTRICTEXTENSIONBUILD: 1
|
|
+ steps:
|
|
+ - uses: actions/checkout@v3
|
|
+ - name: Restore config.cache
|
|
+ uses: actions/cache@v3
|
|
+ with:
|
|
+ path: config.cache
|
|
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
|
|
+ - name: Install Homebrew dependencies
|
|
+ run: brew install pkg-config openssl@1.1 xz gdbm tcl-tk
|
|
+ - name: Configure CPython
|
|
+ run: |
|
|
+ CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \
|
|
+ LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \
|
|
+ PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
|
|
+ ./configure \
|
|
+ --config-cache \
|
|
+ --with-pydebug \
|
|
+ --prefix=/opt/python-dev \
|
|
+ --with-openssl="$(brew --prefix openssl@1.1)"
|
|
+ - name: Build CPython
|
|
+ run: make -j4
|
|
+ - name: Display build info
|
|
+ run: make pythoninfo
|
|
+ - name: Tests
|
|
+ run: make buildbottest TESTOPTS="-j4 -uall,-cpu"
|
|
+
|
|
+ build_ubuntu:
|
|
+ name: 'Ubuntu'
|
|
+ runs-on: ubuntu-20.04
|
|
+ timeout-minutes: 60
|
|
+ needs: check_source
|
|
+ if: needs.check_source.outputs.run_tests == 'true'
|
|
+ env:
|
|
+ OPENSSL_VER: 1.1.1u
|
|
+ PYTHONSTRICTEXTENSIONBUILD: 1
|
|
+ steps:
|
|
+ - uses: actions/checkout@v3
|
|
+ - name: Register gcc problem matcher
|
|
+ run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
|
+ - name: Install Dependencies
|
|
+ run: sudo ./.github/workflows/posix-deps-apt.sh
|
|
+ - name: Configure OpenSSL env vars
|
|
+ run: |
|
|
+ echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV
|
|
+ echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV
|
|
+ echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
|
|
+ - name: 'Restore OpenSSL build'
|
|
+ id: cache-openssl
|
|
+ uses: actions/cache@v3
|
|
+ with:
|
|
+ path: ./multissl/openssl/${{ env.OPENSSL_VER }}
|
|
+ key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
|
|
+ - name: Install OpenSSL
|
|
+ if: steps.cache-openssl.outputs.cache-hit != 'true'
|
|
+ run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux
|
|
+ - name: Add ccache to PATH
|
|
+ run: |
|
|
+ echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
|
+ - name: Configure ccache action
|
|
+ uses: hendrikmuhs/ccache-action@v1.2
|
|
+ - name: Setup directory envs for out-of-tree builds
|
|
+ run: |
|
|
+ echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV
|
|
+ echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV
|
|
+ - name: Create directories for read-only out-of-tree builds
|
|
+ run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR
|
|
+ - name: Bind mount sources read-only
|
|
+ run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR
|
|
+ - name: Restore config.cache
|
|
+ uses: actions/cache@v3
|
|
+ with:
|
|
+ path: ${{ env.CPYTHON_BUILDDIR }}/config.cache
|
|
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
|
|
+ - name: Configure CPython out-of-tree
|
|
+ working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
|
+ run: |
|
|
+ ../cpython-ro-srcdir/configure \
|
|
+ --config-cache \
|
|
+ --with-pydebug \
|
|
+ --with-openssl=$OPENSSL_DIR
|
|
+ - name: Build CPython out-of-tree
|
|
+ working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
|
+ run: make -j4
|
|
+ - name: Display build info
|
|
+ working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
|
+ run: make pythoninfo
|
|
+ - name: Remount sources writable for tests
|
|
+ # some tests write to srcdir, lack of pyc files slows down testing
|
|
+ run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw
|
|
+ - name: Tests
|
|
+ working-directory: ${{ env.CPYTHON_BUILDDIR }}
|
|
+ run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
|
|
+
|
|
+ build_ubuntu_ssltests:
|
|
+ name: 'Ubuntu SSL tests with OpenSSL'
|
|
+ runs-on: ubuntu-20.04
|
|
+ timeout-minutes: 60
|
|
+ needs: check_source
|
|
+ if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_ssl_tests == 'true'
|
|
+ strategy:
|
|
+ fail-fast: false
|
|
+ matrix:
|
|
+ openssl_ver: [1.1.1u, 3.0.9, 3.1.1]
|
|
+ env:
|
|
+ OPENSSL_VER: ${{ matrix.openssl_ver }}
|
|
+ MULTISSL_DIR: ${{ github.workspace }}/multissl
|
|
+ OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}
|
|
+ LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib
|
|
+ steps:
|
|
+ - uses: actions/checkout@v3
|
|
+ - name: Restore config.cache
|
|
+ uses: actions/cache@v3
|
|
+ with:
|
|
+ path: config.cache
|
|
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
|
|
+ - name: Register gcc problem matcher
|
|
+ run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
|
+ - name: Install Dependencies
|
|
+ run: sudo ./.github/workflows/posix-deps-apt.sh
|
|
+ - name: Configure OpenSSL env vars
|
|
+ run: |
|
|
+ echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV
|
|
+ echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV
|
|
+ echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
|
|
+ - name: 'Restore OpenSSL build'
|
|
+ id: cache-openssl
|
|
+ uses: actions/cache@v3
|
|
+ with:
|
|
+ path: ./multissl/openssl/${{ env.OPENSSL_VER }}
|
|
+ key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
|
|
+ - name: Install OpenSSL
|
|
+ if: steps.cache-openssl.outputs.cache-hit != 'true'
|
|
+ run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux
|
|
+ - name: Add ccache to PATH
|
|
+ run: |
|
|
+ echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
|
+ - name: Configure ccache action
|
|
+ uses: hendrikmuhs/ccache-action@v1.2
|
|
+ - name: Configure CPython
|
|
+ run: ./configure --config-cache --with-pydebug --with-openssl=$OPENSSL_DIR
|
|
+ - name: Build CPython
|
|
+ run: make -j4
|
|
+ - name: Display build info
|
|
+ run: make pythoninfo
|
|
+ - name: SSL tests
|
|
+ run: ./python Lib/test/ssltests.py
|
|
+
|
|
+ build_asan:
|
|
+ name: 'Address sanitizer'
|
|
+ runs-on: ubuntu-20.04
|
|
+ timeout-minutes: 60
|
|
+ needs: check_source
|
|
+ if: needs.check_source.outputs.run_tests == 'true'
|
|
+ env:
|
|
+ OPENSSL_VER: 1.1.1u
|
|
+ PYTHONSTRICTEXTENSIONBUILD: 1
|
|
+ ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0
|
|
+ steps:
|
|
+ - uses: actions/checkout@v3
|
|
+ - name: Restore config.cache
|
|
+ uses: actions/cache@v3
|
|
+ with:
|
|
+ path: config.cache
|
|
+ key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }}
|
|
+ - name: Register gcc problem matcher
|
|
+ run: echo "::add-matcher::.github/problem-matchers/gcc.json"
|
|
+ - name: Install Dependencies
|
|
+ run: sudo ./.github/workflows/posix-deps-apt.sh
|
|
+ - name: Set up GCC-10 for ASAN
|
|
+ uses: egor-tensin/setup-gcc@v1
|
|
+ with:
|
|
+ version: 10
|
|
+ - name: Configure OpenSSL env vars
|
|
+ run: |
|
|
+ echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV
|
|
+ echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV
|
|
+ echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV
|
|
+ - name: 'Restore OpenSSL build'
|
|
+ id: cache-openssl
|
|
+ uses: actions/cache@v3
|
|
+ with:
|
|
+ path: ./multissl/openssl/${{ env.OPENSSL_VER }}
|
|
+ key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
|
|
+ - name: Install OpenSSL
|
|
+ if: steps.cache-openssl.outputs.cache-hit != 'true'
|
|
+ run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux
|
|
+ - name: Add ccache to PATH
|
|
+ run: |
|
|
+ echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
|
|
+ - name: Configure ccache action
|
|
+ uses: hendrikmuhs/ccache-action@v1.2
|
|
+ - name: Configure CPython
|
|
+ run: ./configure --config-cache --with-address-sanitizer --without-pymalloc
|
|
+ - name: Build CPython
|
|
+ run: make -j4
|
|
+ - name: Display build info
|
|
+ run: make pythoninfo
|
|
+ - name: Tests
|
|
+ run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
|
|
diff --git a/.gitignore b/.gitignore
|
|
index 0ddfd71..d42e111 100644
|
|
--- a/.gitignore
|
|
+++ b/.gitignore
|
|
@@ -114,6 +114,7 @@ PCbuild/win32/
|
|
Tools/unicode/data/
|
|
/autom4te.cache
|
|
/build/
|
|
+/builddir/
|
|
/config.cache
|
|
/config.log
|
|
/config.status
|
|
@@ -150,6 +151,3 @@ Python/frozen_modules/MANIFEST
|
|
# Ignore ./python binary on Unix but still look into ./Python/ directory.
|
|
/python
|
|
!/Python/
|
|
-
|
|
-# main branch only: ABI files are not checked/maintained
|
|
-Doc/data/python*.abi
|
|
diff --git a/Include/bytesobject.h b/Include/bytesobject.h
|
|
index 4c4dc40..cd88bed 100644
|
|
--- a/Include/bytesobject.h
|
|
+++ b/Include/bytesobject.h
|
|
@@ -35,9 +35,9 @@ PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t);
|
|
PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *);
|
|
PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *);
|
|
PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list)
|
|
- Py_GCC_ATTRIBUTE((format(printf, 1, 0)));
|
|
+ Py_PRINTF(1, 0);
|
|
PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...)
|
|
- Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
|
|
+ Py_PRINTF(1, 2);
|
|
PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *);
|
|
PyAPI_FUNC(char *) PyBytes_AsString(PyObject *);
|
|
PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int);
|
|
diff --git a/Include/fileobject.h b/Include/fileobject.h
|
|
index 4c983e7..260e4c1 100644
|
|
--- a/Include/fileobject.h
|
|
+++ b/Include/fileobject.h
|
|
@@ -30,7 +30,7 @@ PyAPI_DATA(int) Py_UTF8Mode;
|
|
#endif
|
|
|
|
/* A routine to check if a file descriptor can be select()-ed. */
|
|
-#ifdef _MSC_VER
|
|
+#ifdef MS_WINDOWS
|
|
/* On Windows, any socket fd can be select()-ed, no matter how high */
|
|
#define _PyIsSelectable_fd(FD) (1)
|
|
#else
|
|
diff --git a/Include/internal/pycore_condvar.h b/Include/internal/pycore_condvar.h
|
|
index 981c962..ed9e6a7 100644
|
|
--- a/Include/internal/pycore_condvar.h
|
|
+++ b/Include/internal/pycore_condvar.h
|
|
@@ -5,6 +5,12 @@
|
|
# error "this header requires Py_BUILD_CORE define"
|
|
#endif
|
|
|
|
+#ifdef __MINGW32__
|
|
+# if !defined(HAVE_PTHREAD_H) || defined(NT_THREADS)
|
|
+# undef _POSIX_THREADS
|
|
+# endif
|
|
+#endif
|
|
+
|
|
#ifndef _POSIX_THREADS
|
|
/* This means pthreads are not implemented in libc headers, hence the macro
|
|
not present in unistd.h. But they still can be implemented as an external
|
|
@@ -39,6 +45,10 @@
|
|
/* include windows if it hasn't been done before */
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
+/* winpthreads are involved via windows header, so need undef _POSIX_THREADS after header include */
|
|
+#if defined(_POSIX_THREADS)
|
|
+#undef _POSIX_THREADS
|
|
+#endif
|
|
|
|
/* options */
|
|
/* non-emulated condition variables are provided for those that want
|
|
diff --git a/Include/iscygpty.h b/Include/iscygpty.h
|
|
new file mode 100755
|
|
index 0000000..82fd0af
|
|
--- /dev/null
|
|
+++ b/Include/iscygpty.h
|
|
@@ -0,0 +1,41 @@
|
|
+/*
|
|
+ * iscygpty.h -- part of ptycheck
|
|
+ * https://github.com/k-takata/ptycheck
|
|
+ *
|
|
+ * Copyright (c) 2015-2017 K.Takata
|
|
+ *
|
|
+ * You can redistribute it and/or modify it under the terms of either
|
|
+ * the MIT license (as described below) or the Vim license.
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
+ * a copy of this software and associated documentation files (the
|
|
+ * "Software"), to deal in the Software without restriction, including
|
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
+ * the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be
|
|
+ * included in all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+ */
|
|
+
|
|
+#ifndef _ISCYGPTY_H
|
|
+#define _ISCYGPTY_H
|
|
+
|
|
+#ifdef _WIN32
|
|
+int is_cygpty(int fd);
|
|
+int is_cygpty_used(void);
|
|
+#else
|
|
+#define is_cygpty(fd) 0
|
|
+#define is_cygpty_used() 0
|
|
+#endif
|
|
+
|
|
+#endif /* _ISCYGPTY_H */
|
|
diff --git a/Include/osdefs.h b/Include/osdefs.h
|
|
index 3243944..99d4977 100644
|
|
--- a/Include/osdefs.h
|
|
+++ b/Include/osdefs.h
|
|
@@ -10,7 +10,6 @@ extern "C" {
|
|
#ifdef MS_WINDOWS
|
|
#define SEP L'\\'
|
|
#define ALTSEP L'/'
|
|
-#define MAXPATHLEN 256
|
|
#define DELIM L';'
|
|
#endif
|
|
|
|
diff --git a/Include/py_curses.h b/Include/py_curses.h
|
|
index b2c7f1b..e6fc813 100644
|
|
--- a/Include/py_curses.h
|
|
+++ b/Include/py_curses.h
|
|
@@ -36,6 +36,13 @@
|
|
#include <curses.h>
|
|
#endif
|
|
|
|
+#if defined(__MINGW32__)
|
|
+#include <windows.h>
|
|
+#if !defined(_ISPAD)
|
|
+#define _ISPAD 0x10
|
|
+#endif
|
|
+#endif
|
|
+
|
|
#ifdef HAVE_NCURSES_H
|
|
/* configure was checking <curses.h>, but we will
|
|
use <ncurses.h>, which has some or all these features. */
|
|
diff --git a/Include/pyerrors.h b/Include/pyerrors.h
|
|
index 34e3de3..fb71fde 100644
|
|
--- a/Include/pyerrors.h
|
|
+++ b/Include/pyerrors.h
|
|
@@ -315,9 +315,9 @@ PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason(
|
|
);
|
|
|
|
PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...)
|
|
- Py_GCC_ATTRIBUTE((format(printf, 3, 4)));
|
|
+ Py_PRINTF(3, 4);
|
|
PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
|
|
- Py_GCC_ATTRIBUTE((format(printf, 3, 0)));
|
|
+ Py_PRINTF(3, 0);
|
|
|
|
#ifndef Py_LIMITED_API
|
|
# define Py_CPYTHON_ERRORS_H
|
|
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
|
|
index e4c3b09..21346ba 100644
|
|
--- a/Include/pylifecycle.h
|
|
+++ b/Include/pylifecycle.h
|
|
@@ -21,6 +21,15 @@ PyAPI_FUNC(int) Py_IsInitialized(void);
|
|
PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void);
|
|
PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *);
|
|
|
|
+PyAPI_FUNC(wchar_t) Py_GetAltSepW(const wchar_t *);
|
|
+PyAPI_FUNC(wchar_t) Py_GetSepW(const wchar_t *);
|
|
+PyAPI_FUNC(char) Py_GetSepA(const char *);
|
|
+
|
|
+PyAPI_FUNC(void) Py_NormalizeSepsW(wchar_t *);
|
|
+PyAPI_FUNC(void) Py_NormalizeSepsA(char *);
|
|
+
|
|
+PyAPI_FUNC(void) Py_NormalizeSepsPathcchW(wchar_t *);
|
|
+
|
|
|
|
/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
|
|
* exit functions.
|
|
diff --git a/Include/pyport.h b/Include/pyport.h
|
|
index 93250f4..b816c90 100644
|
|
--- a/Include/pyport.h
|
|
+++ b/Include/pyport.h
|
|
@@ -53,6 +53,21 @@
|
|
#endif
|
|
|
|
|
|
+#ifdef __MINGW32__
|
|
+/* Translate GCC[mingw*] platform specific defines to those
|
|
+ * used in python code.
|
|
+ */
|
|
+#if !defined(MS_WIN64) && defined(_WIN64)
|
|
+# define MS_WIN64
|
|
+#endif
|
|
+#if !defined(MS_WIN32) && defined(_WIN32)
|
|
+# define MS_WIN32
|
|
+#endif
|
|
+#if !defined(MS_WINDOWS) && defined(MS_WIN32)
|
|
+# define MS_WINDOWS
|
|
+#endif
|
|
+#endif /* __MINGW32__*/
|
|
+
|
|
/**************************************************************************
|
|
Symbols and macros to supply platform-independent interfaces to basic
|
|
C language & library operations whose spellings vary across platforms.
|
|
@@ -509,12 +524,12 @@ extern char * _getpty(int *, int, mode_t, int);
|
|
*/
|
|
|
|
/*
|
|
- All windows ports, except cygwin, are handled in PC/pyconfig.h.
|
|
+ Only MSVC windows ports is handled in PC/pyconfig.h.
|
|
|
|
- Cygwin is the only other autoconf platform requiring special
|
|
+ Cygwin and Mingw is the only other autoconf platform requiring special
|
|
linkage handling and it uses __declspec().
|
|
*/
|
|
-#if defined(__CYGWIN__)
|
|
+#if defined(__CYGWIN__) || defined(__MINGW32__)
|
|
# define HAVE_DECLSPEC_DLL
|
|
#endif
|
|
|
|
@@ -527,21 +542,23 @@ extern char * _getpty(int *, int, mode_t, int);
|
|
# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
|
|
# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
|
|
/* module init functions inside the core need no external linkage */
|
|
- /* except for Cygwin to handle embedding */
|
|
-# if defined(__CYGWIN__)
|
|
+ /* except for Cygwin/Mingw to handle embedding */
|
|
+# if defined(__CYGWIN__) || defined(__MINGW32__)
|
|
# define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
|
|
-# else /* __CYGWIN__ */
|
|
+# else /* __CYGWIN__ || __MINGW32__*/
|
|
# define PyMODINIT_FUNC PyObject*
|
|
-# endif /* __CYGWIN__ */
|
|
+# endif /* __CYGWIN__ || __MINGW32__*/
|
|
# else /* Py_BUILD_CORE */
|
|
/* Building an extension module, or an embedded situation */
|
|
/* public Python functions and data are imported */
|
|
/* Under Cygwin, auto-import functions to prevent compilation */
|
|
/* failures similar to those described at the bottom of 4.1: */
|
|
/* http://docs.python.org/extending/windows.html#a-cookbook-approach */
|
|
-# if !defined(__CYGWIN__)
|
|
+# if defined(__CYGWIN__) || defined(__MINGW32__)
|
|
+# define PyAPI_FUNC(RTYPE) RTYPE
|
|
+# else
|
|
# define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE
|
|
-# endif /* !__CYGWIN__ */
|
|
+# endif /* __CYGWIN__ || __MINGW32__*/
|
|
# define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE
|
|
/* module init functions outside the core must be exported */
|
|
# if defined(__cplusplus)
|
|
@@ -641,6 +658,12 @@ extern char * _getpty(int *, int, mode_t, int);
|
|
|
|
#define Py_VA_COPY va_copy
|
|
|
|
+#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__>= 4) || __GNUC__ > 4)
|
|
+# define Py_PRINTF(X,Y) Py_GCC_ATTRIBUTE((format(gnu_printf,X,Y)))
|
|
+#else
|
|
+# define Py_PRINTF(X,Y) Py_GCC_ATTRIBUTE((format(printf,X,Y)))
|
|
+#endif
|
|
+
|
|
/*
|
|
* Convenient macros to deal with endianness of the platform. WORDS_BIGENDIAN is
|
|
* detected by configure and defined in pyconfig.h. The code in pyconfig.h
|
|
diff --git a/Include/pythread.h b/Include/pythread.h
|
|
index a483290..9bf8bd6 100644
|
|
--- a/Include/pythread.h
|
|
+++ b/Include/pythread.h
|
|
@@ -7,6 +7,12 @@ typedef void *PyThread_type_lock;
|
|
extern "C" {
|
|
#endif
|
|
|
|
+#ifdef __MINGW32__
|
|
+# if !defined(HAVE_PTHREAD_H) || defined(NT_THREADS)
|
|
+# undef _POSIX_THREADS
|
|
+# endif
|
|
+#endif
|
|
+
|
|
/* Return status codes for Python lock acquisition. Chosen for maximum
|
|
* backwards compatibility, ie failure -> 0, success -> 1. */
|
|
typedef enum PyLockStatus {
|
|
diff --git a/Include/sysmodule.h b/Include/sysmodule.h
|
|
index b508711..d6767dc 100644
|
|
--- a/Include/sysmodule.h
|
|
+++ b/Include/sysmodule.h
|
|
@@ -15,9 +15,9 @@ Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int);
|
|
Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetPath(const wchar_t *);
|
|
|
|
PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
|
|
- Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
|
|
+ Py_PRINTF(1, 2);
|
|
PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...)
|
|
- Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
|
|
+ Py_PRINTF(1, 2);
|
|
PyAPI_FUNC(void) PySys_FormatStdout(const char *format, ...);
|
|
PyAPI_FUNC(void) PySys_FormatStderr(const char *format, ...);
|
|
|
|
diff --git a/Lib/compileall.py b/Lib/compileall.py
|
|
index a388931..069ea2b 100644
|
|
--- a/Lib/compileall.py
|
|
+++ b/Lib/compileall.py
|
|
@@ -38,6 +38,8 @@ def _walk_dir(dir, maxlevels, quiet=0):
|
|
if name == '__pycache__':
|
|
continue
|
|
fullname = os.path.join(dir, name)
|
|
+ if sys.platform == "win32" and sys.version.find("GCC") >= 0:
|
|
+ fullname = fullname.replace('\\','/')
|
|
if not os.path.isdir(fullname):
|
|
yield fullname
|
|
elif (maxlevels > 0 and name != os.curdir and name != os.pardir and
|
|
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
|
|
index 26135ad..76d583b 100644
|
|
--- a/Lib/ctypes/__init__.py
|
|
+++ b/Lib/ctypes/__init__.py
|
|
@@ -458,7 +458,9 @@ def LoadLibrary(self, name):
|
|
cdll = LibraryLoader(CDLL)
|
|
pydll = LibraryLoader(PyDLL)
|
|
|
|
-if _os.name == "nt":
|
|
+if _os.name == "nt" and _sys.version.find('GCC') >= 0:
|
|
+ pythonapi = PyDLL("libpython%d.%d%s.dll" % (_sys.version_info[:2] + (_sys.abiflags,)), None)
|
|
+elif _os.name == "nt":
|
|
pythonapi = PyDLL("python dll", None, _sys.dllhandle)
|
|
elif _sys.platform == "cygwin":
|
|
pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
|
|
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
|
|
index 0c2510e..48ddb3b 100644
|
|
--- a/Lib/ctypes/util.py
|
|
+++ b/Lib/ctypes/util.py
|
|
@@ -31,6 +31,12 @@ def _get_build_version():
|
|
# else we don't know what version of the compiler this is
|
|
return None
|
|
|
|
+ def find_msvcrt_mingw():
|
|
+ is_ucrt = 'clang' in sys.version.lower() or 'ucrt' in sys.version.lower()
|
|
+ if is_ucrt:
|
|
+ return None
|
|
+ return 'msvcrt.dll'
|
|
+
|
|
def find_msvcrt():
|
|
"""Return the name of the VC runtime dll"""
|
|
version = _get_build_version()
|
|
@@ -54,6 +60,9 @@ def find_msvcrt():
|
|
|
|
def find_library(name):
|
|
if name in ('c', 'm'):
|
|
+ import sysconfig
|
|
+ if sysconfig.get_platform().startswith('mingw'):
|
|
+ return find_msvcrt_mingw()
|
|
return find_msvcrt()
|
|
# See MSDN for the REAL search order.
|
|
for directory in os.environ['PATH'].split(os.pathsep):
|
|
diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py
|
|
index 4c47f2e..ab61a86 100644
|
|
--- a/Lib/distutils/ccompiler.py
|
|
+++ b/Lib/distutils/ccompiler.py
|
|
@@ -9,7 +9,7 @@
|
|
from distutils.file_util import move_file
|
|
from distutils.dir_util import mkpath
|
|
from distutils.dep_util import newer_group
|
|
-from distutils.util import split_quoted, execute
|
|
+from distutils.util import split_quoted, execute, get_platform
|
|
from distutils import log
|
|
|
|
class CCompiler:
|
|
@@ -948,6 +948,8 @@ def get_default_compiler(osname=None, platform=None):
|
|
osname = os.name
|
|
if platform is None:
|
|
platform = sys.platform
|
|
+ if get_platform().startswith('mingw'):
|
|
+ return 'mingw32'
|
|
for pattern, compiler in _default_compilers:
|
|
if re.match(pattern, platform) is not None or \
|
|
re.match(pattern, osname) is not None:
|
|
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
|
|
index f287b34..e87e3ad 100644
|
|
--- a/Lib/distutils/command/build_ext.py
|
|
+++ b/Lib/distutils/command/build_ext.py
|
|
@@ -186,7 +186,7 @@ def finalize_options(self):
|
|
# for extensions under windows use different directories
|
|
# for Release and Debug builds.
|
|
# also Python's library directory must be appended to library_dirs
|
|
- if os.name == 'nt':
|
|
+ if os.name == 'nt' and not self.plat_name.startswith(('mingw')):
|
|
# the 'libs' directory is for binary installs - we assume that
|
|
# must be the *native* platform. But we don't really support
|
|
# cross-compiling via a binary install anyway, so we let it go.
|
|
@@ -218,15 +218,16 @@ def finalize_options(self):
|
|
|
|
# For extensions under Cygwin, Python's library directory must be
|
|
# appended to library_dirs
|
|
- if sys.platform[:6] == 'cygwin':
|
|
- if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
|
|
+ if sys.platform[:6] == 'cygwin' or self.plat_name.startswith(('mingw')):
|
|
+ if not sysconfig.python_build:
|
|
# building third party extensions
|
|
+ config_dir_name = os.path.basename(sysconfig.get_config_var('LIBPL'))
|
|
self.library_dirs.append(os.path.join(sys.prefix, "lib",
|
|
"python" + get_python_version(),
|
|
- "config"))
|
|
+ config_dir_name))
|
|
else:
|
|
# building python standard extensions
|
|
- self.library_dirs.append('.')
|
|
+ self.library_dirs.append(sysconfig.project_base)
|
|
|
|
# For building extensions with a shared Python library,
|
|
# Python's library directory must be appended to library_dirs
|
|
@@ -237,7 +238,7 @@ def finalize_options(self):
|
|
self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
|
|
else:
|
|
# building python standard extensions
|
|
- self.library_dirs.append('.')
|
|
+ self.library_dirs.append(sysconfig.project_base)
|
|
|
|
# The argument parsing will result in self.define being a string, but
|
|
# it has to be a list of 2-tuples. All the preprocessor symbols
|
|
@@ -712,6 +713,20 @@ def get_libraries(self, ext):
|
|
# pyconfig.h that MSVC groks. The other Windows compilers all seem
|
|
# to need it mentioned explicitly, though, so that's what we do.
|
|
# Append '_d' to the python import library on debug builds.
|
|
+
|
|
+ # Use self.plat_name as it works even in case of
|
|
+ # cross-compilation (at least for mingw build).
|
|
+ if self.plat_name.startswith('mingw'):
|
|
+ from distutils import sysconfig
|
|
+ extra = []
|
|
+ for lib in (
|
|
+ sysconfig.get_config_var('BLDLIBRARY').split()
|
|
+ + sysconfig.get_config_var('SHLIBS').split()
|
|
+ ):
|
|
+ if lib.startswith('-l'):
|
|
+ extra.append(lib[2:])
|
|
+ return ext.libraries + extra
|
|
+
|
|
if sys.platform == "win32":
|
|
from distutils._msvccompiler import MSVCCompiler
|
|
if not isinstance(self.compiler, MSVCCompiler):
|
|
diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py
|
|
index 01d5331..25eb3d8 100644
|
|
--- a/Lib/distutils/command/install.py
|
|
+++ b/Lib/distutils/command/install.py
|
|
@@ -72,8 +72,8 @@
|
|
INSTALL_SCHEMES['nt_user'] = {
|
|
'purelib': '$usersite',
|
|
'platlib': '$usersite',
|
|
- 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name',
|
|
- 'scripts': '$userbase/Python$py_version_nodot/Scripts',
|
|
+ 'headers': '$userbase/include/python$py_version_short_plat$abiflags/$dist_name',
|
|
+ 'scripts': '$userbase/bin',
|
|
'data' : '$userbase',
|
|
}
|
|
|
|
@@ -81,7 +81,7 @@
|
|
'purelib': '$usersite',
|
|
'platlib': '$usersite',
|
|
'headers':
|
|
- '$userbase/include/python$py_version_short$abiflags/$dist_name',
|
|
+ '$userbase/include/python$py_version_short_plat$abiflags/$dist_name',
|
|
'scripts': '$userbase/bin',
|
|
'data' : '$userbase',
|
|
}
|
|
@@ -311,6 +311,7 @@ def finalize_options(self):
|
|
'py_version': py_version,
|
|
'py_version_short': '%d.%d' % sys.version_info[:2],
|
|
'py_version_nodot': '%d%d' % sys.version_info[:2],
|
|
+ '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]}',
|
|
'sys_prefix': prefix,
|
|
'prefix': prefix,
|
|
'sys_exec_prefix': exec_prefix,
|
|
@@ -363,7 +364,8 @@ def finalize_options(self):
|
|
|
|
# Convert directories from Unix /-separated syntax to the local
|
|
# convention.
|
|
- self.convert_paths('lib', 'purelib', 'platlib',
|
|
+ self.convert_paths('base', 'platbase',
|
|
+ 'lib', 'purelib', 'platlib',
|
|
'scripts', 'data', 'headers')
|
|
if HAS_USER_SITE:
|
|
self.convert_paths('userbase', 'usersite')
|
|
diff --git a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py
|
|
index 66c12dd..d8c8428 100644
|
|
--- a/Lib/distutils/cygwinccompiler.py
|
|
+++ b/Lib/distutils/cygwinccompiler.py
|
|
@@ -44,12 +44,13 @@
|
|
# (ld supports -shared)
|
|
# * mingw gcc 3.2/ld 2.13 works
|
|
# (ld supports -shared)
|
|
+# * llvm-mingw with Clang 11 works
|
|
+# (lld supports -shared)
|
|
|
|
import os
|
|
import sys
|
|
import copy
|
|
-from subprocess import Popen, PIPE, check_output
|
|
-import re
|
|
+import shlex
|
|
|
|
from distutils.unixccompiler import UnixCCompiler
|
|
from distutils.file_util import write_file
|
|
@@ -57,6 +58,7 @@
|
|
CompileError, UnknownFileError)
|
|
from distutils.version import LooseVersion
|
|
from distutils.spawn import find_executable
|
|
+from subprocess import Popen, check_output
|
|
|
|
def get_msvcr():
|
|
"""Include the appropriate MSVC runtime library if Python was built
|
|
@@ -91,6 +93,7 @@ class CygwinCCompiler(UnixCCompiler):
|
|
obj_extension = ".o"
|
|
static_lib_extension = ".a"
|
|
shared_lib_extension = ".dll"
|
|
+ dylib_lib_extension = ".dll.a"
|
|
static_lib_format = "lib%s%s"
|
|
shared_lib_format = "%s%s"
|
|
exe_extension = ".exe"
|
|
@@ -109,50 +112,28 @@ def __init__(self, verbose=0, dry_run=0, force=0):
|
|
"Compiling may fail because of undefined preprocessor macros."
|
|
% details)
|
|
|
|
- self.gcc_version, self.ld_version, self.dllwrap_version = \
|
|
- get_versions()
|
|
- self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" %
|
|
- (self.gcc_version,
|
|
- self.ld_version,
|
|
- self.dllwrap_version) )
|
|
-
|
|
- # ld_version >= "2.10.90" and < "2.13" should also be able to use
|
|
- # gcc -mdll instead of dllwrap
|
|
- # Older dllwraps had own version numbers, newer ones use the
|
|
- # same as the rest of binutils ( also ld )
|
|
- # dllwrap 2.10.90 is buggy
|
|
- if self.ld_version >= "2.10.90":
|
|
- self.linker_dll = "gcc"
|
|
- else:
|
|
- self.linker_dll = "dllwrap"
|
|
+ self.cc = os.environ.get('CC', 'gcc')
|
|
+ self.cxx = os.environ.get('CXX', 'g++')
|
|
|
|
- # ld_version >= "2.13" support -shared so use it instead of
|
|
- # -mdll -static
|
|
- if self.ld_version >= "2.13":
|
|
- shared_option = "-shared"
|
|
- else:
|
|
- shared_option = "-mdll -static"
|
|
-
|
|
- # Hard-code GCC because that's what this is all about.
|
|
- # XXX optimization, warnings etc. should be customizable.
|
|
- self.set_executables(compiler='gcc -mcygwin -O -Wall',
|
|
- compiler_so='gcc -mcygwin -mdll -O -Wall',
|
|
- compiler_cxx='g++ -mcygwin -O -Wall',
|
|
- linker_exe='gcc -mcygwin',
|
|
+ # Older numpy dependend on this existing to check for ancient
|
|
+ # gcc versions. This doesn't make much sense with clang etc so
|
|
+ # just hardcode to something recent.
|
|
+ # https://github.com/numpy/numpy/pull/20333
|
|
+ self.gcc_version = LooseVersion("11.2.0")
|
|
+
|
|
+ self.linker_dll = self.cc
|
|
+ shared_option = "-shared"
|
|
+
|
|
+ self.set_executables(compiler='%s -mcygwin -O -Wall' % self.cc,
|
|
+ compiler_so='%s -mcygwin -mdll -O -Wall' % self.cc,
|
|
+ compiler_cxx='%s -mcygwin -O -Wall' % self.cxx,
|
|
+ linker_exe='%s -mcygwin' % self.cc,
|
|
linker_so=('%s -mcygwin %s' %
|
|
(self.linker_dll, shared_option)))
|
|
|
|
- # cygwin and mingw32 need different sets of libraries
|
|
- if self.gcc_version == "2.91.57":
|
|
- # cygwin shouldn't need msvcrt, but without the dlls will crash
|
|
- # (gcc version 2.91.57) -- perhaps something about initialization
|
|
- self.dll_libraries=["msvcrt"]
|
|
- self.warn(
|
|
- "Consider upgrading to a newer version of gcc")
|
|
- else:
|
|
- # Include the appropriate MSVC runtime library if Python was built
|
|
- # with MSVC 7.0 or later.
|
|
- self.dll_libraries = get_msvcr()
|
|
+ # Include the appropriate MSVC runtime library if Python was built
|
|
+ # with MSVC 7.0 or later.
|
|
+ self.dll_libraries = get_msvcr()
|
|
|
|
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
|
|
"""Compiles the source by spawning GCC and windres if needed."""
|
|
@@ -162,6 +143,28 @@ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
|
|
self.spawn(["windres", "-i", src, "-o", obj])
|
|
except DistutilsExecError as msg:
|
|
raise CompileError(msg)
|
|
+ elif ext == '.mc':
|
|
+ # Adapted from msvc9compiler:
|
|
+ #
|
|
+ # Compile .MC to .RC file to .RES file.
|
|
+ # * '-h dir' specifies the directory for the generated include file
|
|
+ # * '-r dir' specifies the target directory of the generated RC file and the binary message resource it includes
|
|
+ #
|
|
+ # For now (since there are no options to change this),
|
|
+ # we use the source-directory for the include file and
|
|
+ # the build directory for the RC file and message
|
|
+ # resources. This works at least for win32all.
|
|
+ h_dir = os.path.dirname(src)
|
|
+ rc_dir = os.path.dirname(obj)
|
|
+ try:
|
|
+ # first compile .MC to .RC and .H file
|
|
+ self.spawn(['windmc'] + ['-h', h_dir, '-r', rc_dir] + [src])
|
|
+ base, _ = os.path.splitext(os.path.basename(src))
|
|
+ rc_file = os.path.join(rc_dir, base + '.rc')
|
|
+ # then compile .RC to .RES file
|
|
+ self.spawn(['windres', '-i', rc_file, '-o', obj])
|
|
+ except DistutilsExecError as msg:
|
|
+ raise CompileError(msg)
|
|
else: # for other files use the C-compiler
|
|
try:
|
|
self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
|
|
@@ -214,28 +217,21 @@ def link(self, target_desc, objects, output_filename, output_dir=None,
|
|
|
|
# next add options for def-file and to creating import libraries
|
|
|
|
- # dllwrap uses different options than gcc/ld
|
|
- if self.linker_dll == "dllwrap":
|
|
- extra_preargs.extend(["--output-lib", lib_file])
|
|
- # for dllwrap we have to use a special option
|
|
- extra_preargs.extend(["--def", def_file])
|
|
- # we use gcc/ld here and can be sure ld is >= 2.9.10
|
|
- else:
|
|
- # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
|
|
- #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
|
|
- # for gcc/ld the def-file is specified as any object files
|
|
- objects.append(def_file)
|
|
+ # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
|
|
+ #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
|
|
+ # for gcc/ld the def-file is specified as any object files
|
|
+ objects.append(def_file)
|
|
|
|
#end: if ((export_symbols is not None) and
|
|
# (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
|
|
|
|
# who wants symbols and a many times larger output file
|
|
# should explicitly switch the debug mode on
|
|
- # otherwise we let dllwrap/ld strip the output file
|
|
+ # otherwise we let ld strip the output file
|
|
# (On my machine: 10KiB < stripped_file < ??100KiB
|
|
# unstripped_file = stripped_file + XXX KiB
|
|
# ( XXX=254 for a typical python extension))
|
|
- if not debug:
|
|
+ if not debug and not hasattr(sys, 'gettotalrefcount'):
|
|
extra_preargs.append("-s")
|
|
|
|
UnixCCompiler.link(self, target_desc, objects, output_filename,
|
|
@@ -253,11 +249,16 @@ def object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
|
|
output_dir = ''
|
|
obj_names = []
|
|
for src_name in source_filenames:
|
|
- # use normcase to make sure '.rc' is really '.rc' and not '.RC'
|
|
- base, ext = os.path.splitext(os.path.normcase(src_name))
|
|
- if ext not in (self.src_extensions + ['.rc','.res']):
|
|
+ base, ext = os.path.splitext(src_name)
|
|
+ # use 'normcase' only for resource suffixes
|
|
+ ext_normcase = os.path.normcase(ext)
|
|
+ if ext_normcase in ['.rc', '.res', '.mc']:
|
|
+ ext = ext_normcase
|
|
+ if ext not in (self.src_extensions + ['.rc', '.res', '.mc']):
|
|
raise UnknownFileError("unknown file type '%s' (from '%s')" % \
|
|
(ext, src_name))
|
|
+ base = os.path.splitdrive(base)[1] # Chop off the drive
|
|
+ base = base[os.path.isabs(base):] # If abs, chop off leading /
|
|
if strip_dir:
|
|
base = os.path.basename (base)
|
|
if ext in ('.res', '.rc'):
|
|
@@ -279,31 +280,18 @@ def __init__(self, verbose=0, dry_run=0, force=0):
|
|
|
|
CygwinCCompiler.__init__ (self, verbose, dry_run, force)
|
|
|
|
- # ld_version >= "2.13" support -shared so use it instead of
|
|
- # -mdll -static
|
|
- if self.ld_version >= "2.13":
|
|
- shared_option = "-shared"
|
|
- else:
|
|
- shared_option = "-mdll -static"
|
|
-
|
|
- # A real mingw32 doesn't need to specify a different entry point,
|
|
- # but cygwin 2.91.57 in no-cygwin-mode needs it.
|
|
- if self.gcc_version <= "2.91.57":
|
|
- entry_point = '--entry _DllMain@12'
|
|
- else:
|
|
- entry_point = ''
|
|
+ shared_option = "-shared"
|
|
|
|
- if is_cygwingcc():
|
|
+ if is_cygwincc(self.cc):
|
|
raise CCompilerError(
|
|
'Cygwin gcc cannot be used with --compiler=mingw32')
|
|
|
|
- self.set_executables(compiler='gcc -O -Wall',
|
|
- compiler_so='gcc -mdll -O -Wall',
|
|
- compiler_cxx='g++ -O -Wall',
|
|
- linker_exe='gcc',
|
|
- linker_so='%s %s %s'
|
|
- % (self.linker_dll, shared_option,
|
|
- entry_point))
|
|
+ self.set_executables(compiler='%s -O2 -Wall' % self.cc,
|
|
+ compiler_so='%s -mdll -O2 -Wall' % self.cc,
|
|
+ compiler_cxx='%s -O2 -Wall' % self.cxx,
|
|
+ linker_exe='%s' % self.cc,
|
|
+ linker_so='%s %s'
|
|
+ % (self.linker_dll, shared_option))
|
|
# Maybe we should also append -mthreads, but then the finished
|
|
# dlls need another dll (mingwm10.dll see Mingw32 docs)
|
|
# (-mthreads: Support thread-safe exception handling on `Mingw32')
|
|
@@ -313,7 +301,7 @@ def __init__(self, verbose=0, dry_run=0, force=0):
|
|
|
|
# Include the appropriate MSVC runtime library if Python was built
|
|
# with MSVC 7.0 or later.
|
|
- self.dll_libraries = get_msvcr()
|
|
+ self.dll_libraries = get_msvcr() or []
|
|
|
|
# Because these compilers aren't configured in Python's pyconfig.h file by
|
|
# default, we should at least warn the user if he is using an unmodified
|
|
@@ -351,6 +339,10 @@ def check_config_h():
|
|
if "GCC" in sys.version:
|
|
return CONFIG_H_OK, "sys.version mentions 'GCC'"
|
|
|
|
+ # Clang would also work
|
|
+ if "Clang" in sys.version:
|
|
+ return CONFIG_H_OK, "sys.version mentions 'Clang'"
|
|
+
|
|
# let's see if __GNUC__ is mentioned in python.h
|
|
fn = sysconfig.get_config_h_filename()
|
|
try:
|
|
@@ -366,38 +358,8 @@ def check_config_h():
|
|
return (CONFIG_H_UNCERTAIN,
|
|
"couldn't read '%s': %s" % (fn, exc.strerror))
|
|
|
|
-RE_VERSION = re.compile(br'(\d+\.\d+(\.\d+)*)')
|
|
-
|
|
-def _find_exe_version(cmd):
|
|
- """Find the version of an executable by running `cmd` in the shell.
|
|
-
|
|
- If the command is not found, or the output does not match
|
|
- `RE_VERSION`, returns None.
|
|
- """
|
|
- executable = cmd.split()[0]
|
|
- if find_executable(executable) is None:
|
|
- return None
|
|
- out = Popen(cmd, shell=True, stdout=PIPE).stdout
|
|
- try:
|
|
- out_string = out.read()
|
|
- finally:
|
|
- out.close()
|
|
- result = RE_VERSION.search(out_string)
|
|
- if result is None:
|
|
- return None
|
|
- # LooseVersion works with strings
|
|
- # so we need to decode our bytes
|
|
- return LooseVersion(result.group(1).decode())
|
|
-
|
|
-def get_versions():
|
|
- """ Try to find out the versions of gcc, ld and dllwrap.
|
|
-
|
|
- If not possible it returns None for it.
|
|
- """
|
|
- commands = ['gcc -dumpversion', 'ld -v', 'dllwrap --version']
|
|
- return tuple([_find_exe_version(cmd) for cmd in commands])
|
|
|
|
-def is_cygwingcc():
|
|
- '''Try to determine if the gcc that would be used is from cygwin.'''
|
|
- out_string = check_output(['gcc', '-dumpmachine'])
|
|
+def is_cygwincc(cc):
|
|
+ '''Try to determine if the compiler that would be used is from cygwin.'''
|
|
+ out_string = check_output(shlex.split(cc) + ['-dumpmachine'])
|
|
return out_string.strip().endswith(b'cygwin')
|
|
diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py
|
|
index a7976fb..c341679 100644
|
|
--- a/Lib/distutils/msvc9compiler.py
|
|
+++ b/Lib/distutils/msvc9compiler.py
|
|
@@ -291,8 +291,6 @@ def query_vcvarsall(version, arch="x86"):
|
|
|
|
# More globals
|
|
VERSION = get_build_version()
|
|
-if VERSION < 8.0:
|
|
- raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
|
|
# MACROS = MacroExpander(VERSION)
|
|
|
|
class MSVCCompiler(CCompiler) :
|
|
@@ -327,6 +325,8 @@ class MSVCCompiler(CCompiler) :
|
|
|
|
def __init__(self, verbose=0, dry_run=0, force=0):
|
|
CCompiler.__init__ (self, verbose, dry_run, force)
|
|
+ if VERSION < 8.0:
|
|
+ raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
|
|
self.__version = VERSION
|
|
self.__root = r"Software\Microsoft\VisualStudio"
|
|
# self.__macros = MACROS
|
|
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
|
|
index 03b8558..024c15c 100644
|
|
--- a/Lib/distutils/sysconfig.py
|
|
+++ b/Lib/distutils/sysconfig.py
|
|
@@ -64,8 +64,23 @@ def parse_config_h(fp, g=None):
|
|
|
|
_python_build = partial(is_python_build, check_home=True)
|
|
_init_posix = partial(sysconfig_init_posix, _config_vars)
|
|
-_init_nt = partial(_init_non_posix, _config_vars)
|
|
|
|
+def _posix_build():
|
|
+ # GCC[mingw*] use posix build system
|
|
+ # Check for cross builds explicitly
|
|
+ host_platform = os.environ.get("_PYTHON_HOST_PLATFORM")
|
|
+ if host_platform:
|
|
+ if host_platform.startswith('mingw'):
|
|
+ return True
|
|
+ return os.name == 'posix' or \
|
|
+ (os.name == "nt" and 'GCC' in sys.version)
|
|
+posix_build = _posix_build()
|
|
+
|
|
+
|
|
+def _init_nt():
|
|
+ if posix_build:
|
|
+ return _init_posix(_config_vars)
|
|
+ return _init_non_posix(_config_vars)
|
|
|
|
# Similar function is also implemented in sysconfig as _parse_makefile
|
|
# but without the parsing capabilities of distutils.text_file.TextFile.
|
|
@@ -196,7 +211,23 @@ def customize_compiler(compiler):
|
|
Mainly needed on Unix, so we can plug in the information that
|
|
varies across Unices and is stored in Python's Makefile.
|
|
"""
|
|
- if compiler.compiler_type == "unix":
|
|
+ global _config_vars
|
|
+ if compiler.compiler_type in ["cygwin", "mingw32"]:
|
|
+ # Note that cygwin use posix build and 'unix' compiler.
|
|
+ # If build is not based on posix then we must predefine
|
|
+ # some environment variables corresponding to posix
|
|
+ # build rules and defaults.
|
|
+ if not 'GCC' in sys.version:
|
|
+ _config_vars['CC'] = "gcc"
|
|
+ _config_vars['CXX'] = "g++"
|
|
+ _config_vars['OPT'] = "-fwrapv -O3 -Wall -Wstrict-prototypes"
|
|
+ _config_vars['CFLAGS'] = ""
|
|
+ _config_vars['CCSHARED'] = ""
|
|
+ _config_vars['LDSHARED'] = "gcc -shared -Wl,--enable-auto-image-base"
|
|
+ _config_vars['AR'] = "ar"
|
|
+ _config_vars['ARFLAGS'] = "rc"
|
|
+
|
|
+ if compiler.compiler_type in ["unix", "cygwin", "mingw32"]:
|
|
if sys.platform == "darwin":
|
|
# Perform first-time customization of compiler-related
|
|
# config vars on OS X now that we know we need a compiler.
|
|
@@ -274,7 +305,7 @@ def get_python_inc(plat_specific=0, prefix=None):
|
|
"""
|
|
if prefix is None:
|
|
prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
|
|
- if os.name == "posix":
|
|
+ if posix_build:
|
|
if python_build:
|
|
# Assume the executable is in the build directory. The
|
|
# pyconfig.h file should be in the same directory. Since
|
|
@@ -321,7 +352,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
|
|
else:
|
|
prefix = plat_specific and EXEC_PREFIX or PREFIX
|
|
|
|
- if os.name == "posix":
|
|
+ if posix_build:
|
|
if plat_specific or standard_lib:
|
|
# Platform-specific modules (any module from a non-pure-Python
|
|
# module distribution) or standard Python library modules.
|
|
diff --git a/Lib/distutils/tests/test_cygwinccompiler.py b/Lib/distutils/tests/test_cygwinccompiler.py
|
|
index 0912ffd..a93c174 100644
|
|
--- a/Lib/distutils/tests/test_cygwinccompiler.py
|
|
+++ b/Lib/distutils/tests/test_cygwinccompiler.py
|
|
@@ -8,7 +8,7 @@
|
|
from distutils import cygwinccompiler
|
|
from distutils.cygwinccompiler import (check_config_h,
|
|
CONFIG_H_OK, CONFIG_H_NOTOK,
|
|
- CONFIG_H_UNCERTAIN, get_versions,
|
|
+ CONFIG_H_UNCERTAIN,
|
|
get_msvcr)
|
|
from distutils.tests import support
|
|
|
|
@@ -81,40 +81,6 @@ def test_check_config_h(self):
|
|
self.write_file(self.python_h, 'xxx __GNUC__ xxx')
|
|
self.assertEqual(check_config_h()[0], CONFIG_H_OK)
|
|
|
|
- def test_get_versions(self):
|
|
-
|
|
- # get_versions calls distutils.spawn.find_executable on
|
|
- # 'gcc', 'ld' and 'dllwrap'
|
|
- self.assertEqual(get_versions(), (None, None, None))
|
|
-
|
|
- # Let's fake we have 'gcc' and it returns '3.4.5'
|
|
- self._exes['gcc'] = b'gcc (GCC) 3.4.5 (mingw special)\nFSF'
|
|
- res = get_versions()
|
|
- self.assertEqual(str(res[0]), '3.4.5')
|
|
-
|
|
- # and let's see what happens when the version
|
|
- # doesn't match the regular expression
|
|
- # (\d+\.\d+(\.\d+)*)
|
|
- self._exes['gcc'] = b'very strange output'
|
|
- res = get_versions()
|
|
- self.assertEqual(res[0], None)
|
|
-
|
|
- # same thing for ld
|
|
- self._exes['ld'] = b'GNU ld version 2.17.50 20060824'
|
|
- res = get_versions()
|
|
- self.assertEqual(str(res[1]), '2.17.50')
|
|
- self._exes['ld'] = b'@(#)PROGRAM:ld PROJECT:ld64-77'
|
|
- res = get_versions()
|
|
- self.assertEqual(res[1], None)
|
|
-
|
|
- # and dllwrap
|
|
- self._exes['dllwrap'] = b'GNU dllwrap 2.17.50 20060824\nFSF'
|
|
- res = get_versions()
|
|
- self.assertEqual(str(res[2]), '2.17.50')
|
|
- self._exes['dllwrap'] = b'Cheese Wrap'
|
|
- res = get_versions()
|
|
- self.assertEqual(res[2], None)
|
|
-
|
|
def test_get_msvcr(self):
|
|
|
|
# none
|
|
diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py
|
|
index d00c489..76a7d82 100644
|
|
--- a/Lib/distutils/unixccompiler.py
|
|
+++ b/Lib/distutils/unixccompiler.py
|
|
@@ -249,9 +249,13 @@ def runtime_library_dir_option(self, dir):
|
|
# -Wl whenever gcc was used in the past it is probably
|
|
# safest to keep doing so.
|
|
if sysconfig.get_config_var("GNULD") == "yes":
|
|
- # GNU ld needs an extra option to get a RUNPATH
|
|
+ # GNU ELF ld needs an extra option to get a RUNPATH
|
|
# instead of just an RPATH.
|
|
- return "-Wl,--enable-new-dtags,-R" + dir
|
|
+ if sys.platform in ["win32", "cygwin"] or \
|
|
+ "mingw" in compiler:
|
|
+ return []
|
|
+ else:
|
|
+ return "-Wl,--enable-new-dtags,-R" + dir
|
|
else:
|
|
return "-Wl,-R" + dir
|
|
else:
|
|
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
|
|
index 2ce5c5b..81626b3 100644
|
|
--- a/Lib/distutils/util.py
|
|
+++ b/Lib/distutils/util.py
|
|
@@ -37,6 +37,22 @@ def get_host_platform():
|
|
|
|
"""
|
|
if os.name == 'nt':
|
|
+ if 'gcc' in sys.version.lower():
|
|
+ if 'ucrt' in sys.version.lower():
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64_ucrt'
|
|
+ return 'mingw_i686_ucrt'
|
|
+ if 'clang' in sys.version.lower():
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64_clang'
|
|
+ if 'arm64' in sys.version.lower():
|
|
+ return 'mingw_aarch64'
|
|
+ if 'arm' in sys.version.lower():
|
|
+ return 'mingw_armv7'
|
|
+ return 'mingw_i686_clang'
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64'
|
|
+ return 'mingw_i686'
|
|
if 'amd64' in sys.version.lower():
|
|
return 'win-amd64'
|
|
if '(arm)' in sys.version.lower():
|
|
@@ -130,6 +146,13 @@ def convert_path (pathname):
|
|
paths.remove('.')
|
|
if not paths:
|
|
return os.curdir
|
|
+ # On Windows, if paths is ['C:','folder','subfolder'] then
|
|
+ # os.path.join(*paths) will return 'C:folder\subfolder' which
|
|
+ # is thus relative to the CWD on that drive. So we work around
|
|
+ # this by adding a \ to path[0]
|
|
+ if (len(paths) > 0 and paths[0].endswith(':') and
|
|
+ sys.platform == "win32" and sys.version.find("GCC") >= 0):
|
|
+ paths[0] += '\\'
|
|
return os.path.join(*paths)
|
|
|
|
# convert_path ()
|
|
@@ -140,6 +163,10 @@ def change_root (new_root, pathname):
|
|
relative, this is equivalent to "os.path.join(new_root,pathname)".
|
|
Otherwise, it requires making 'pathname' relative and then joining the
|
|
two, which is tricky on DOS/Windows and Mac OS.
|
|
+
|
|
+ If on Windows or OS/2 and both new_root and pathname are on different
|
|
+ drives, raises DistutilsChangeRootError as this is nonsensical,
|
|
+ otherwise use drive which can be in either of new_root or pathname.
|
|
"""
|
|
if os.name == 'posix':
|
|
if not os.path.isabs(pathname):
|
|
@@ -149,9 +176,20 @@ def change_root (new_root, pathname):
|
|
|
|
elif os.name == 'nt':
|
|
(drive, path) = os.path.splitdrive(pathname)
|
|
- if path[0] == '\\':
|
|
+ if path[0] == os.sep:
|
|
path = path[1:]
|
|
- return os.path.join(new_root, path)
|
|
+ (drive_r, path_r) = os.path.splitdrive(new_root)
|
|
+ if path_r and path_r[0] == os.sep:
|
|
+ path_r = path_r[1:]
|
|
+ drive_used = ''
|
|
+ if len(drive) == 2 and len(drive_r) == 2 and drive != drive_r:
|
|
+ raise DistutilsChangeRootError("root and pathname not on same drive (%s, %s)"
|
|
+ % (drive_r,drive))
|
|
+ elif len(drive_r) == 2:
|
|
+ drive_used = drive_r+os.sep
|
|
+ elif len(drive) == 2:
|
|
+ drive_used = drive+os.sep
|
|
+ return os.path.join(drive_used+path_r, path)
|
|
|
|
else:
|
|
raise DistutilsPlatformError("nothing known about platform '%s'" % os.name)
|
|
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
|
|
index f603a89..7693d05 100644
|
|
--- a/Lib/importlib/_bootstrap_external.py
|
|
+++ b/Lib/importlib/_bootstrap_external.py
|
|
@@ -42,6 +42,10 @@
|
|
path_separators = ['\\', '/']
|
|
else:
|
|
path_separators = ['/']
|
|
+
|
|
+if _os.environ.get('MSYSTEM', ''):
|
|
+ path_separators = path_separators[::-1]
|
|
+
|
|
# Assumption made in _path_join()
|
|
assert all(len(sep) == 1 for sep in path_separators)
|
|
path_sep = path_separators[0]
|
|
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
|
|
index 0444b0f..0bc5956 100644
|
|
--- a/Lib/ntpath.py
|
|
+++ b/Lib/ntpath.py
|
|
@@ -11,9 +11,7 @@
|
|
curdir = '.'
|
|
pardir = '..'
|
|
extsep = '.'
|
|
-sep = '\\'
|
|
pathsep = ';'
|
|
-altsep = '/'
|
|
defpath = '.;C:\\bin'
|
|
devnull = 'nul'
|
|
|
|
@@ -23,6 +21,14 @@
|
|
import genericpath
|
|
from genericpath import *
|
|
|
|
+if sys.platform == "win32" and os.environ.get("MSYSTEM", ""):
|
|
+ sep = '/'
|
|
+ altsep = '\\'
|
|
+else:
|
|
+ sep = '\\'
|
|
+ altsep = '/'
|
|
+bsep = str.encode(sep)
|
|
+baltsep = str.encode(altsep)
|
|
|
|
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
|
"basename","dirname","commonprefix","getsize","getmtime",
|
|
@@ -34,9 +40,33 @@
|
|
|
|
def _get_bothseps(path):
|
|
if isinstance(path, bytes):
|
|
- return b'\\/'
|
|
+ return bsep+baltsep
|
|
+ else:
|
|
+ return sep+altsep
|
|
+
|
|
+def _get_sep(path):
|
|
+ if isinstance(path, bytes):
|
|
+ return bsep
|
|
+ else:
|
|
+ return sep
|
|
+
|
|
+def _get_altsep(path):
|
|
+ if isinstance(path, bytes):
|
|
+ return baltsep
|
|
+ else:
|
|
+ return altsep
|
|
+
|
|
+def _get_colon(path):
|
|
+ if isinstance(path, bytes):
|
|
+ return b':'
|
|
+ else:
|
|
+ return ':'
|
|
+
|
|
+def _get_unc_prefix(path):
|
|
+ if isinstance(path, bytes):
|
|
+ return b'\\\\?\\UNC\\'
|
|
else:
|
|
- return '\\/'
|
|
+ return '\\\\?\\UNC\\'
|
|
|
|
# Normalize the case of a pathname and map slashes to backslashes.
|
|
# Other normalizations (such as optimizing '../' away) are not done
|
|
@@ -58,14 +88,14 @@ def normcase(s):
|
|
return s
|
|
if isinstance(s, bytes):
|
|
encoding = sys.getfilesystemencoding()
|
|
- s = s.decode(encoding, 'surrogateescape').replace('/', '\\')
|
|
+ s = s.decode(encoding, 'surrogateescape').replace(altsep, sep)
|
|
s = _LCMapStringEx(_LOCALE_NAME_INVARIANT,
|
|
_LCMAP_LOWERCASE, s)
|
|
return s.encode(encoding, 'surrogateescape')
|
|
else:
|
|
return _LCMapStringEx(_LOCALE_NAME_INVARIANT,
|
|
_LCMAP_LOWERCASE,
|
|
- s.replace('/', '\\'))
|
|
+ s.replace(altsep, sep))
|
|
except ImportError:
|
|
def normcase(s):
|
|
"""Normalize case of pathname.
|
|
@@ -74,8 +104,8 @@ def normcase(s):
|
|
"""
|
|
s = os.fspath(s)
|
|
if isinstance(s, bytes):
|
|
- return os.fsencode(os.fsdecode(s).replace('/', '\\').lower())
|
|
- return s.replace('/', '\\').lower()
|
|
+ return os.fsencode(os.fsdecode(s).replace(altsep, sep).lower())
|
|
+ return s.replace(altsep, sep).lower()
|
|
|
|
|
|
# Return whether a path is absolute.
|
|
@@ -87,14 +117,9 @@ def normcase(s):
|
|
def isabs(s):
|
|
"""Test whether a path is absolute"""
|
|
s = os.fspath(s)
|
|
- if isinstance(s, bytes):
|
|
- sep = b'\\'
|
|
- altsep = b'/'
|
|
- colon_sep = b':\\'
|
|
- else:
|
|
- sep = '\\'
|
|
- altsep = '/'
|
|
- colon_sep = ':\\'
|
|
+ sep = _get_sep(s)
|
|
+ altsep = _get_altsep(s)
|
|
+ colon_sep = _get_colon(s) + sep
|
|
s = s[:3].replace(altsep, sep)
|
|
# Absolute: UNC, device, and paths with a drive and root.
|
|
# LEGACY BUG: isabs("/x") should be false since the path has no drive.
|
|
@@ -106,14 +131,9 @@ def isabs(s):
|
|
# Join two (or more) paths.
|
|
def join(path, *paths):
|
|
path = os.fspath(path)
|
|
- if isinstance(path, bytes):
|
|
- sep = b'\\'
|
|
- seps = b'\\/'
|
|
- colon = b':'
|
|
- else:
|
|
- sep = '\\'
|
|
- seps = '\\/'
|
|
- colon = ':'
|
|
+ sep = _get_sep(path)
|
|
+ seps = _get_bothseps(path)
|
|
+ colon = _get_colon(path)
|
|
try:
|
|
if not paths:
|
|
path[:0] + sep #23780: Ensure compatible data type even if p is null.
|
|
@@ -172,16 +192,10 @@ def splitdrive(p):
|
|
"""
|
|
p = os.fspath(p)
|
|
if len(p) >= 2:
|
|
- if isinstance(p, bytes):
|
|
- sep = b'\\'
|
|
- altsep = b'/'
|
|
- colon = b':'
|
|
- unc_prefix = b'\\\\?\\UNC\\'
|
|
- else:
|
|
- sep = '\\'
|
|
- altsep = '/'
|
|
- colon = ':'
|
|
- unc_prefix = '\\\\?\\UNC\\'
|
|
+ sep = _get_sep(p)
|
|
+ altsep = _get_altsep(p)
|
|
+ colon = _get_colon(p)
|
|
+ unc_prefix = _get_unc_prefix(p)
|
|
normp = p.replace(altsep, sep)
|
|
if normp[0:2] == sep * 2:
|
|
# UNC drives, e.g. \\server\share or \\?\UNC\server\share
|
|
@@ -231,9 +245,9 @@ def split(p):
|
|
def splitext(p):
|
|
p = os.fspath(p)
|
|
if isinstance(p, bytes):
|
|
- return genericpath._splitext(p, b'\\', b'/', b'.')
|
|
+ return genericpath._splitext(p, bsep, baltsep, b'.')
|
|
else:
|
|
- return genericpath._splitext(p, '\\', '/', '.')
|
|
+ return genericpath._splitext(p, sep, altsep, '.')
|
|
splitext.__doc__ = genericpath._splitext.__doc__
|
|
|
|
|
|
@@ -334,7 +348,7 @@ def expanduser(path):
|
|
if 'USERPROFILE' in os.environ:
|
|
userhome = os.environ['USERPROFILE']
|
|
elif not 'HOMEPATH' in os.environ:
|
|
- return path
|
|
+ return os.path.normpath(path)
|
|
else:
|
|
try:
|
|
drive = os.environ['HOMEDRIVE']
|
|
@@ -361,7 +375,7 @@ def expanduser(path):
|
|
if isinstance(path, bytes):
|
|
userhome = os.fsencode(userhome)
|
|
|
|
- return userhome + path[i:]
|
|
+ return os.path.normpath(userhome) + path[i:]
|
|
|
|
|
|
# Expand paths containing shell variable substitutions.
|
|
@@ -496,14 +510,12 @@ def expandvars(path):
|
|
def normpath(path):
|
|
"""Normalize path, eliminating double slashes, etc."""
|
|
path = os.fspath(path)
|
|
+ sep = _get_sep(path)
|
|
+ altsep = _get_altsep(path)
|
|
if isinstance(path, bytes):
|
|
- sep = b'\\'
|
|
- altsep = b'/'
|
|
curdir = b'.'
|
|
pardir = b'..'
|
|
else:
|
|
- sep = '\\'
|
|
- altsep = '/'
|
|
curdir = '.'
|
|
pardir = '..'
|
|
path = path.replace(altsep, sep)
|
|
@@ -570,7 +582,7 @@ def _abspath_fallback(path):
|
|
def abspath(path):
|
|
"""Return the absolute version of a path."""
|
|
try:
|
|
- return _getfullpathname(normpath(path))
|
|
+ return normpath(_getfullpathname(normpath(path)))
|
|
except (OSError, ValueError):
|
|
return _abspath_fallback(path)
|
|
|
|
@@ -719,6 +731,7 @@ def realpath(path, *, strict=False):
|
|
# strip the prefix anyway.
|
|
if ex.winerror == initial_winerror:
|
|
path = spath
|
|
+ path = normpath(path)
|
|
return path
|
|
|
|
|
|
@@ -729,12 +742,11 @@ def realpath(path, *, strict=False):
|
|
def relpath(path, start=None):
|
|
"""Return a relative version of a path"""
|
|
path = os.fspath(path)
|
|
+ sep = _get_sep(path)
|
|
if isinstance(path, bytes):
|
|
- sep = b'\\'
|
|
curdir = b'.'
|
|
pardir = b'..'
|
|
else:
|
|
- sep = '\\'
|
|
curdir = '.'
|
|
pardir = '..'
|
|
|
|
@@ -789,13 +801,11 @@ def commonpath(paths):
|
|
raise ValueError('commonpath() arg is an empty sequence')
|
|
|
|
paths = tuple(map(os.fspath, paths))
|
|
+ sep = _get_sep(paths[0])
|
|
+ altsep = _get_altsep(paths[0])
|
|
if isinstance(paths[0], bytes):
|
|
- sep = b'\\'
|
|
- altsep = b'/'
|
|
curdir = b'.'
|
|
else:
|
|
- sep = '\\'
|
|
- altsep = '/'
|
|
curdir = '.'
|
|
|
|
try:
|
|
diff --git a/Lib/pathlib.py b/Lib/pathlib.py
|
|
index ecb1e8a..eec8a9e 100644
|
|
--- a/Lib/pathlib.py
|
|
+++ b/Lib/pathlib.py
|
|
@@ -115,6 +115,8 @@ class _WindowsFlavour(_Flavour):
|
|
|
|
sep = '\\'
|
|
altsep = '/'
|
|
+ if os.environ.get('MSYSTEM', ''):
|
|
+ sep, altsep = altsep, sep
|
|
has_drv = True
|
|
pathmod = ntpath
|
|
|
|
diff --git a/Lib/site.py b/Lib/site.py
|
|
index 69670d9..41b9cf1 100644
|
|
--- a/Lib/site.py
|
|
+++ b/Lib/site.py
|
|
@@ -88,6 +88,12 @@
|
|
USER_BASE = None
|
|
|
|
|
|
+# Same as defined in Lib/sysconfig.py
|
|
+# redeclared since sysconfig is large for site.
|
|
+# GCC[mingw*] use posix build system
|
|
+_POSIX_BUILD = os.name == 'posix' or \
|
|
+ (os.name == "nt" and 'GCC' in sys.version)
|
|
+
|
|
def _trace(message):
|
|
if sys.flags.verbose:
|
|
print(message, file=sys.stderr)
|
|
@@ -273,7 +279,7 @@ def _getuserbase():
|
|
def joinuser(*args):
|
|
return os.path.expanduser(os.path.join(*args))
|
|
|
|
- if os.name == "nt":
|
|
+ if os.name == "nt" and not _POSIX_BUILD:
|
|
base = os.environ.get("APPDATA") or "~"
|
|
return joinuser(base, "Python")
|
|
|
|
@@ -283,14 +289,36 @@ def joinuser(*args):
|
|
|
|
return joinuser("~", ".local")
|
|
|
|
+# Copy of sysconfig.get_platform() but only for MinGW
|
|
+def _get_platform():
|
|
+ if os.name == 'nt':
|
|
+ if 'gcc' in sys.version.lower():
|
|
+ if 'ucrt' in sys.version.lower():
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64_ucrt'
|
|
+ return 'mingw_i686_ucrt'
|
|
+ if 'clang' in sys.version.lower():
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64_clang'
|
|
+ if 'arm64' in sys.version.lower():
|
|
+ return 'mingw_aarch64'
|
|
+ if 'arm' in sys.version.lower():
|
|
+ return 'mingw_armv7'
|
|
+ return 'mingw_i686_clang'
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64'
|
|
+ return 'mingw_i686'
|
|
+ return sys.platform
|
|
|
|
# Same to sysconfig.get_path('purelib', os.name+'_user')
|
|
def _get_path(userbase):
|
|
version = sys.version_info
|
|
|
|
if os.name == 'nt':
|
|
- ver_nodot = sys.winver.replace('.', '')
|
|
- return f'{userbase}\\Python{ver_nodot}\\site-packages'
|
|
+ if not _POSIX_BUILD:
|
|
+ ver_nodot = sys.winver.replace('.', '')
|
|
+ return f'{userbase}\\Python{ver_nodot}\\site-packages'
|
|
+ return f'{userbase}/lib/python{version[0]}.{version[1]}-{_get_platform()}/site-packages'
|
|
|
|
if sys.platform == 'darwin' and sys._framework:
|
|
return f'{userbase}/lib/python/site-packages'
|
|
@@ -361,7 +389,7 @@ def getsitepackages(prefixes=None):
|
|
continue
|
|
seen.add(prefix)
|
|
|
|
- if os.sep == '/':
|
|
+ if _POSIX_BUILD:
|
|
libdirs = [sys.platlibdir]
|
|
if sys.platlibdir != "lib":
|
|
libdirs.append("lib")
|
|
@@ -392,7 +420,7 @@ def setquit():
|
|
The repr of each object contains a hint at how it works.
|
|
|
|
"""
|
|
- if os.sep == '\\':
|
|
+ if sys.platform == 'win32':
|
|
eof = 'Ctrl-Z plus Return'
|
|
else:
|
|
eof = 'Ctrl-D (i.e. EOF)'
|
|
diff --git a/Lib/ssl.py b/Lib/ssl.py
|
|
index ebac1d6..cac0c37 100644
|
|
--- a/Lib/ssl.py
|
|
+++ b/Lib/ssl.py
|
|
@@ -254,7 +254,7 @@ class _TLSMessageType:
|
|
CHANGE_CIPHER_SPEC = 0x0101
|
|
|
|
|
|
-if sys.platform == "win32":
|
|
+if sys.platform == "win32" and sys.version.find("GCC") == -1:
|
|
from _ssl import enum_certificates, enum_crls
|
|
|
|
from socket import socket, SOCK_STREAM, create_connection
|
|
@@ -591,7 +591,7 @@ def _load_windows_store_certs(self, storename, purpose):
|
|
def load_default_certs(self, purpose=Purpose.SERVER_AUTH):
|
|
if not isinstance(purpose, _ASN1Object):
|
|
raise TypeError(purpose)
|
|
- if sys.platform == "win32":
|
|
+ if sys.platform == "win32" and sys.version.find("GCC") == -1:
|
|
for storename in self._windows_cert_stores:
|
|
self._load_windows_store_certs(storename, purpose)
|
|
self.set_default_verify_paths()
|
|
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
|
|
index ebe3711..8035d2e 100644
|
|
--- a/Lib/sysconfig.py
|
|
+++ b/Lib/sysconfig.py
|
|
@@ -2,6 +2,7 @@
|
|
|
|
import os
|
|
import sys
|
|
+import textwrap
|
|
from os.path import pardir, realpath
|
|
|
|
__all__ = [
|
|
@@ -47,13 +48,13 @@
|
|
'data': '{base}',
|
|
},
|
|
'nt': {
|
|
- 'stdlib': '{installed_base}/Lib',
|
|
- 'platstdlib': '{base}/Lib',
|
|
- 'purelib': '{base}/Lib/site-packages',
|
|
- 'platlib': '{base}/Lib/site-packages',
|
|
- 'include': '{installed_base}/Include',
|
|
- 'platinclude': '{installed_base}/Include',
|
|
- 'scripts': '{base}/Scripts',
|
|
+ 'stdlib': '{installed_base}/lib/python{py_version_short}',
|
|
+ 'platstdlib': '{base}/lib/python{py_version_short}',
|
|
+ 'purelib': '{base}/lib/python{py_version_short}/site-packages',
|
|
+ 'platlib': '{base}/lib/python{py_version_short}/site-packages',
|
|
+ 'include': '{installed_base}/include/python{py_version_short}',
|
|
+ 'platinclude': '{installed_base}/include/python{py_version_short}',
|
|
+ 'scripts': '{base}/bin',
|
|
'data': '{base}',
|
|
},
|
|
# Downstream distributors can overwrite the default install scheme.
|
|
@@ -97,13 +98,18 @@
|
|
},
|
|
}
|
|
|
|
+# GCC[mingw*] use posix build system
|
|
+_POSIX_BUILD = os.name == 'posix' or \
|
|
+ (os.name == "nt" and 'GCC' in sys.version)
|
|
+
|
|
# For the OS-native venv scheme, we essentially provide an alias:
|
|
-if os.name == 'nt':
|
|
+if os.name == 'nt' and not _POSIX_BUILD:
|
|
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv']
|
|
else:
|
|
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv']
|
|
|
|
|
|
+
|
|
# NOTE: site.py has copy of this function.
|
|
# Sync it when modify this function.
|
|
def _getuserbase():
|
|
@@ -118,7 +124,7 @@ def _getuserbase():
|
|
def joinuser(*args):
|
|
return os.path.expanduser(os.path.join(*args))
|
|
|
|
- if os.name == "nt":
|
|
+ if os.name == "nt" and not _POSIX_BUILD:
|
|
base = os.environ.get("APPDATA") or "~"
|
|
return joinuser(base, "Python")
|
|
|
|
@@ -134,20 +140,20 @@ def joinuser(*args):
|
|
_INSTALL_SCHEMES |= {
|
|
# NOTE: When modifying "purelib" scheme, update site._get_path() too.
|
|
'nt_user': {
|
|
- 'stdlib': '{userbase}/Python{py_version_nodot_plat}',
|
|
- 'platstdlib': '{userbase}/Python{py_version_nodot_plat}',
|
|
- 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages',
|
|
- 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages',
|
|
- 'include': '{userbase}/Python{py_version_nodot_plat}/Include',
|
|
- 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts',
|
|
+ 'stdlib': '{userbase}/lib/python{py_version_short_plat}',
|
|
+ 'platstdlib': '{userbase}/lib/python{py_version_short_plat}',
|
|
+ 'purelib': '{userbase}/lib/python{py_version_short_plat}/site-packages',
|
|
+ 'platlib': '{userbase}/lib/python{py_version_short_plat}/site-packages',
|
|
+ 'include': '{userbase}/include/python{py_version_short_plat}',
|
|
+ 'scripts': '{userbase}/bin',
|
|
'data': '{userbase}',
|
|
},
|
|
'posix_user': {
|
|
- 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}',
|
|
- 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}',
|
|
- 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
|
|
- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
|
|
- 'include': '{userbase}/include/python{py_version_short}',
|
|
+ 'stdlib': '{userbase}/{platlibdir}/python{py_version_short_plat}',
|
|
+ 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short_plat}',
|
|
+ 'purelib': '{userbase}/lib/python{py_version_short_plat}/site-packages',
|
|
+ 'platlib': '{userbase}/lib/python{py_version_short_plat}/site-packages',
|
|
+ 'include': '{userbase}/include/python{py_version_short_plat}',
|
|
'scripts': '{userbase}/bin',
|
|
'data': '{userbase}',
|
|
},
|
|
@@ -277,7 +283,7 @@ def _expand_vars(scheme, vars):
|
|
|
|
|
|
def _get_preferred_schemes():
|
|
- if os.name == 'nt':
|
|
+ if os.name == 'nt' and not _POSIX_BUILD:
|
|
return {
|
|
'prefix': 'nt',
|
|
'home': 'posix_home',
|
|
@@ -435,6 +441,14 @@ def _parse_makefile(filename, vars=None, keep_unresolved=True):
|
|
if isinstance(v, str):
|
|
done[k] = v.strip()
|
|
|
|
+ # any keys that have one with the same name suffixed with _b2h
|
|
+ # need to be replaced with the value of the _b2h key.
|
|
+ # This converts from MSYS*/Cygwin paths to Windows paths.
|
|
+ for k, v in dict(done).items():
|
|
+ if isinstance(k, str):
|
|
+ if k.endswith("_b2h"):
|
|
+ done[k[:-4]]=v
|
|
+
|
|
# save the results in the global dictionary
|
|
vars.update(done)
|
|
return vars
|
|
@@ -514,11 +528,30 @@ def _generate_posix_vars():
|
|
os.makedirs(pybuilddir, exist_ok=True)
|
|
destfile = os.path.join(pybuilddir, name + '.py')
|
|
|
|
+ replacement = """
|
|
+ keys_to_replace = [
|
|
+ 'BINDIR', 'BINLIBDEST', 'CONFINCLUDEDIR',
|
|
+ 'CONFINCLUDEPY', 'DESTDIRS', 'DESTLIB', 'DESTSHARED',
|
|
+ 'INCLDIRSTOMAKE', 'INCLUDEDIR', 'INCLUDEPY',
|
|
+ 'LIBDEST', 'LIBDIR', 'LIBPC', 'LIBPL', 'MACHDESTLIB',
|
|
+ 'MANDIR', 'SCRIPTDIR', 'datarootdir', 'exec_prefix',
|
|
+ 'TZPATH',
|
|
+ ]
|
|
+
|
|
+ prefix = build_time_vars['BINDIR'][:-4]
|
|
+
|
|
+ for key in keys_to_replace:
|
|
+ value = build_time_vars[key]
|
|
+ build_time_vars[key] = value.replace(prefix, sys.prefix)
|
|
+ """
|
|
+
|
|
with open(destfile, 'w', encoding='utf8') as f:
|
|
+ f.write('import sys\n')
|
|
f.write('# system configuration generated and used by'
|
|
' the sysconfig module\n')
|
|
f.write('build_time_vars = ')
|
|
pprint.pprint(vars, stream=f)
|
|
+ f.write('\n%s' % textwrap.dedent(replacement))
|
|
|
|
# Create file used for sys.path fixup -- see Modules/getpath.c
|
|
with open('pybuilddir.txt', 'w', encoding='utf8') as f:
|
|
@@ -541,7 +574,7 @@ def _init_non_posix(vars):
|
|
vars['INCLUDEPY'] = get_path('include')
|
|
vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
|
|
vars['EXE'] = '.exe'
|
|
- vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
|
|
+ vars['VERSION'] = _PY_VERSION_SHORT
|
|
vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
|
|
vars['TZPATH'] = ''
|
|
|
|
@@ -587,7 +620,7 @@ def parse_config_h(fp, vars=None):
|
|
def get_config_h_filename():
|
|
"""Return the path of pyconfig.h."""
|
|
if _PYTHON_BUILD:
|
|
- if os.name == "nt":
|
|
+ if os.name == "nt" and not _POSIX_BUILD:
|
|
inc_dir = os.path.join(_PROJECT_BASE, "PC")
|
|
else:
|
|
inc_dir = _PROJECT_BASE
|
|
@@ -662,11 +695,15 @@ def get_config_vars(*args):
|
|
_CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '')
|
|
except AttributeError:
|
|
_CONFIG_VARS['py_version_nodot_plat'] = ''
|
|
+ if os.name == 'nt' and _POSIX_BUILD:
|
|
+ _CONFIG_VARS['py_version_short_plat'] = f'{_PY_VERSION_SHORT}-{get_platform()}'
|
|
+ else:
|
|
+ _CONFIG_VARS['py_version_short_plat'] = _PY_VERSION_SHORT
|
|
|
|
- if os.name == 'nt':
|
|
+ if os.name == 'nt' and not _POSIX_BUILD:
|
|
_init_non_posix(_CONFIG_VARS)
|
|
_CONFIG_VARS['VPATH'] = sys._vpath
|
|
- if os.name == 'posix':
|
|
+ if _POSIX_BUILD:
|
|
_init_posix(_CONFIG_VARS)
|
|
if _HAS_USER_BASE:
|
|
# Setting 'userbase' is done below the call to the
|
|
@@ -676,7 +713,7 @@ def get_config_vars(*args):
|
|
|
|
# Always convert srcdir to an absolute path
|
|
srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE)
|
|
- if os.name == 'posix':
|
|
+ if _POSIX_BUILD:
|
|
if _PYTHON_BUILD:
|
|
# If srcdir is a relative path (typically '.' or '..')
|
|
# then it should be interpreted relative to the directory
|
|
@@ -714,7 +751,7 @@ def get_config_var(name):
|
|
"""
|
|
return get_config_vars().get(name)
|
|
|
|
-
|
|
+# make sure to change site._get_platform() while changing this function
|
|
def get_platform():
|
|
"""Return a string that identifies the current platform.
|
|
|
|
@@ -737,6 +774,22 @@ def get_platform():
|
|
|
|
"""
|
|
if os.name == 'nt':
|
|
+ if 'gcc' in sys.version.lower():
|
|
+ if 'ucrt' in sys.version.lower():
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64_ucrt'
|
|
+ return 'mingw_i686_ucrt'
|
|
+ if 'clang' in sys.version.lower():
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64_clang'
|
|
+ if 'arm64' in sys.version.lower():
|
|
+ return 'mingw_aarch64'
|
|
+ if 'arm' in sys.version.lower():
|
|
+ return 'mingw_armv7'
|
|
+ return 'mingw_i686_clang'
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64'
|
|
+ return 'mingw_i686'
|
|
if 'amd64' in sys.version.lower():
|
|
return 'win-amd64'
|
|
if '(arm)' in sys.version.lower():
|
|
diff --git a/Lib/test/__main__.py b/Lib/test/__main__.py
|
|
index 19a6b2b..7641b32 100644
|
|
--- a/Lib/test/__main__.py
|
|
+++ b/Lib/test/__main__.py
|
|
@@ -1,2 +1,10 @@
|
|
+import os
|
|
+import sys
|
|
+
|
|
from test.libregrtest import main
|
|
+
|
|
+if sys.platform == "win32":
|
|
+ # Enable DLL loading from PATH.
|
|
+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1"
|
|
+
|
|
main()
|
|
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
|
|
index 53ba1ad..3b6f4ab 100644
|
|
--- a/Lib/test/test_bytes.py
|
|
+++ b/Lib/test/test_bytes.py
|
|
@@ -1105,7 +1105,7 @@ def test_from_format(self):
|
|
|
|
if os.name == 'nt':
|
|
# Windows (MSCRT)
|
|
- ptr_format = '0x%0{}X'.format(2 * sizeof_ptr)
|
|
+ ptr_format = '0x%0{}x'.format(2 * sizeof_ptr)
|
|
def ptr_formatter(ptr):
|
|
return (ptr_format % ptr)
|
|
else:
|
|
diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py
|
|
index 8d5b426..82ad71d 100644
|
|
--- a/Lib/test/test_getpath.py
|
|
+++ b/Lib/test/test_getpath.py
|
|
@@ -838,6 +838,7 @@ def test_symlink_buildpath_macos(self):
|
|
ENV_PYTHONHOME="",
|
|
ENV_PYTHONEXECUTABLE="",
|
|
ENV___PYVENV_LAUNCHER__="",
|
|
+ ENV_MSYSTEM="",
|
|
argv0="",
|
|
py_setpath="",
|
|
real_executable="",
|
|
@@ -877,6 +878,7 @@ def __init__(self, *a, argv0=None, config=None, **kw):
|
|
self.update(DEFAULT_NAMESPACE)
|
|
self["config"] = DEFAULT_CONFIG.copy()
|
|
self["os_name"] = "nt"
|
|
+ self["is_mingw"] = 0
|
|
self["PLATLIBDIR"] = "DLLs"
|
|
self["PYWINVER"] = "9.8-XY"
|
|
self["VPATH"] = r"..\.."
|
|
@@ -912,6 +914,9 @@ def __missing__(self, key):
|
|
except AttributeError:
|
|
raise KeyError(key) from None
|
|
|
|
+ def normpath(self, path):
|
|
+ return ntpath.normpath(path)
|
|
+
|
|
def abspath(self, path):
|
|
if self.isabs(path):
|
|
return path
|
|
@@ -1053,6 +1058,7 @@ def __init__(self, *a, argv0=None, config=None, **kw):
|
|
self.update(DEFAULT_NAMESPACE)
|
|
self["config"] = DEFAULT_CONFIG.copy()
|
|
self["os_name"] = "posix"
|
|
+ self["is_mingw"] = 0
|
|
self["PLATLIBDIR"] = "lib"
|
|
self["WITH_NEXT_FRAMEWORK"] = 0
|
|
super().__init__(*a, **kw)
|
|
@@ -1089,6 +1095,9 @@ def __missing__(self, key):
|
|
except AttributeError:
|
|
raise KeyError(key) from None
|
|
|
|
+ def normpath(self, path):
|
|
+ return path
|
|
+
|
|
def abspath(self, path):
|
|
if self.isabs(path):
|
|
return path
|
|
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
|
|
index cdd1bea..cfd8a10 100644
|
|
--- a/Lib/test/test_httpservers.py
|
|
+++ b/Lib/test/test_httpservers.py
|
|
@@ -442,10 +442,10 @@ def test_undecodable_filename(self):
|
|
def test_undecodable_parameter(self):
|
|
# sanity check using a valid parameter
|
|
response = self.request(self.base_url + '/?x=123').read()
|
|
- self.assertRegex(response, f'listing for {self.base_url}/\?x=123'.encode('latin1'))
|
|
+ self.assertRegex(response, rf'listing for {self.base_url}/\?x=123'.encode('latin1'))
|
|
# now the bogus encoding
|
|
response = self.request(self.base_url + '/?x=%bb').read()
|
|
- self.assertRegex(response, f'listing for {self.base_url}/\?x=\xef\xbf\xbd'.encode('latin1'))
|
|
+ self.assertRegex(response, rf'listing for {self.base_url}/\?x=\xef\xbf\xbd'.encode('latin1'))
|
|
|
|
def test_get_dir_redirect_location_domain_injection_bug(self):
|
|
"""Ensure //evil.co/..%2f../../X does not put //evil.co/ in Location.
|
|
diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py
|
|
index b7dfe86..58a8f5d 100644
|
|
--- a/Lib/test/test_importlib/test_windows.py
|
|
+++ b/Lib/test/test_importlib/test_windows.py
|
|
@@ -24,6 +24,23 @@ def get_platform():
|
|
'x64' : 'win-amd64',
|
|
'arm' : 'win-arm32',
|
|
}
|
|
+ if os.name == 'nt':
|
|
+ if 'gcc' in sys.version.lower():
|
|
+ if 'ucrt' in sys.version.lower():
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64_ucrt'
|
|
+ return 'mingw_i686_ucrt'
|
|
+ if 'clang' in sys.version.lower():
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64_clang'
|
|
+ if 'arm64' in sys.version.lower():
|
|
+ return 'mingw_aarch64'
|
|
+ if 'arm' in sys.version.lower():
|
|
+ return 'mingw_armv7'
|
|
+ return 'mingw_i686_clang'
|
|
+ if 'amd64' in sys.version.lower():
|
|
+ return 'mingw_x86_64'
|
|
+ return 'mingw_i686'
|
|
if ('VSCMD_ARG_TGT_ARCH' in os.environ and
|
|
os.environ['VSCMD_ARG_TGT_ARCH'] in TARGET_TO_PLAT):
|
|
return TARGET_TO_PLAT[os.environ['VSCMD_ARG_TGT_ARCH']]
|
|
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
|
|
index d96371d..a75a664 100644
|
|
--- a/Lib/test/test_sysconfig.py
|
|
+++ b/Lib/test/test_sysconfig.py
|
|
@@ -17,7 +17,7 @@
|
|
from sysconfig import (get_paths, get_platform, get_config_vars,
|
|
get_path, get_path_names, _INSTALL_SCHEMES,
|
|
get_default_scheme, get_scheme_names, get_config_var,
|
|
- _expand_vars, _get_preferred_schemes, _main)
|
|
+ _expand_vars, _get_preferred_schemes, _main, _POSIX_BUILD)
|
|
import _osx_support
|
|
|
|
|
|
@@ -180,7 +180,7 @@ def test_nt_venv_scheme(self):
|
|
self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='nt_venv'))
|
|
|
|
def test_venv_scheme(self):
|
|
- if sys.platform == 'win32':
|
|
+ if not _POSIX_BUILD and sys.platform == 'win32':
|
|
self.assertEqual(
|
|
sysconfig.get_path('scripts', scheme='venv'),
|
|
sysconfig.get_path('scripts', scheme='nt_venv')
|
|
@@ -371,6 +371,10 @@ def test_user_similar(self):
|
|
if HAS_USER_BASE:
|
|
user_path = get_path(name, 'posix_user')
|
|
expected = os.path.normpath(global_path.replace(base, user, 1))
|
|
+ if os.name == 'nt' and _POSIX_BUILD:
|
|
+ expected = expected.replace(
|
|
+ f'python{sysconfig.get_python_version()}',
|
|
+ f'python{sysconfig.get_python_version()}-{get_platform()}')
|
|
# bpo-44860: platlib of posix_user doesn't use sys.platlibdir,
|
|
# whereas posix_prefix does.
|
|
if name == 'platlib':
|
|
diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py
|
|
index 6bce308..1cd57d0 100644
|
|
--- a/Lib/venv/__init__.py
|
|
+++ b/Lib/venv/__init__.py
|
|
@@ -11,7 +11,7 @@
|
|
import sys
|
|
import sysconfig
|
|
import types
|
|
-
|
|
+from sysconfig import _POSIX_BUILD
|
|
|
|
CORE_VENV_DEPS = ('pip', 'setuptools')
|
|
logger = logging.getLogger(__name__)
|
|
@@ -301,7 +301,7 @@ def setup_python(self, context):
|
|
if not os.path.islink(path):
|
|
os.chmod(path, 0o755)
|
|
else:
|
|
- if self.symlinks:
|
|
+ if self.symlinks and not _POSIX_BUILD:
|
|
# For symlinking, we need a complete copy of the root directory
|
|
# If symlinks fail, you'll get unnecessary copies of files, but
|
|
# we assume that if you've opted into symlinks on Windows then
|
|
@@ -325,6 +325,12 @@ def setup_python(self, context):
|
|
if os.path.lexists(src):
|
|
copier(src, os.path.join(binpath, suffix))
|
|
|
|
+ if _POSIX_BUILD:
|
|
+ # copy from python/pythonw so the venvlauncher magic in symlink_or_copy triggers
|
|
+ copier(os.path.join(dirname, 'python.exe'), os.path.join(binpath, 'python3.exe'))
|
|
+ copier(os.path.join(dirname, 'python.exe'), os.path.join(binpath, 'python%d.%d.exe' % sys.version_info[:2]))
|
|
+ copier(os.path.join(dirname, 'pythonw.exe'), os.path.join(binpath, 'python3w.exe'))
|
|
+
|
|
if sysconfig.is_python_build():
|
|
# copy init.tcl
|
|
for root, dirs, files in os.walk(context.python_dir):
|
|
@@ -349,6 +355,7 @@ def _call_new_python(self, context, *py_args, **kwargs):
|
|
env['VIRTUAL_ENV'] = context.env_dir
|
|
env.pop('PYTHONHOME', None)
|
|
env.pop('PYTHONPATH', None)
|
|
+ env.pop("MSYSTEM", None)
|
|
kwargs['cwd'] = context.env_dir
|
|
kwargs['executable'] = context.env_exec_cmd
|
|
subprocess.check_output(args, **kwargs)
|
|
diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate
|
|
index 6fbc2b8..9c3d58d 100644
|
|
--- a/Lib/venv/scripts/common/activate
|
|
+++ b/Lib/venv/scripts/common/activate
|
|
@@ -38,7 +38,7 @@ deactivate () {
|
|
# unset irrelevant variables
|
|
deactivate nondestructive
|
|
|
|
-VIRTUAL_ENV="__VENV_DIR__"
|
|
+VIRTUAL_ENV=$(cygpath "__VENV_DIR__")
|
|
export VIRTUAL_ENV
|
|
|
|
_OLD_VIRTUAL_PATH="$PATH"
|
|
diff --git a/Makefile.pre.in b/Makefile.pre.in
|
|
index 3ea8653..2707d04 100644
|
|
--- a/Makefile.pre.in
|
|
+++ b/Makefile.pre.in
|
|
@@ -39,6 +39,7 @@ CXX= @CXX@
|
|
MAINCC= @MAINCC@
|
|
LINKCC= @LINKCC@
|
|
AR= @AR@
|
|
+WINDRES= @WINDRES@
|
|
READELF= @READELF@
|
|
SOABI= @SOABI@
|
|
LDVERSION= @LDVERSION@
|
|
@@ -123,6 +124,7 @@ PY_CORE_CFLAGS= $(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE
|
|
PY_CORE_LDFLAGS=$(PY_LDFLAGS) $(PY_LDFLAGS_NODIST)
|
|
# Strict or non-strict aliasing flags used to compile dtoa.c, see above
|
|
CFLAGS_ALIASING=@CFLAGS_ALIASING@
|
|
+RCFLAGS=@RCFLAGS@
|
|
|
|
|
|
# Machine-dependent subdirectories
|
|
@@ -141,6 +143,12 @@ exec_prefix= @exec_prefix@
|
|
# Install prefix for data files
|
|
datarootdir= @datarootdir@
|
|
|
|
+# Locations needed for semi-native fixup of sysconfig.
|
|
+srcdir_b2h= @srcdir_b2h@
|
|
+abs_srcdir_b2h= @abs_srcdir_b2h@
|
|
+abs_builddir_b2h= @abs_builddir_b2h@
|
|
+prefix_b2h= @prefix_b2h@
|
|
+
|
|
# Expanded directories
|
|
BINDIR= @bindir@
|
|
LIBDIR= @libdir@
|
|
@@ -158,10 +166,12 @@ BINLIBDEST= @BINLIBDEST@
|
|
LIBDEST= $(SCRIPTDIR)/python$(VERSION)
|
|
INCLUDEPY= $(INCLUDEDIR)/python$(LDVERSION)
|
|
CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(LDVERSION)
|
|
+VENVLAUNCHERDIR= $(BINLIBDEST)/venv/scripts/nt
|
|
|
|
# Symbols used for using shared libraries
|
|
SHLIB_SUFFIX= @SHLIB_SUFFIX@
|
|
EXT_SUFFIX= @EXT_SUFFIX@
|
|
+PYD_PLATFORM_TAG = @PYD_PLATFORM_TAG@
|
|
LDSHARED= @LDSHARED@ $(PY_LDFLAGS)
|
|
BLDSHARED= @BLDSHARED@ $(PY_CORE_LDFLAGS)
|
|
LDCXXSHARED= @LDCXXSHARED@
|
|
@@ -268,6 +278,8 @@ LIBRARY_DEPS= @LIBRARY_DEPS@
|
|
LINK_PYTHON_DEPS=@LINK_PYTHON_DEPS@
|
|
PY_ENABLE_SHARED= @PY_ENABLE_SHARED@
|
|
STATIC_LIBPYTHON= @STATIC_LIBPYTHON@
|
|
+ABI3DLLLIBRARY= libpython3.dll
|
|
+ABI3LDLIBRARY= libpython3.dll.a
|
|
|
|
|
|
LIBS= @LIBS@
|
|
@@ -284,6 +296,7 @@ LIBOBJS= @LIBOBJS@
|
|
|
|
PYTHON= python$(EXE)
|
|
BUILDPYTHON= python$(BUILDEXE)
|
|
+BUILDPYTHONW= pythonw$(BUILDEXE)
|
|
|
|
HOSTRUNNER= @HOSTRUNNER@
|
|
|
|
@@ -344,6 +357,7 @@ IO_OBJS= \
|
|
##########################################################################
|
|
|
|
LIBFFI_INCLUDEDIR= @LIBFFI_INCLUDEDIR@
|
|
+NCURSESW_INCLUDEDIR= @NCURSESW_INCLUDEDIR@
|
|
|
|
##########################################################################
|
|
# Parser
|
|
@@ -390,7 +404,7 @@ PYTHON_OBJS= \
|
|
Python/dynamic_annotations.o \
|
|
Python/errors.o \
|
|
Python/frame.o \
|
|
- Python/frozenmain.o \
|
|
+ @PYTHON_OBJS_FROZENMAIN@ \
|
|
Python/future.o \
|
|
Python/getargs.o \
|
|
Python/getcompiler.o \
|
|
@@ -402,6 +416,7 @@ PYTHON_OBJS= \
|
|
Python/import.o \
|
|
Python/importdl.o \
|
|
Python/initconfig.o \
|
|
+ Python/iscygpty.o \
|
|
Python/marshal.o \
|
|
Python/modsupport.o \
|
|
Python/mysnprintf.o \
|
|
@@ -584,8 +599,8 @@ LIBEXPAT_HEADERS= \
|
|
|
|
# Default target
|
|
all: @DEF_MAKE_ALL_RULE@
|
|
-build_all: check-clean-src $(BUILDPYTHON) platform oldsharedmods sharedmods \
|
|
- gdbhooks Programs/_testembed python-config
|
|
+build_all: check-clean-src $(BUILDPYTHON) $(BUILDPYTHONW) platform oldsharedmods sharedmods \
|
|
+ gdbhooks Programs/_testembed python-config $(ABI3DLLLIBRARY) $(ABI3LDLIBRARY)
|
|
build_wasm: check-clean-src $(BUILDPYTHON) platform oldsharedmods python-config
|
|
|
|
# Check that the source is clean when building out of source.
|
|
@@ -700,9 +715,30 @@ coverage-report: regen-token regen-frozen
|
|
clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c
|
|
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir)
|
|
|
|
+python_exe.o: $(srcdir)/PC/python_exe.rc
|
|
+ $(WINDRES) $(RCFLAGS) -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_exe.rc $@
|
|
+
|
|
+pythonw_exe.o: $(srcdir)/PC/pythonw_exe.rc
|
|
+ $(WINDRES) $(RCFLAGS) -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pythonw_exe.rc $@
|
|
+
|
|
+python_nt.o: $(srcdir)/PC/python_nt.rc
|
|
+ $(WINDRES) $(RCFLAGS) -DORIGINAL_FILENAME=\\\"$(DLLLIBRARY)\\\" -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_nt.rc $@
|
|
+
|
|
+python3dll_nt.o: $(srcdir)/PC/python_nt.rc
|
|
+ $(WINDRES) $(RCFLAGS) -DORIGINAL_FILENAME=\\\"$(ABI3DLLLIBRARY)\\\" -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/python_nt.rc $@
|
|
+
|
|
+venvlauncher.o: $(srcdir)/PC/pylauncher.rc
|
|
+ $(WINDRES) $(RCFLAGS) -DPY_ICON -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pylauncher.rc $@
|
|
+
|
|
+venvwlauncher.o: $(srcdir)/PC/pylauncher.rc
|
|
+ $(WINDRES) $(RCFLAGS) -DPYW_ICON -I$(srcdir)/Include -I$(srcdir)/PC -I. $(srcdir)/PC/pylauncher.rc $@
|
|
+
|
|
+$(BUILDPYTHONW): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) pythonw_exe.o
|
|
+ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -municode -mwindows -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) pythonw_exe.o
|
|
+
|
|
# Build the interpreter
|
|
-$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS)
|
|
- $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS)
|
|
+$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) python_exe.o
|
|
+ $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -municode -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) python_exe.o
|
|
|
|
platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt
|
|
$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform
|
|
@@ -806,13 +842,17 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
|
|
|
|
# This rule builds the Cygwin Python DLL and import library if configured
|
|
# for a shared core library; otherwise, this rule is a noop.
|
|
-$(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS)
|
|
+$(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS) python_nt.o
|
|
if test -n "$(DLLLIBRARY)"; then \
|
|
$(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \
|
|
- $(LIBS) $(MODLIBS) $(SYSLIBS); \
|
|
+ $(LIBS) $(LDFLAGS_NODIST) $(MODLIBS) $(SYSLIBS) python_nt.o; \
|
|
else true; \
|
|
fi
|
|
|
|
+$(ABI3DLLLIBRARY) $(ABI3LDLIBRARY): python3dll_nt.o $(srcdir)/PC/launcher.c
|
|
+ $(LDSHARED) -DPYTHON_DLL_NAME=\"$(DLLLIBRARY)\" $(srcdir)/PC/python3dll.c -Wl,--out-implib=$(ABI3LDLIBRARY) -o $(ABI3DLLLIBRARY) python3dll_nt.o \
|
|
+ $(LDFLAGS_NODIST);
|
|
+
|
|
# wasm32-emscripten browser build
|
|
# wasm assets directory is relative to current build dir, e.g. "./usr/local".
|
|
# --preload-file turns a relative asset path into an absolute path.
|
|
@@ -974,7 +1014,7 @@ BOOTSTRAP_HEADERS = \
|
|
Programs/_bootstrap_python.o: Programs/_bootstrap_python.c $(BOOTSTRAP_HEADERS) $(PYTHON_HEADERS)
|
|
|
|
_bootstrap_python: $(LIBRARY_OBJS_OMIT_FROZEN) Programs/_bootstrap_python.o Modules/getpath.o Modules/Setup.local
|
|
- $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ $(LIBRARY_OBJS_OMIT_FROZEN) \
|
|
+ $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ -municode -mwindows $(LIBRARY_OBJS_OMIT_FROZEN) \
|
|
Programs/_bootstrap_python.o Modules/getpath.o $(LIBS) $(MODLIBS) $(SYSLIBS)
|
|
|
|
|
|
@@ -1276,9 +1316,15 @@ Python/dynload_hpux.o: $(srcdir)/Python/dynload_hpux.c Makefile
|
|
-DSHLIB_EXT='"$(EXT_SUFFIX)"' \
|
|
-o $@ $(srcdir)/Python/dynload_hpux.c
|
|
|
|
+Python/dynload_win.o: $(srcdir)/Python/dynload_win.c Makefile
|
|
+ $(CC) -c $(PY_CORE_CFLAGS) \
|
|
+ -DPYD_PLATFORM_TAG='"$(PYD_PLATFORM_TAG)"' \
|
|
+ -o $@ $(srcdir)/Python/dynload_win.c
|
|
+
|
|
Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h
|
|
$(CC) -c $(PY_CORE_CFLAGS) \
|
|
-DABIFLAGS='"$(ABIFLAGS)"' \
|
|
+ -DVPATH='"$(VPATH)"' \
|
|
$(MULTIARCH_CPPFLAGS) \
|
|
-o $@ $(srcdir)/Python/sysmodule.c
|
|
|
|
@@ -1496,6 +1542,7 @@ PYTHON_HEADERS= \
|
|
$(srcdir)/Include/frameobject.h \
|
|
$(srcdir)/Include/import.h \
|
|
$(srcdir)/Include/intrcheck.h \
|
|
+ $(srcdir)/Include/iscygpty.h \
|
|
$(srcdir)/Include/iterobject.h \
|
|
$(srcdir)/Include/listobject.h \
|
|
$(srcdir)/Include/longobject.h \
|
|
@@ -1791,7 +1838,7 @@ $(DESTSHARED):
|
|
# Install the interpreter with $(VERSION) affixed
|
|
# This goes into $(exec_prefix)
|
|
altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@
|
|
- @for i in $(BINDIR) $(LIBDIR); \
|
|
+ @for i in $(BINDIR) $(LIBDIR) $(VENVLAUNCHERDIR); \
|
|
do \
|
|
if test ! -d $(DESTDIR)$$i; then \
|
|
echo "Creating directory $$i"; \
|
|
@@ -1801,6 +1848,7 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@
|
|
done
|
|
if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \
|
|
$(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \
|
|
+ $(INSTALL_PROGRAM) $(BUILDPYTHONW) $(DESTDIR)$(BINDIR)/python3w$(EXE); \
|
|
else \
|
|
$(INSTALL_PROGRAM) $(STRIPFLAG) Mac/pythonw $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \
|
|
fi
|
|
@@ -1814,6 +1862,7 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@
|
|
if test -f $(LDLIBRARY) && test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \
|
|
if test -n "$(DLLLIBRARY)" ; then \
|
|
$(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \
|
|
+ $(INSTALL_SHARED) $(ABI3DLLLIBRARY) $(DESTDIR)$(BINDIR); \
|
|
else \
|
|
$(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \
|
|
if test $(LDLIBRARY) != $(INSTSONAME); then \
|
|
@@ -1924,6 +1973,7 @@ LIBSUBDIRS= asyncio \
|
|
tkinter \
|
|
tomllib \
|
|
turtledemo \
|
|
+ msilib \
|
|
unittest \
|
|
urllib \
|
|
venv venv/scripts venv/scripts/common venv/scripts/posix \
|
|
@@ -2223,8 +2273,9 @@ libainstall: all python-config
|
|
@if test "$(STATIC_LIBPYTHON)" = 1; then \
|
|
if test -d $(LIBRARY); then :; else \
|
|
if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
|
|
- if test "$(SHLIB_SUFFIX)" = .dll; then \
|
|
- $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \
|
|
+ if test "$(SHLIB_SUFFIX)" = .dll -o "$(SHLIB_SUFFIX)" = .pyd; then \
|
|
+ $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBDIR) ; \
|
|
+ $(INSTALL_DATA) $(ABI3LDLIBRARY) $(DESTDIR)$(LIBDIR) ; \
|
|
else \
|
|
$(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
|
|
fi; \
|
|
@@ -2263,16 +2314,23 @@ libainstall: all python-config
|
|
else true; \
|
|
fi
|
|
|
|
+ifeq ($(shell uname -o),Msys)
|
|
+DESTDIRFINAL=$(DESTDIR)
|
|
+else
|
|
+DESTDIRFINAL=$(DESTDIR)/
|
|
+endif
|
|
+
|
|
# Install the dynamically loadable modules
|
|
# This goes into $(exec_prefix)
|
|
sharedinstall: all
|
|
+ MSYS2_ARG_CONV_EXCL="--prefix=;--install-scripts=;--install-platlib=" \
|
|
$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \
|
|
--prefix=$(prefix) \
|
|
--install-scripts=$(BINDIR) \
|
|
--install-platlib=$(DESTSHARED) \
|
|
- --root=$(DESTDIR)/
|
|
- -rm $(DESTDIR)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py
|
|
- -rm -r $(DESTDIR)$(DESTSHARED)/__pycache__
|
|
+ --root=$(DESTDIRFINAL)
|
|
+ -rm $(DESTDIRFINAL)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py
|
|
+ -rm -r $(DESTDIRFINAL)$(DESTSHARED)/__pycache__
|
|
|
|
# Here are a couple of targets for MacOSX again, to install a full
|
|
# framework-based Python. frameworkinstall installs everything, the
|
|
@@ -2464,7 +2522,7 @@ clean: clean-retain-profile
|
|
fi
|
|
|
|
clobber: clean
|
|
- -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \
|
|
+ -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY)$(ABI3LDLIBRARY) $(ABI3DLLLIBRARY) \
|
|
tags TAGS \
|
|
config.cache config.log pyconfig.h Modules/config.c
|
|
-rm -rf build platform
|
|
diff --git a/Misc/NEWS.d/3.11.4.rst b/Misc/NEWS.d/3.11.4.rst
|
|
new file mode 100755
|
|
index 0000000..71ed43d
|
|
--- /dev/null
|
|
+++ b/Misc/NEWS.d/3.11.4.rst
|
|
@@ -0,0 +1,785 @@
|
|
+.. date: 2023-06-01-03-24-58
|
|
+.. gh-issue: 103142
|
|
+.. nonce: GLWDMX
|
|
+.. release date: 2023-06-06
|
|
+.. section: Security
|
|
+
|
|
+The version of OpenSSL used in our binary builds has been upgraded to 1.1.1u
|
|
+to address several CVEs.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-02-17-56-32
|
|
+.. gh-issue: 99889
|
|
+.. nonce: l664SU
|
|
+.. section: Security
|
|
+
|
|
+Fixed a security in flaw in :func:`uu.decode` that could allow for directory
|
|
+traversal based on the input if no ``out_file`` was specified.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-01-15-03-25
|
|
+.. gh-issue: 104049
|
|
+.. nonce: b01Y3g
|
|
+.. section: Security
|
|
+
|
|
+Do not expose the local on-disk location in directory indexes produced by
|
|
+:class:`http.client.SimpleHTTPRequestHandler`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-03-07-20-59-17
|
|
+.. gh-issue: 102153
|
|
+.. nonce: 14CLSZ
|
|
+.. section: Security
|
|
+
|
|
+:func:`urllib.parse.urlsplit` now strips leading C0 control and space
|
|
+characters following the specification for URLs defined by WHATWG in
|
|
+response to CVE-2023-24329. Patch by Illia Volochii.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-31-19-35-22
|
|
+.. gh-issue: 105164
|
|
+.. nonce: 6Wajph
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Ensure annotations are set up correctly if the only annotation in a block is
|
|
+within a :keyword:`match` block. Patch by Jelle Zijlstra.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-18-13-00-21
|
|
+.. gh-issue: 104615
|
|
+.. nonce: h_rtw2
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Fix wrong ordering of assignments in code like ``a, a = x, y``. Contributed
|
|
+by Carl Meyer.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-14-18-56-54
|
|
+.. gh-issue: 104482
|
|
+.. nonce: yaQsv8
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Fix three error handling bugs in ast.c's validation of pattern matching
|
|
+statements.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-13-06-22-52
|
|
+.. gh-issue: 102818
|
|
+.. nonce: HIX1Dr
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Do not add a frame to the traceback in the ``sys.setprofile`` and
|
|
+``sys.settrace`` trampoline functions. This ensures that frames are not
|
|
+duplicated if an exception is raised in the callback function, and ensures
|
|
+that frames are not omitted if a C callback is used and that does not add
|
|
+the frame.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-12-00-19-02
|
|
+.. gh-issue: 104405
|
|
+.. nonce: tXV5fn
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Fix an issue where some :term:`bytecode` instructions could ignore
|
|
+:pep:`523` when "inlining" calls.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-01-12-03-52
|
|
+.. gh-issue: 104018
|
|
+.. nonce: PFxGS4
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Disallow the "z" format specifier in %-format of bytes objects.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-28-18-57-13
|
|
+.. gh-issue: 103971
|
|
+.. nonce: Q3U9lv
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Fix an issue where incorrect locations numbers could be assigned to code
|
|
+following ``case`` blocks.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-21-17-03-14
|
|
+.. gh-issue: 102310
|
|
+.. nonce: anLjDx
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Change the error range for invalid bytes literals.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-21-16-12-41
|
|
+.. gh-issue: 103590
|
|
+.. nonce: 7DHDOE
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Do not wrap a single exception raised from a ``try-except*`` construct in an
|
|
+:exc:`ExceptionGroup`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-14-22-35-23
|
|
+.. gh-issue: 101517
|
|
+.. nonce: 5EqM-S
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Fix bug in line numbers of instructions emitted for :keyword:`except*
|
|
+<except_star>`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-08-17-13-07
|
|
+.. gh-issue: 103242
|
|
+.. nonce: ysI1b3
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Migrate :meth:`~ssl.SSLContext.set_ecdh_curve` method not to use deprecated
|
|
+OpenSSL APIs. Patch by Dong-hee Na.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-01-00-46-31
|
|
+.. gh-issue: 102700
|
|
+.. nonce: 493NB4
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Allow built-in modules to be submodules. This allows submodules to be
|
|
+statically linked into a CPython binary.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-02-12-22-40-22
|
|
+.. gh-issue: 101857
|
|
+.. nonce: _bribG
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Fix xattr support detection on Linux systems by widening the check to linux,
|
|
+not just glibc. This fixes support for musl.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2022-11-08-12-36-25
|
|
+.. gh-issue: 99184
|
|
+.. nonce: KIaqzz
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Bypass instance attribute access of ``__name__`` in ``repr`` of
|
|
+:class:`weakref.ref`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2022-09-27-11-59-13
|
|
+.. gh-issue: 96670
|
|
+.. nonce: XrBBit
|
|
+.. section: Core and Builtins
|
|
+
|
|
+The parser now raises :exc:`SyntaxError` when parsing source code containing
|
|
+null bytes. Backported from ``aab01e3``. Patch by Pablo Galindo
|
|
+
|
|
+..
|
|
+
|
|
+.. bpo: 31821
|
|
+.. date: 2019-12-01-12-58-31
|
|
+.. nonce: 1FNmwk
|
|
+.. section: Core and Builtins
|
|
+
|
|
+Fix :func:`!pause_reading` to work when called from :func:`!connection_made`
|
|
+in :mod:`asyncio`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-06-02-02-38-26
|
|
+.. gh-issue: 105080
|
|
+.. nonce: 2imGMg
|
|
+.. section: Library
|
|
+
|
|
+Fixed inconsistent signature on derived classes for
|
|
+:func:`inspect.signature`
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-24-09-34-23
|
|
+.. gh-issue: 104874
|
|
+.. nonce: oqyJSy
|
|
+.. section: Library
|
|
+
|
|
+Document the ``__name__`` and ``__supertype__`` attributes of
|
|
+:class:`typing.NewType`. Patch by Jelle Zijlstra.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-17-20-03-01
|
|
+.. gh-issue: 104340
|
|
+.. nonce: kp_XmX
|
|
+.. section: Library
|
|
+
|
|
+When an ``asyncio`` pipe protocol loses its connection due to an error, and
|
|
+the caller doesn't await ``wait_closed()`` on the corresponding
|
|
+``StreamWriter``, don't log a warning about an exception that was never
|
|
+retrieved. After all, according to the ``StreamWriter.close()`` docs, the
|
|
+``wait_closed()`` call is optional ("not mandatory").
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-17-08-01-36
|
|
+.. gh-issue: 104372
|
|
+.. nonce: jpoWs6
|
|
+.. section: Library
|
|
+
|
|
+Refactored the ``_posixsubprocess`` internals to avoid Python C API usage
|
|
+between fork and exec when marking ``pass_fds=`` file descriptors
|
|
+inheritable.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-16-11-02-44
|
|
+.. gh-issue: 75367
|
|
+.. nonce: qLWR35
|
|
+.. section: Library
|
|
+
|
|
+Fix data descriptor detection in :func:`inspect.getattr_static`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-16-10-07-16
|
|
+.. gh-issue: 104536
|
|
+.. nonce: hFWD8f
|
|
+.. section: Library
|
|
+
|
|
+Fix a race condition in the internal :mod:`multiprocessing.process` cleanup
|
|
+logic that could manifest as an unintended ``AttributeError`` when calling
|
|
+``process.close()``.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-11-23-03-00
|
|
+.. gh-issue: 104399
|
|
+.. nonce: MMatTP
|
|
+.. section: Library
|
|
+
|
|
+Prepare the ``_tkinter`` module for building with Tcl 9.0 and future
|
|
+libtommath by replacing usage of deprecated functions
|
|
+:c:func:`mp_to_unsigned_bin_n` and :c:func:`mp_unsigned_bin_size` when
|
|
+necessary.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-08-20-57-17
|
|
+.. gh-issue: 104307
|
|
+.. nonce: DSB93G
|
|
+.. section: Library
|
|
+
|
|
+:func:`socket.getnameinfo` now releases the GIL while contacting the DNS
|
|
+server
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-08-15-39-00
|
|
+.. gh-issue: 87695
|
|
+.. nonce: f6iO7v
|
|
+.. section: Library
|
|
+
|
|
+Fix issue where :meth:`pathlib.Path.glob` raised :exc:`OSError` when it
|
|
+encountered a symlink to an overly long path.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-07-19-56-45
|
|
+.. gh-issue: 104265
|
|
+.. nonce: fVblry
|
|
+.. section: Library
|
|
+
|
|
+Prevent possible crash by disallowing instantiation of the
|
|
+:class:`!_csv.Reader` and :class:`!_csv.Writer` types. The regression was
|
|
+introduced in 3.10.0a4 with PR 23224 (:issue:`14935`). Patch by Radislav
|
|
+Chugunov.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-01-16-43-28
|
|
+.. gh-issue: 104035
|
|
+.. nonce: MrJBw8
|
|
+.. section: Library
|
|
+
|
|
+Do not ignore user-defined ``__getstate__`` and ``__setstate__`` methods for
|
|
+slotted frozen dataclasses.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-29-18-23-16
|
|
+.. gh-issue: 103987
|
|
+.. nonce: sRgALL
|
|
+.. section: Library
|
|
+
|
|
+In :mod:`mmap`, fix several bugs that could lead to access to memory-mapped
|
|
+files after they have been invalidated.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-27-20-03-08
|
|
+.. gh-issue: 103935
|
|
+.. nonce: Uaf2M0
|
|
+.. section: Library
|
|
+
|
|
+Use :func:`io.open_code` for files to be executed instead of raw
|
|
+:func:`open`
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-27-00-45-41
|
|
+.. gh-issue: 100370
|
|
+.. nonce: MgZ3KY
|
|
+.. section: Library
|
|
+
|
|
+Fix potential :exc:`OverflowError` in :meth:`sqlite3.Connection.blobopen`
|
|
+for 32-bit builds. Patch by Erlend E. Aasland.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-26-09-54-25
|
|
+.. gh-issue: 103848
|
|
+.. nonce: aDSnpR
|
|
+.. section: Library
|
|
+
|
|
+Add checks to ensure that ``[`` bracketed ``]`` hosts found by
|
|
+:func:`urllib.parse.urlsplit` are of IPv6 or IPvFuture format.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-26-09-38-47
|
|
+.. gh-issue: 103872
|
|
+.. nonce: 8LBsDz
|
|
+.. section: Library
|
|
+
|
|
+Update the bundled copy of pip to version 23.1.2.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-25-19-58-13
|
|
+.. gh-issue: 103861
|
|
+.. nonce: JeozgD
|
|
+.. section: Library
|
|
+
|
|
+Fix ``zipfile.Zipfile`` creating invalid zip files when ``force_zip64`` was
|
|
+used to add files to them. Patch by Carey Metcalfe.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-24-00-34-23
|
|
+.. gh-issue: 103685
|
|
+.. nonce: U14jBM
|
|
+.. section: Library
|
|
+
|
|
+Prepare :meth:`tkinter.Menu.index` for Tk 8.7 so that it does not raise
|
|
+``TclError: expected integer but got ""`` when it should return ``None``.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-22-22-14-09
|
|
+.. gh-issue: 81403
|
|
+.. nonce: zVz9Td
|
|
+.. section: Library
|
|
+
|
|
+:class:`urllib.request.CacheFTPHandler` no longer raises :class:`URLError`
|
|
+if a cached FTP instance is reused. ftplib's endtransfer method calls
|
|
+voidresp to drain the connection to handle FTP instance reuse properly.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-16-18-29-04
|
|
+.. gh-issue: 103578
|
|
+.. nonce: fly1wc
|
|
+.. section: Library
|
|
+
|
|
+Fixed a bug where :mod:`pdb` crashes when reading source file with different
|
|
+encoding by replacing :func:`io.open` with :func:`io.open_code`. The new
|
|
+method would also call into the hook set by :func:`PyFile_SetOpenCodeHook`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-15-12-19-14
|
|
+.. gh-issue: 103556
|
|
+.. nonce: TEf-2m
|
|
+.. section: Library
|
|
+
|
|
+Now creating :class:`inspect.Signature` objects with positional-only
|
|
+parameter with a default followed by a positional-or-keyword parameter
|
|
+without one is impossible.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-15-11-21-38
|
|
+.. gh-issue: 103559
|
|
+.. nonce: a9rYHG
|
|
+.. section: Library
|
|
+
|
|
+Update the bundled copy of pip to version 23.1.1.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-12-17-59-55
|
|
+.. gh-issue: 103365
|
|
+.. nonce: UBEE0U
|
|
+.. section: Library
|
|
+
|
|
+Set default Flag boundary to ``STRICT`` and fix bitwise operations.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-12-13-04-16
|
|
+.. gh-issue: 103472
|
|
+.. nonce: C6bOHv
|
|
+.. section: Library
|
|
+
|
|
+Avoid a potential :exc:`ResourceWarning` in
|
|
+:class:`http.client.HTTPConnection` by closing the proxy / tunnel's CONNECT
|
|
+response explicitly.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-11-21-38-39
|
|
+.. gh-issue: 103449
|
|
+.. nonce: -nxmhb
|
|
+.. section: Library
|
|
+
|
|
+Fix a bug in doc string generation in :func:`dataclasses.dataclass`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-06-17-28-36
|
|
+.. gh-issue: 103256
|
|
+.. nonce: 1syxfs
|
|
+.. section: Library
|
|
+
|
|
+Fixed a bug that caused :mod:`hmac` to raise an exception when the requested
|
|
+hash algorithm was not available in OpenSSL despite being available
|
|
+separately as part of ``hashlib`` itself. It now falls back properly to the
|
|
+built-in. This could happen when, for example, your OpenSSL does not include
|
|
+SHA3 support and you want to compute ``hmac.digest(b'K', b'M',
|
|
+'sha3_256')``.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-05-01-28-53
|
|
+.. gh-issue: 103225
|
|
+.. nonce: QD3JVU
|
|
+.. section: Library
|
|
+
|
|
+Fix a bug in :mod:`pdb` when displaying line numbers of module-level source
|
|
+code.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-04-12-43-38
|
|
+.. gh-issue: 93910
|
|
+.. nonce: jurMzv
|
|
+.. section: Library
|
|
+
|
|
+Remove deprecation of enum ``memmber.member`` access.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-03-23-44-34
|
|
+.. gh-issue: 102978
|
|
+.. nonce: gy9eVk
|
|
+.. section: Library
|
|
+
|
|
+Fixes :func:`unittest.mock.patch` not enforcing function signatures for
|
|
+methods decorated with ``@classmethod`` or ``@staticmethod`` when patch is
|
|
+called with ``autospec=True``.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-02-23-05-22
|
|
+.. gh-issue: 103204
|
|
+.. nonce: bbDmu0
|
|
+.. section: Library
|
|
+
|
|
+Fixes :mod:`http.server` accepting HTTP requests with HTTP version numbers
|
|
+preceded by '+', or '-', or with digit-separating '_' characters. The
|
|
+length of the version numbers is also constrained.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-03-23-15-24-38
|
|
+.. gh-issue: 102953
|
|
+.. nonce: YR4KaK
|
|
+.. section: Library
|
|
+
|
|
+The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`,
|
|
+have a new a *filter* argument that allows limiting tar features than may be
|
|
+surprising or dangerous, such as creating files outside the destination
|
|
+directory. See :ref:`tarfile-extraction-filter` for details.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-02-09-22-24-34
|
|
+.. gh-issue: 101640
|
|
+.. nonce: oFuEpB
|
|
+.. section: Library
|
|
+
|
|
+:class:`argparse.ArgumentParser` now catches errors when writing messages,
|
|
+such as when :data:`sys.stderr` is ``None``. Patch by Oleg Iarygin.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2022-09-07-09-32-07
|
|
+.. gh-issue: 96522
|
|
+.. nonce: t73oqp
|
|
+.. section: Library
|
|
+
|
|
+Fix potential deadlock in pty.spawn()
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2022-08-27-21-41-41
|
|
+.. gh-issue: 87474
|
|
+.. nonce: 9X-kxt
|
|
+.. section: Library
|
|
+
|
|
+Fix potential file descriptor leaks in :class:`subprocess.Popen`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-28-21-01-00
|
|
+.. gh-issue: 89455
|
|
+.. nonce: qAKRrA
|
|
+.. section: Documentation
|
|
+
|
|
+Add missing documentation for the ``max_group_depth`` and
|
|
+``max_group_width`` parameters and the ``exceptions`` attribute of the
|
|
+:class:`traceback.TracebackException` class.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-28-19-08-42
|
|
+.. gh-issue: 89412
|
|
+.. nonce: j4cg7K
|
|
+.. section: Documentation
|
|
+
|
|
+Add missing documentation for the ``end_lineno`` and ``end_offset``
|
|
+attributes of the :class:`traceback.TracebackException` class.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-25-22-34-31
|
|
+.. gh-issue: 104943
|
|
+.. nonce: J2v1Pc
|
|
+.. section: Documentation
|
|
+
|
|
+Remove mentions of old Python versions in :class:`typing.NamedTuple`.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-14-12-11-28
|
|
+.. gh-issue: 67056
|
|
+.. nonce: nVC2Rf
|
|
+.. section: Documentation
|
|
+
|
|
+Document that the effect of registering or unregistering an :mod:`atexit`
|
|
+cleanup function from within a registered cleanup function is undefined.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-25-22-58-08
|
|
+.. gh-issue: 48241
|
|
+.. nonce: l1Gxxh
|
|
+.. section: Documentation
|
|
+
|
|
+Clarifying documentation about the url parameter to urllib.request.urlopen
|
|
+and urllib.request.Requst needing to be encoded properly.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-15-02-22-44
|
|
+.. gh-issue: 104494
|
|
+.. nonce: Bkrbfn
|
|
+.. section: Tests
|
|
+
|
|
+Update ``test_pack_configure_in`` and ``test_place_configure_in`` for
|
|
+changes to error message formatting in Tk 8.7.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-14-03-00-00
|
|
+.. gh-issue: 104461
|
|
+.. nonce: Rmex11
|
|
+.. section: Tests
|
|
+
|
|
+Run test_configure_screen on X11 only, since the ``DISPLAY`` environment
|
|
+variable and ``-screen`` option for toplevels are not useful on Tk for Win32
|
|
+or Aqua.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-08-00-50-23
|
|
+.. gh-issue: 103329
|
|
+.. nonce: M38tqF
|
|
+.. section: Tests
|
|
+
|
|
+Regression tests for the behaviour of ``unittest.mock.PropertyMock`` were
|
|
+added.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-02-11-22-36-10
|
|
+.. gh-issue: 85984
|
|
+.. nonce: EVXjT9
|
|
+.. section: Tests
|
|
+
|
|
+Utilize new "winsize" functions from termios in pty tests.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2022-11-06-18-42-38
|
|
+.. gh-issue: 75729
|
|
+.. nonce: uGYJrv
|
|
+.. section: Tests
|
|
+
|
|
+Fix the :func:`os.spawn* <os.spawnl>` tests failing on Windows when the
|
|
+working directory or interpreter path contains spaces.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-06-06-09-08-10
|
|
+.. gh-issue: 90005
|
|
+.. nonce: 8mmeJQ
|
|
+.. section: Build
|
|
+
|
|
+Fix a regression in :file:`configure` where we could end up unintentionally
|
|
+linking with ``libbsd``.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-04-10-56-14
|
|
+.. gh-issue: 104106
|
|
+.. nonce: -W9BJS
|
|
+.. section: Build
|
|
+
|
|
+Add gcc fallback of mkfifoat/mknodat for macOS. Patch by Dong-hee Na.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-02-11-05-31-05
|
|
+.. gh-issue: 99069
|
|
+.. nonce: X4LDvY
|
|
+.. section: Build
|
|
+
|
|
+Extended workaround defining ``static_assert`` when missing from the libc
|
|
+headers to all clang and gcc builds. In particular, this fixes building on
|
|
+macOS <= 10.10.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-31-16-14-31
|
|
+.. gh-issue: 105146
|
|
+.. nonce: gNjqq8
|
|
+.. section: Windows
|
|
+
|
|
+Updated the links at the end of the installer to point to Discourse rather
|
|
+than the mailing lists.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-18-22-46-03
|
|
+.. gh-issue: 104623
|
|
+.. nonce: HJZhm1
|
|
+.. section: Windows
|
|
+
|
|
+Update Windows installer to use SQLite 3.42.0.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-03-24-11-25-28
|
|
+.. gh-issue: 102997
|
|
+.. nonce: dredy2
|
|
+.. section: Windows
|
|
+
|
|
+Update Windows installer to use SQLite 3.41.2.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-03-18-21-38-00
|
|
+.. gh-issue: 88013
|
|
+.. nonce: Z3loxC
|
|
+.. section: Windows
|
|
+
|
|
+Fixed a bug where :exc:`TypeError` was raised when calling
|
|
+:func:`ntpath.realpath` with a bytes parameter in some cases.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-30-23-30-46
|
|
+.. gh-issue: 103142
|
|
+.. nonce: 55lMXQ
|
|
+.. section: macOS
|
|
+
|
|
+Update macOS installer to use OpenSSL 1.1.1u.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-18-22-31-49
|
|
+.. gh-issue: 104623
|
|
+.. nonce: 6h7Xfx
|
|
+.. section: macOS
|
|
+
|
|
+Update macOS installer to SQLite 3.42.0.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-03-24-11-20-47
|
|
+.. gh-issue: 102997
|
|
+.. nonce: ZgQkbq
|
|
+.. section: macOS
|
|
+
|
|
+Update macOS installer to SQLite 3.41.2.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-23-17-19-49
|
|
+.. gh-issue: 104719
|
|
+.. nonce: rvYXH-
|
|
+.. section: IDLE
|
|
+
|
|
+Remove IDLE's modification of tokenize.tabsize and test other uses of
|
|
+tokenize data and methods.
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-17-17-32-21
|
|
+.. gh-issue: 104499
|
|
+.. nonce: hNeqV4
|
|
+.. section: IDLE
|
|
+
|
|
+Fix completions for Tk Aqua 8.7 (currently blank).
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-05-17-15-11-11
|
|
+.. gh-issue: 104496
|
|
+.. nonce: wjav-y
|
|
+.. section: IDLE
|
|
+
|
|
+About prints both tcl and tk versions if different (expected someday).
|
|
+
|
|
+..
|
|
+
|
|
+.. date: 2023-04-30-20-01-18
|
|
+.. gh-issue: 88496
|
|
+.. nonce: y65vUb
|
|
+.. section: IDLE
|
|
+
|
|
+Fix IDLE test hang on macOS.
|
|
diff --git a/Misc/config_mingw b/Misc/config_mingw
|
|
new file mode 100755
|
|
index 0000000..9be43fd
|
|
--- /dev/null
|
|
+++ b/Misc/config_mingw
|
|
@@ -0,0 +1,15 @@
|
|
+# configure defaults for mingw* hosts
|
|
+
|
|
+# mingw functions to ignore
|
|
+ac_cv_func_ftruncate=ignore # implement it as _chsize
|
|
+
|
|
+# mingw-w64 functions to ignore
|
|
+ac_cv_func_truncate=ignore
|
|
+ac_cv_func_alarm=ignore
|
|
+
|
|
+# files to ignore
|
|
+ac_cv_file__dev_ptmx=ignore #NOTE: under MSYS environment device exist
|
|
+ac_cv_file__dev_ptc=no
|
|
+
|
|
+# force detection of winsock2 functionality - require wxp or newer
|
|
+ac_cv_func_getpeername=yes
|
|
diff --git a/Misc/cross_mingw32 b/Misc/cross_mingw32
|
|
new file mode 100755
|
|
index 0000000..03fde9e
|
|
--- /dev/null
|
|
+++ b/Misc/cross_mingw32
|
|
@@ -0,0 +1,11 @@
|
|
+# configure defaults for mingw32 host if cross-build
|
|
+
|
|
+ac_cv_little_endian_double=yes
|
|
+ac_cv_big_endian_double=no
|
|
+ac_cv_mixed_endian_double=no
|
|
+
|
|
+ac_cv_tanh_preserves_zero_sign=yes
|
|
+
|
|
+ac_cv_wchar_t_signed=no
|
|
+
|
|
+ac_cv_have_size_t_format=no
|
|
diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in
|
|
index 2602fe2..e0e048a 100644
|
|
--- a/Misc/python-config.sh.in
|
|
+++ b/Misc/python-config.sh.in
|
|
@@ -1,32 +1,44 @@
|
|
#!/bin/sh
|
|
|
|
-# Keep this script in sync with python-config.in
|
|
-
|
|
exit_with_usage ()
|
|
{
|
|
echo "Usage: $0 --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--help|--abiflags|--configdir|--embed"
|
|
- exit $1
|
|
+ exit 1
|
|
}
|
|
|
|
+# Really, python-config.py (and thus .sh) should be called directly, but
|
|
+# sometimes software (e.g. GDB) calls python-config.sh as if it were the
|
|
+# Python executable, passing python-config.py as the first argument.
|
|
+# Work around that oddness by ignoring any .py passed as first arg.
|
|
+case "$1" in
|
|
+ *.py)
|
|
+ shift
|
|
+ ;;
|
|
+esac
|
|
+
|
|
if [ "$1" = "" ] ; then
|
|
- exit_with_usage 1
|
|
+ exit_with_usage
|
|
fi
|
|
|
|
# Returns the actual prefix where this script was installed to.
|
|
installed_prefix ()
|
|
{
|
|
- RESULT=$(dirname $(cd $(dirname "$1") && pwd -P))
|
|
- if which readlink >/dev/null 2>&1 ; then
|
|
- if readlink -f "$RESULT" >/dev/null 2>&1; then
|
|
- RESULT=$(readlink -f "$RESULT")
|
|
- fi
|
|
+ local RESULT=$(dirname $(cd $(dirname "$1") && pwd -P))
|
|
+ if [ $(which readlink) ] ; then
|
|
+ RESULT=$(readlink -f "$RESULT")
|
|
+ fi
|
|
+ # Since we don't know where the output from this script will end up
|
|
+ # we keep all paths in Windows-land since MSYS2 can handle that
|
|
+ # while native tools can't handle paths in MSYS2-land.
|
|
+ if [ "$OSTYPE" = "msys" ]; then
|
|
+ RESULT=$(cd "$RESULT" && pwd -W)
|
|
fi
|
|
echo $RESULT
|
|
}
|
|
|
|
prefix_real=$(installed_prefix "$0")
|
|
|
|
-# Use sed to fix paths from their built-to locations to their installed-to
|
|
+# Use sed to fix paths from their built-to locations to their installed to
|
|
# locations. Keep prefix & exec_prefix using their original values in case
|
|
# they are referenced in other configure variables, to prevent double
|
|
# substitution, issue #22140.
|
|
@@ -41,13 +53,17 @@ LIBM="@LIBM@"
|
|
LIBC="@LIBC@"
|
|
SYSLIBS="$LIBM $LIBC"
|
|
ABIFLAGS="@ABIFLAGS@"
|
|
+# Protect against lack of substitution.
|
|
+if [ "$ABIFLAGS" = "@""ABIFLAGS""@" ] ; then
|
|
+ ABIFLAGS=
|
|
+fi
|
|
LIBS="@LIBPYTHON@ @LIBS@ $SYSLIBS"
|
|
LIBS_EMBED="-lpython${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS"
|
|
BASECFLAGS="@BASECFLAGS@"
|
|
-LDLIBRARY="@LDLIBRARY@"
|
|
OPT="@OPT@"
|
|
PY_ENABLE_SHARED="@PY_ENABLE_SHARED@"
|
|
LDVERSION="@LDVERSION@"
|
|
+LDLIBRARY="@LDLIBRARY@"
|
|
LIBDEST=${prefix_real}/lib/python${VERSION}
|
|
LIBPL=$(echo "@LIBPL@" | sed "s#$prefix#$prefix_real#")
|
|
SO="@EXT_SUFFIX@"
|
|
@@ -61,7 +77,7 @@ for ARG in $*
|
|
do
|
|
case $ARG in
|
|
--help)
|
|
- exit_with_usage 0
|
|
+ exit_with_usage
|
|
;;
|
|
--embed)
|
|
PY_EMBED=1
|
|
@@ -69,7 +85,7 @@ do
|
|
--prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--abiflags|--configdir)
|
|
;;
|
|
*)
|
|
- exit_with_usage 1
|
|
+ exit_with_usage
|
|
;;
|
|
esac
|
|
done
|
|
@@ -80,37 +96,37 @@ fi
|
|
|
|
for ARG in "$@"
|
|
do
|
|
- case "$ARG" in
|
|
+ case $ARG in
|
|
--prefix)
|
|
- echo "$prefix_real"
|
|
+ echo -ne "$prefix_real"
|
|
;;
|
|
--exec-prefix)
|
|
- echo "$exec_prefix_real"
|
|
+ echo -ne "$exec_prefix_real "
|
|
;;
|
|
--includes)
|
|
- echo "$INCDIR $PLATINCDIR"
|
|
+ echo -ne "$INCDIR $PLATINCDIR"
|
|
;;
|
|
--cflags)
|
|
- echo "$INCDIR $PLATINCDIR $BASECFLAGS $CFLAGS $OPT"
|
|
+ echo -ne "$INCDIR $PLATINCDIR $BASECFLAGS $CFLAGS $OPT"
|
|
;;
|
|
--libs)
|
|
- echo "$LIBS"
|
|
+ echo -ne "$LIBS"
|
|
;;
|
|
--ldflags)
|
|
LIBPLUSED=
|
|
if [ "$PY_ENABLE_SHARED" = "0" ] ; then
|
|
LIBPLUSED="-L$LIBPL"
|
|
fi
|
|
- echo "$LIBPLUSED -L$libdir $LIBS"
|
|
+ echo -ne "$LIBPLUSED -L$libdir $LIBS "
|
|
;;
|
|
--extension-suffix)
|
|
- echo "$SO"
|
|
+ echo -ne "$SO "
|
|
;;
|
|
--abiflags)
|
|
- echo "$ABIFLAGS"
|
|
+ echo -ne "$ABIFLAGS "
|
|
;;
|
|
--configdir)
|
|
- echo "$LIBPL"
|
|
+ echo -ne "$LIBPL "
|
|
;;
|
|
esac
|
|
done
|
|
diff --git a/Misc/python.pc.in b/Misc/python.pc.in
|
|
index 87e04de..3900190 100644
|
|
--- a/Misc/python.pc.in
|
|
+++ b/Misc/python.pc.in
|
|
@@ -9,5 +9,5 @@ Description: Build a C extension for Python
|
|
Requires:
|
|
Version: @VERSION@
|
|
Libs.private: @LIBS@
|
|
-Libs:
|
|
+Libs: -L${libdir} -lpython@VERSION@@ABIFLAGS@
|
|
Cflags: -I${includedir}/python@VERSION@@ABIFLAGS@
|
|
diff --git a/Modules/Setup.bootstrap.in b/Modules/Setup.bootstrap.in
|
|
index e3e9b96..6986290 100644
|
|
--- a/Modules/Setup.bootstrap.in
|
|
+++ b/Modules/Setup.bootstrap.in
|
|
@@ -8,15 +8,15 @@
|
|
# module C APIs are used in core
|
|
atexit atexitmodule.c
|
|
faulthandler faulthandler.c
|
|
-posix posixmodule.c
|
|
-_signal signalmodule.c
|
|
+@INITSYS@ posixmodule.c
|
|
+_signal signalmodule.c -lws2_32
|
|
_tracemalloc _tracemalloc.c
|
|
|
|
# modules used by importlib, deepfreeze, freeze, runpy, and sysconfig
|
|
_codecs _codecsmodule.c
|
|
_collections _collectionsmodule.c
|
|
errno errnomodule.c
|
|
-_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c
|
|
+_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
|
|
itertools itertoolsmodule.c
|
|
_sre _sre/sre.c
|
|
_thread _threadmodule.c
|
|
@@ -33,3 +33,8 @@ _symtable symtablemodule.c
|
|
|
|
# for systems without $HOME env, used by site._getuserbase()
|
|
@MODULE_PWD_TRUE@pwd pwdmodule.c
|
|
+
|
|
+# build-in modules for windows platform:
|
|
+@USE_WIN32_MODULE@winreg ../PC/winreg.c
|
|
+@MODULE_MSVCRT_TRUE@msvcrt -DPy_BUILD_CORE ../PC/msvcrtmodule.c
|
|
+@MODULE__WINAPI_TRUE@_winapi _winapi.c
|
|
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
|
|
index fc73264..6ed71fa 100644
|
|
--- a/Modules/_ctypes/_ctypes.c
|
|
+++ b/Modules/_ctypes/_ctypes.c
|
|
@@ -3403,6 +3403,18 @@ static PPROC FindAddress(void *handle, const char *name, PyObject *type)
|
|
mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
|
|
if (!mangled_name)
|
|
return NULL;
|
|
+ /* Issue: for stdcall decorated export functions MSVC compiler adds
|
|
+ * underscore, but GCC compiler create them without. This is
|
|
+ * visible by example for _ctypes_test.pyd module.
|
|
+ * As well functions from system libraries are without underscore.
|
|
+ * Solutions:
|
|
+ * - If a python module is build with gcc option --add-stdcall-alias
|
|
+ * the module will contain XXX as alias for function XXX@ as result
|
|
+ * first search in this method will succeed.
|
|
+ * - Distutil may use compiler to create def-file, to modify it as
|
|
+ * add underscore alias and with new def file to create module.
|
|
+ * - Or may be just to search for function without underscore.
|
|
+ */
|
|
for (i = 0; i < 32; ++i) {
|
|
sprintf(mangled_name, "_%s@%d", name, i*4);
|
|
Py_BEGIN_ALLOW_THREADS
|
|
@@ -3410,6 +3422,13 @@ static PPROC FindAddress(void *handle, const char *name, PyObject *type)
|
|
Py_END_ALLOW_THREADS
|
|
if (address)
|
|
return address;
|
|
+ /* search for function without underscore as weel */
|
|
+ sprintf(mangled_name, "%s@%d", name, i*4);
|
|
+ Py_BEGIN_ALLOW_THREADS
|
|
+ address = (PPROC)GetProcAddress(handle, mangled_name);
|
|
+ Py_END_ALLOW_THREADS
|
|
+ if (address)
|
|
+ return address;
|
|
}
|
|
return NULL;
|
|
#endif
|
|
diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c
|
|
index e6440fa..f42714a 100644
|
|
--- a/Modules/_gdbmmodule.c
|
|
+++ b/Modules/_gdbmmodule.c
|
|
@@ -12,7 +12,7 @@
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
|
|
-#if defined(WIN32) && !defined(__CYGWIN__)
|
|
+#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
|
#include "gdbmerrno.h"
|
|
extern const char * gdbm_strerror(gdbm_error);
|
|
#endif
|
|
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
|
|
index 4496609..80cc6f9 100644
|
|
--- a/Modules/_io/fileio.c
|
|
+++ b/Modules/_io/fileio.c
|
|
@@ -20,6 +20,7 @@
|
|
#endif
|
|
#include <stddef.h> /* For offsetof */
|
|
#include "_iomodule.h"
|
|
+#include "iscygpty.h"
|
|
|
|
/*
|
|
* Known likely problems:
|
|
@@ -1129,7 +1130,7 @@ _io_FileIO_isatty_impl(fileio *self)
|
|
return err_closed();
|
|
Py_BEGIN_ALLOW_THREADS
|
|
_Py_BEGIN_SUPPRESS_IPH
|
|
- res = isatty(self->fd);
|
|
+ res = isatty(self->fd) || is_cygpty(self->fd);
|
|
_Py_END_SUPPRESS_IPH
|
|
Py_END_ALLOW_THREADS
|
|
return PyBool_FromLong(res);
|
|
diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c
|
|
index 23c38e1..dfb6c7e 100644
|
|
--- a/Modules/_localemodule.c
|
|
+++ b/Modules/_localemodule.c
|
|
@@ -12,6 +12,13 @@ This software comes with no warranty. Use at your own risk.
|
|
#define PY_SSIZE_T_CLEAN
|
|
#include "Python.h"
|
|
#include "pycore_fileutils.h"
|
|
+#ifdef __MINGW32__
|
|
+/* The header libintl.h and library libintl may exist on mingw host.
|
|
+ * To be compatible with MSVC build we has to undef some defines.
|
|
+ */
|
|
+#undef HAVE_LIBINTL_H
|
|
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
|
|
+#endif
|
|
|
|
#include <stdio.h>
|
|
#include <locale.h>
|
|
diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c
|
|
index 0809c24..bbb1b38 100644
|
|
--- a/Modules/_multiprocessing/multiprocessing.c
|
|
+++ b/Modules/_multiprocessing/multiprocessing.c
|
|
@@ -172,7 +172,7 @@ static PyMethodDef module_methods[] = {
|
|
_MULTIPROCESSING_RECV_METHODDEF
|
|
_MULTIPROCESSING_SEND_METHODDEF
|
|
#endif
|
|
-#if !defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__)
|
|
+#if defined(MS_WINDOWS) || (!defined(POSIX_SEMAPHORES_NOT_ENABLED) && !defined(__ANDROID__))
|
|
_MULTIPROCESSING_SEM_UNLINK_METHODDEF
|
|
#endif
|
|
{NULL}
|
|
diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h
|
|
index 3a8314b..c07cfe8 100644
|
|
--- a/Modules/_multiprocessing/multiprocessing.h
|
|
+++ b/Modules/_multiprocessing/multiprocessing.h
|
|
@@ -21,7 +21,10 @@
|
|
# endif
|
|
# define SEM_HANDLE HANDLE
|
|
# define SEM_VALUE_MAX LONG_MAX
|
|
-# define HAVE_MP_SEMAPHORE
|
|
+# define HAVE_MP_SEMAPHORE
|
|
+# if defined(HAVE_SEM_OPEN) && defined(_POSIX_THREADS)
|
|
+# include <semaphore.h>
|
|
+# endif
|
|
#else
|
|
# include <fcntl.h> /* O_CREAT and O_EXCL */
|
|
# if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
|
|
diff --git a/Modules/_winapi.c b/Modules/_winapi.c
|
|
index f6bb07f..56f3306 100644
|
|
--- a/Modules/_winapi.c
|
|
+++ b/Modules/_winapi.c
|
|
@@ -41,7 +41,9 @@
|
|
|
|
#define WINDOWS_LEAN_AND_MEAN
|
|
#include "windows.h"
|
|
+#if defined(Py_DEBUG)
|
|
#include <crtdbg.h>
|
|
+#endif
|
|
#include "winreparse.h"
|
|
|
|
#if defined(MS_WIN32) && !defined(MS_WIN64)
|
|
@@ -957,7 +959,7 @@ getattributelist(PyObject *obj, const char *name, AttributeList *attribute_list)
|
|
DWORD err;
|
|
BOOL result;
|
|
PyObject *value;
|
|
- Py_ssize_t handle_list_size;
|
|
+ Py_ssize_t handle_list_size = 0;
|
|
DWORD attribute_count = 0;
|
|
SIZE_T attribute_list_size = 0;
|
|
|
|
diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c
|
|
index e5b96be..0e5ab45 100644
|
|
--- a/Modules/_xxsubinterpretersmodule.c
|
|
+++ b/Modules/_xxsubinterpretersmodule.c
|
|
@@ -1765,7 +1765,7 @@ PyDoc_STRVAR(channelid_doc,
|
|
"A channel ID identifies a channel and may be used as an int.");
|
|
|
|
static PyTypeObject ChannelIDtype = {
|
|
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
|
+ PyVarObject_HEAD_INIT(NULL, 0)
|
|
"_xxsubinterpreters.ChannelID", /* tp_name */
|
|
sizeof(channelid), /* tp_basicsize */
|
|
0, /* tp_itemsize */
|
|
diff --git a/Modules/getpath.c b/Modules/getpath.c
|
|
index bc730fc..0419c2a 100644
|
|
--- a/Modules/getpath.c
|
|
+++ b/Modules/getpath.c
|
|
@@ -54,6 +54,25 @@
|
|
|
|
/* HELPER FUNCTIONS for getpath.py */
|
|
|
|
+static PyObject *
|
|
+getpath_normpath(PyObject *Py_UNUSED(self), PyObject *args)
|
|
+{
|
|
+ PyObject *r = NULL;
|
|
+ PyObject *pathobj;
|
|
+ wchar_t *path;
|
|
+ if (!PyArg_ParseTuple(args, "U", &pathobj)) {
|
|
+ return NULL;
|
|
+ }
|
|
+ Py_ssize_t len;
|
|
+ wchar_t *buffer = PyUnicode_AsWideCharString(pathobj, &len);
|
|
+ if (!buffer) {
|
|
+ return NULL;
|
|
+ }
|
|
+ r = PyUnicode_FromWideChar(_Py_normpath(buffer, len), -1);
|
|
+ PyMem_Free(buffer);
|
|
+ return r;
|
|
+}
|
|
+
|
|
static PyObject *
|
|
getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args)
|
|
{
|
|
@@ -88,6 +107,12 @@ getpath_basename(PyObject *Py_UNUSED(self), PyObject *args)
|
|
}
|
|
Py_ssize_t end = PyUnicode_GET_LENGTH(path);
|
|
Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1);
|
|
+#ifdef ALTSEP
|
|
+ if (pos < 0) {
|
|
+ // try using altsep
|
|
+ pos = PyUnicode_FindChar(path, ALTSEP, 0, end, -1);
|
|
+ }
|
|
+#endif
|
|
if (pos < 0) {
|
|
return Py_NewRef(path);
|
|
}
|
|
@@ -104,6 +129,12 @@ getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args)
|
|
}
|
|
Py_ssize_t end = PyUnicode_GET_LENGTH(path);
|
|
Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1);
|
|
+#ifdef ALTSEP
|
|
+ if (pos < 0) {
|
|
+ // try using altsep
|
|
+ pos = PyUnicode_FindChar(path, ALTSEP, 0, end, -1);
|
|
+ }
|
|
+#endif
|
|
if (pos < 0) {
|
|
return PyUnicode_FromStringAndSize(NULL, 0);
|
|
}
|
|
@@ -513,6 +544,7 @@ getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args)
|
|
|
|
|
|
static PyMethodDef getpath_methods[] = {
|
|
+ {"normpath", getpath_normpath, METH_VARARGS, NULL},
|
|
{"abspath", getpath_abspath, METH_VARARGS, NULL},
|
|
{"basename", getpath_basename, METH_VARARGS, NULL},
|
|
{"dirname", getpath_dirname, METH_VARARGS, NULL},
|
|
@@ -884,6 +916,11 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config)
|
|
#else
|
|
!decode_to_dict(dict, "os_name", "posix") ||
|
|
#endif
|
|
+#ifdef __MINGW32__
|
|
+ !int_to_dict(dict, "is_mingw", 1) ||
|
|
+#else
|
|
+ !int_to_dict(dict, "is_mingw", 0) ||
|
|
+#endif
|
|
#ifdef WITH_NEXT_FRAMEWORK
|
|
!int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 1) ||
|
|
#else
|
|
@@ -910,6 +947,9 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config)
|
|
!funcs_to_dict(dict, config->pathconfig_warnings) ||
|
|
#ifndef MS_WINDOWS
|
|
PyDict_SetItemString(dict, "winreg", Py_None) < 0 ||
|
|
+#endif
|
|
+#ifdef __MINGW32__
|
|
+ !env_to_dict(dict, "ENV_MSYSTEM", 0) ||
|
|
#endif
|
|
PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins()) < 0
|
|
) {
|
|
diff --git a/Modules/getpath.py b/Modules/getpath.py
|
|
index 74f918c..c98cb1f 100644
|
|
--- a/Modules/getpath.py
|
|
+++ b/Modules/getpath.py
|
|
@@ -30,6 +30,7 @@
|
|
|
|
# ** Values known at compile time **
|
|
# os_name -- [in] one of 'nt', 'posix', 'darwin'
|
|
+# is_mingw -- [in] True if targeting MinGW
|
|
# PREFIX -- [in] sysconfig.get_config_var(...)
|
|
# EXEC_PREFIX -- [in] sysconfig.get_config_var(...)
|
|
# PYTHONPATH -- [in] sysconfig.get_config_var(...)
|
|
@@ -51,6 +52,7 @@
|
|
# ENV_PYTHONHOME -- [in] getenv(...)
|
|
# ENV_PYTHONEXECUTABLE -- [in] getenv(...)
|
|
# ENV___PYVENV_LAUNCHER__ -- [in] getenv(...)
|
|
+# ENV_MSYSTEM -- [in] getenv(...)
|
|
|
|
# ** Values calculated at runtime **
|
|
# config -- [in/out] dict of the PyConfig structure
|
|
@@ -185,8 +187,27 @@
|
|
ZIP_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}{VERSION_MINOR}.zip'
|
|
DELIM = ':'
|
|
SEP = '/'
|
|
+ ALTSEP = None
|
|
|
|
-elif os_name == 'nt':
|
|
+elif os_name == 'nt' and is_mingw:
|
|
+ BUILDDIR_TXT = 'pybuilddir.txt'
|
|
+ BUILD_LANDMARK = 'Modules/Setup.local'
|
|
+ DEFAULT_PROGRAM_NAME = f'python{VERSION_MAJOR}'
|
|
+ STDLIB_SUBDIR = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}'
|
|
+ STDLIB_LANDMARKS = [f'{STDLIB_SUBDIR}/os.py', f'{STDLIB_SUBDIR}/os.pyc']
|
|
+ PLATSTDLIB_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}/lib-dynload'
|
|
+ BUILDSTDLIB_LANDMARKS = ['Lib/os.py']
|
|
+ VENV_LANDMARK = 'pyvenv.cfg'
|
|
+ ZIP_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}{VERSION_MINOR}.zip'
|
|
+ DELIM = ';'
|
|
+ if ENV_MSYSTEM:
|
|
+ SEP = '/'
|
|
+ ALTSEP = '\\'
|
|
+ else:
|
|
+ SEP = '\\'
|
|
+ ALTSEP = '/'
|
|
+
|
|
+elif os_name == 'nt': # MSVC
|
|
BUILDDIR_TXT = 'pybuilddir.txt'
|
|
BUILD_LANDMARK = f'{VPATH}\\Modules\\Setup.local'
|
|
DEFAULT_PROGRAM_NAME = f'python'
|
|
@@ -199,6 +220,7 @@
|
|
WINREG_KEY = f'SOFTWARE\\Python\\PythonCore\\{PYWINVER}\\PythonPath'
|
|
DELIM = ';'
|
|
SEP = '\\'
|
|
+ ALTSEP = '/'
|
|
|
|
|
|
# ******************************************************************************
|
|
@@ -211,6 +233,8 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
return prefix
|
|
prefix = dirname(prefix)
|
|
|
|
+def _normpath(p):
|
|
+ return normpath(p) if p is not None else None
|
|
|
|
# ******************************************************************************
|
|
# READ VARIABLES FROM config
|
|
@@ -263,10 +287,10 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
if not executable:
|
|
executable = real_executable
|
|
|
|
-if not executable and SEP in program_name:
|
|
+if not executable and (SEP in program_name or
|
|
+ (ALTSEP and ALTSEP in program_name)):
|
|
# Resolve partial path program_name against current directory
|
|
executable = abspath(program_name)
|
|
-
|
|
if not executable:
|
|
# All platforms default to real_executable if known at this
|
|
# stage. POSIX does not set this value.
|
|
@@ -497,15 +521,15 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
except (FileNotFoundError, PermissionError):
|
|
if isfile(joinpath(real_executable_dir, BUILD_LANDMARK)):
|
|
build_prefix = joinpath(real_executable_dir, VPATH)
|
|
- if os_name == 'nt':
|
|
+ if os_name == 'nt' and not is_mingw:
|
|
# QUIRK: Windows builds need platstdlib_dir to be the executable
|
|
# dir. Normally the builddir marker handles this, but in this
|
|
# case we need to correct manually.
|
|
platstdlib_dir = real_executable_dir
|
|
|
|
if build_prefix:
|
|
- if os_name == 'nt':
|
|
- # QUIRK: No searching for more landmarks on Windows
|
|
+ if os_name == 'nt' and not is_mingw:
|
|
+ # QUIRK: No searching for more landmarks on MSVC
|
|
build_stdlib_prefix = build_prefix
|
|
else:
|
|
build_stdlib_prefix = search_up(build_prefix, *BUILDSTDLIB_LANDMARKS)
|
|
@@ -552,6 +576,9 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
# First try to detect prefix by looking alongside our runtime library, if known
|
|
if library and not prefix:
|
|
library_dir = dirname(library)
|
|
+ if os_name == 'nt' and is_mingw:
|
|
+ # QUIRK: On Windows, mingw Python DLLs are in the bin directory
|
|
+ library_dir = joinpath(library_dir, '..')
|
|
if ZIP_LANDMARK:
|
|
if os_name == 'nt':
|
|
# QUIRK: Windows does not search up for ZIP file
|
|
@@ -597,7 +624,7 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
|
|
# Detect exec_prefix by searching from executable for the platstdlib_dir
|
|
if PLATSTDLIB_LANDMARK and not exec_prefix:
|
|
- if os_name == 'nt':
|
|
+ if os_name == 'nt' and (not is_mingw):
|
|
# QUIRK: Windows always assumed these were the same
|
|
# gh-100320: Our PYDs are assumed to be relative to the Lib directory
|
|
# (that is, prefix) rather than the executable (that is, executable_dir)
|
|
@@ -607,7 +634,7 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
if not exec_prefix and EXEC_PREFIX:
|
|
exec_prefix = EXEC_PREFIX
|
|
if not exec_prefix or not isdir(joinpath(exec_prefix, PLATSTDLIB_LANDMARK)):
|
|
- if os_name == 'nt':
|
|
+ if os_name == 'nt' and (not is_mingw):
|
|
# QUIRK: If DLLs is missing on Windows, don't warn, just assume
|
|
# that they're in exec_prefix
|
|
if not platstdlib_dir:
|
|
@@ -645,7 +672,7 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
|
|
if py_setpath:
|
|
# If Py_SetPath was called then it overrides any existing search path
|
|
- config['module_search_paths'] = py_setpath.split(DELIM)
|
|
+ config['module_search_paths'] = [_normpath(p) for p in py_setpath.split(DELIM)]
|
|
config['module_search_paths_set'] = 1
|
|
|
|
elif not pythonpath_was_set:
|
|
@@ -660,7 +687,7 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
pythonpath.append(abspath(p))
|
|
|
|
# Then add the default zip file
|
|
- if os_name == 'nt':
|
|
+ if os_name == 'nt' and (not is_mingw):
|
|
# QUIRK: Windows uses the library directory rather than the prefix
|
|
if library:
|
|
library_dir = dirname(library)
|
|
@@ -673,7 +700,7 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
else:
|
|
pythonpath.append(joinpath(prefix, ZIP_LANDMARK))
|
|
|
|
- if os_name == 'nt' and use_environment and winreg:
|
|
+ if (not is_mingw) and os_name == 'nt' and use_environment and winreg:
|
|
# QUIRK: Windows also lists paths in the registry. Paths are stored
|
|
# as the default value of each subkey of
|
|
# {HKCU,HKLM}\Software\Python\PythonCore\{winver}\PythonPath
|
|
@@ -714,7 +741,7 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
if not platstdlib_dir and exec_prefix:
|
|
platstdlib_dir = joinpath(exec_prefix, PLATSTDLIB_LANDMARK)
|
|
|
|
- if os_name == 'nt':
|
|
+ if os_name == 'nt' and (not is_mingw):
|
|
# QUIRK: Windows generates paths differently
|
|
if platstdlib_dir:
|
|
pythonpath.append(platstdlib_dir)
|
|
@@ -732,7 +759,7 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
if platstdlib_dir:
|
|
pythonpath.append(platstdlib_dir)
|
|
|
|
- config['module_search_paths'] = pythonpath
|
|
+ config['module_search_paths'] = [_normpath(p) for p in pythonpath]
|
|
config['module_search_paths_set'] = 1
|
|
|
|
|
|
@@ -742,8 +769,8 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
|
|
# QUIRK: Non-Windows replaces prefix/exec_prefix with defaults when running
|
|
# in build directory. This happens after pythonpath calculation.
|
|
-if os_name != 'nt' and build_prefix:
|
|
- prefix = config.get('prefix') or PREFIX
|
|
+if (os_name != 'nt' or is_mingw) and build_prefix:
|
|
+ prefix = config.get('prefix') or abspath(PREFIX)
|
|
exec_prefix = config.get('exec_prefix') or EXEC_PREFIX or prefix
|
|
|
|
|
|
@@ -767,23 +794,23 @@ def search_up(prefix, *landmarks, test=isfile):
|
|
warn("unsupported 'import' line in ._pth file")
|
|
else:
|
|
pythonpath.append(joinpath(pth_dir, line))
|
|
- config['module_search_paths'] = pythonpath
|
|
+ config['module_search_paths'] = [_normpath(p) for p in pythonpath]
|
|
config['module_search_paths_set'] = 1
|
|
|
|
# ******************************************************************************
|
|
# UPDATE config FROM CALCULATED VALUES
|
|
# ******************************************************************************
|
|
|
|
-config['program_name'] = program_name
|
|
-config['home'] = home
|
|
-config['executable'] = executable
|
|
-config['base_executable'] = base_executable
|
|
-config['prefix'] = prefix
|
|
-config['exec_prefix'] = exec_prefix
|
|
-config['base_prefix'] = base_prefix or prefix
|
|
-config['base_exec_prefix'] = base_exec_prefix or exec_prefix
|
|
+config['program_name'] = _normpath(program_name)
|
|
+config['home'] = _normpath(home)
|
|
+config['executable'] = _normpath(executable)
|
|
+config['base_executable'] = _normpath(base_executable)
|
|
+config['prefix'] = _normpath(prefix)
|
|
+config['exec_prefix'] = _normpath(exec_prefix)
|
|
+config['base_prefix'] = _normpath(base_prefix or prefix)
|
|
+config['base_exec_prefix'] = _normpath(base_exec_prefix or exec_prefix)
|
|
|
|
-config['platlibdir'] = platlibdir
|
|
+config['platlibdir'] = _normpath(platlibdir)
|
|
# test_embed expects empty strings, not None
|
|
-config['stdlib_dir'] = stdlib_dir or ''
|
|
-config['platstdlib_dir'] = platstdlib_dir or ''
|
|
+config['stdlib_dir'] = _normpath(stdlib_dir or '')
|
|
+config['platstdlib_dir'] = _normpath(platstdlib_dir or '')
|
|
diff --git a/Modules/main.c b/Modules/main.c
|
|
index 6904e3f..5c8708e 100644
|
|
--- a/Modules/main.c
|
|
+++ b/Modules/main.c
|
|
@@ -7,6 +7,7 @@
|
|
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
|
|
#include "pycore_pylifecycle.h" // _Py_PreInitializeFromPyArgv()
|
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
|
+#include "iscygpty.h"
|
|
|
|
/* Includes for exit_sigint() */
|
|
#include <stdio.h> // perror()
|
|
@@ -92,7 +93,7 @@ static inline int config_run_code(const PyConfig *config)
|
|
static int
|
|
stdin_is_interactive(const PyConfig *config)
|
|
{
|
|
- return (isatty(fileno(stdin)) || config->interactive);
|
|
+ return (isatty(fileno(stdin)) || config->interactive || is_cygpty(fileno(stdin)));
|
|
}
|
|
|
|
|
|
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
|
|
index a01662d..c2362a6 100644
|
|
--- a/Modules/posixmodule.c
|
|
+++ b/Modules/posixmodule.c
|
|
@@ -50,6 +50,7 @@
|
|
#ifdef __ANDROID__
|
|
# undef HAVE_FACCESSAT
|
|
#endif
|
|
+#include "iscygpty.h"
|
|
|
|
#include <stdio.h> // ctermid()
|
|
#include <stdlib.h> // system()
|
|
@@ -350,6 +351,32 @@ corresponding Unix manual entries for more information on calls.");
|
|
# define HAVE_CWAIT 1
|
|
# define HAVE_FSYNC 1
|
|
# define fsync _commit
|
|
+# elif defined(__MINGW32__) /* GCC for windows hosts */
|
|
+/* getlogin is detected by configure on mingw-w64 */
|
|
+# undef HAVE_GETLOGIN
|
|
+/* opendir is detected by configure on mingw-w64, and for some reason
|
|
+things don't work as expected. For example, os.listdir always returns
|
|
+the cwd's directory listing instead of the one specified. By
|
|
+un-defining, this, os.listdir will use the one which uses native
|
|
+windows API. */
|
|
+# undef HAVE_OPENDIR
|
|
+/*# define HAVE_GETCWD 1 - detected by configure*/
|
|
+# define HAVE_GETPPID 1
|
|
+# define HAVE_GETLOGIN 1
|
|
+# define HAVE_SPAWNV 1
|
|
+# define HAVE_WSPAWNV 1
|
|
+# define HAVE_WEXECV 1
|
|
+/*# define HAVE_EXECV 1 - detected by configure*/
|
|
+# define HAVE_PIPE 1
|
|
+# define HAVE_POPEN 1
|
|
+# define HAVE_SYSTEM 1
|
|
+# define HAVE_CWAIT 1
|
|
+# define HAVE_FSYNC 1
|
|
+# define fsync _commit
|
|
+# include <winioctl.h>
|
|
+# ifndef _MAX_ENV
|
|
+# define _MAX_ENV 32767
|
|
+# endif
|
|
# endif /* _MSC_VER */
|
|
#endif /* ! __WATCOMC__ || __QNX__ */
|
|
|
|
@@ -428,7 +455,7 @@ extern char *ctermid_r(char *);
|
|
# endif
|
|
#endif
|
|
|
|
-#ifdef _MSC_VER
|
|
+#ifdef MS_WINDOWS
|
|
# ifdef HAVE_DIRECT_H
|
|
# include <direct.h>
|
|
# endif
|
|
@@ -439,7 +466,7 @@ extern char *ctermid_r(char *);
|
|
# include <process.h>
|
|
# endif
|
|
# include <malloc.h>
|
|
-#endif /* _MSC_VER */
|
|
+#endif /* MS_WINDOWS */
|
|
|
|
#ifndef MAXPATHLEN
|
|
# if defined(PATH_MAX) && PATH_MAX > 1024
|
|
@@ -1593,9 +1620,9 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
|
|
** man environ(7).
|
|
*/
|
|
#include <crt_externs.h>
|
|
-#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
|
|
+#elif !defined(MS_WINDOWS) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__))
|
|
extern char **environ;
|
|
-#endif /* !_MSC_VER */
|
|
+#endif /* !MS_WINDOWS */
|
|
|
|
static PyObject *
|
|
convertenviron(void)
|
|
@@ -3815,6 +3842,7 @@ posix_getcwd(int use_bytes)
|
|
return PyErr_SetFromWindowsErr(0);
|
|
}
|
|
|
|
+ Py_NormalizeSepsW(wbuf2);
|
|
PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len);
|
|
if (wbuf2 != wbuf) {
|
|
PyMem_RawFree(wbuf2);
|
|
@@ -4419,6 +4447,7 @@ os__getfinalpathname_impl(PyObject *module, path_t *path)
|
|
target_path = tmp;
|
|
}
|
|
|
|
+ Py_NormalizeSepsW(target_path);
|
|
result = PyUnicode_FromWideChar(target_path, result_length);
|
|
if (result && path->narrow) {
|
|
Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
|
|
@@ -5467,7 +5496,7 @@ os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
|
|
/*[clinic end generated code: output=cfcac69d027b82cf input=2fbd62a2f228f8f4]*/
|
|
{
|
|
#ifdef MS_WINDOWS
|
|
- HANDLE hFile;
|
|
+ HANDLE hFile = 0;
|
|
FILETIME atime, mtime;
|
|
#else
|
|
int result;
|
|
@@ -10194,7 +10223,7 @@ os_isatty_impl(PyObject *module, int fd)
|
|
int return_value;
|
|
Py_BEGIN_ALLOW_THREADS
|
|
_Py_BEGIN_SUPPRESS_IPH
|
|
- return_value = isatty(fd);
|
|
+ return_value = isatty(fd) || is_cygpty(fd);
|
|
_Py_END_SUPPRESS_IPH
|
|
Py_END_ALLOW_THREADS
|
|
return return_value;
|
|
@@ -14682,7 +14711,7 @@ os__add_dll_directory_impl(PyObject *module, path_t *path)
|
|
loaded. */
|
|
Py_BEGIN_ALLOW_THREADS
|
|
if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
|
|
- !(AddDllDirectory = (PAddDllDirectory)GetProcAddress(
|
|
+ !(AddDllDirectory = (PAddDllDirectory)(void *)GetProcAddress(
|
|
hKernel32, "AddDllDirectory")) ||
|
|
!(cookie = (*AddDllDirectory)(path->wide))) {
|
|
err = GetLastError();
|
|
@@ -14732,7 +14761,7 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie)
|
|
loaded. */
|
|
Py_BEGIN_ALLOW_THREADS
|
|
if (!(hKernel32 = GetModuleHandleW(L"kernel32")) ||
|
|
- !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress(
|
|
+ !(RemoveDllDirectory = (PRemoveDllDirectory)(void *)GetProcAddress(
|
|
hKernel32, "RemoveDllDirectory")) ||
|
|
!(*RemoveDllDirectory)(cookieValue)) {
|
|
err = GetLastError();
|
|
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
|
|
index 4eea928..6be3582 100644
|
|
--- a/Modules/selectmodule.c
|
|
+++ b/Modules/selectmodule.c
|
|
@@ -146,9 +146,9 @@ seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
|
|
v = PyObject_AsFileDescriptor( o );
|
|
if (v == -1) goto finally;
|
|
|
|
-#if defined(_MSC_VER)
|
|
+#if defined(MS_WIN32)
|
|
max = 0; /* not used for Win32 */
|
|
-#else /* !_MSC_VER */
|
|
+#else /* !MS_WIN32 */
|
|
if (!_PyIsSelectable_fd(v)) {
|
|
PyErr_SetString(PyExc_ValueError,
|
|
"filedescriptor out of range in select()");
|
|
@@ -156,7 +156,7 @@ seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
|
|
}
|
|
if (v > max)
|
|
max = v;
|
|
-#endif /* _MSC_VER */
|
|
+#endif /* MS_WIN32 */
|
|
FD_SET(v, set);
|
|
|
|
/* add object and its file descriptor to the list */
|
|
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
|
|
index 65d0e10..d1bfe3d 100644
|
|
--- a/Modules/socketmodule.c
|
|
+++ b/Modules/socketmodule.c
|
|
@@ -274,7 +274,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\
|
|
# endif
|
|
|
|
/* Macros based on the IPPROTO enum, see: https://bugs.python.org/issue29515 */
|
|
-#ifdef MS_WINDOWS
|
|
+#ifdef _MSC_VER
|
|
#define IPPROTO_ICMP IPPROTO_ICMP
|
|
#define IPPROTO_IGMP IPPROTO_IGMP
|
|
#define IPPROTO_GGP IPPROTO_GGP
|
|
@@ -305,7 +305,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\
|
|
#define IPPROTO_PGM IPPROTO_PGM // WinSock2 only
|
|
#define IPPROTO_L2TP IPPROTO_L2TP // WinSock2 only
|
|
#define IPPROTO_SCTP IPPROTO_SCTP // WinSock2 only
|
|
-#endif /* MS_WINDOWS */
|
|
+#endif /* _MSC_VER */
|
|
|
|
/* Provides the IsWindows7SP1OrGreater() function */
|
|
#include <versionhelpers.h>
|
|
@@ -404,6 +404,10 @@ remove_unusable_flags(PyObject *m)
|
|
/* Do not include addrinfo.h for MSVC7 or greater. 'addrinfo' and
|
|
* EAI_* constants are defined in (the already included) ws2tcpip.h.
|
|
*/
|
|
+#elif defined(__MINGW32__)
|
|
+ /* Do not include addrinfo.h as minimum supported version is
|
|
+ * _WIN32_WINNT >= WindowsXP(0x0501)
|
|
+ */
|
|
#else
|
|
# include "addrinfo.h"
|
|
#endif
|
|
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
|
|
index 1b35b11..cff1f1d 100644
|
|
--- a/Modules/socketmodule.h
|
|
+++ b/Modules/socketmodule.h
|
|
@@ -68,8 +68,10 @@ struct SOCKADDR_BTH_REDEF {
|
|
*/
|
|
# ifdef SIO_GET_MULTICAST_FILTER
|
|
# include <mstcpip.h> /* for SIO_RCVALL */
|
|
+#ifndef __MINGW32__ /* resolve by configure */
|
|
# define HAVE_ADDRINFO
|
|
# define HAVE_SOCKADDR_STORAGE
|
|
+#endif
|
|
# define HAVE_GETADDRINFO
|
|
# define HAVE_GETNAMEINFO
|
|
# define ENABLE_IPV6
|
|
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
|
|
index 18f9ddb..4edc2e7 100644
|
|
--- a/Modules/timemodule.c
|
|
+++ b/Modules/timemodule.c
|
|
@@ -783,7 +783,7 @@ time_strftime(PyObject *module, PyObject *args)
|
|
return NULL;
|
|
}
|
|
|
|
-#if defined(_MSC_VER) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__)
|
|
+#if defined(MS_WINDOWS) || (defined(__sun) && defined(__SVR4)) || defined(_AIX) || defined(__VXWORKS__)
|
|
if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) {
|
|
PyErr_SetString(PyExc_ValueError,
|
|
"strftime() requires year in [1; 9999]");
|
|
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
|
|
index ffe55eb..1d73c09 100644
|
|
--- a/Objects/fileobject.c
|
|
+++ b/Objects/fileobject.c
|
|
@@ -3,6 +3,7 @@
|
|
#define PY_SSIZE_T_CLEAN
|
|
#include "Python.h"
|
|
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
|
+#include "iscygpty.h"
|
|
#include "pycore_runtime.h" // _PyRuntime
|
|
|
|
#if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER)
|
|
@@ -387,7 +388,7 @@ stdprinter_isatty(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
|
|
}
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
- res = isatty(self->fd);
|
|
+ res = isatty(self->fd) || is_cygpty(self->fd);
|
|
Py_END_ALLOW_THREADS
|
|
|
|
return PyBool_FromLong(res);
|
|
diff --git a/PC/_testconsole.c b/PC/_testconsole.c
|
|
index a830883..52aca33 100644
|
|
--- a/PC/_testconsole.c
|
|
+++ b/PC/_testconsole.c
|
|
@@ -10,7 +10,7 @@
|
|
#ifdef MS_WINDOWS
|
|
|
|
#include "pycore_fileutils.h" // _Py_get_osfhandle()
|
|
-#include "..\modules\_io\_iomodule.h"
|
|
+#include "../Modules/_io/_iomodule.h"
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
@@ -108,7 +108,7 @@ _testconsole_read_output_impl(PyObject *module, PyObject *file)
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
-#include "clinic\_testconsole.c.h"
|
|
+#include "clinic/_testconsole.c.h"
|
|
|
|
PyMethodDef testconsole_methods[] = {
|
|
_TESTCONSOLE_WRITE_INPUT_METHODDEF
|
|
diff --git a/PC/launcher.c b/PC/launcher.c
|
|
index da566a1..09ac7d9 100644
|
|
--- a/PC/launcher.c
|
|
+++ b/PC/launcher.c
|
|
@@ -155,12 +155,12 @@ static wchar_t * get_env(wchar_t * key)
|
|
#else
|
|
#if defined(_WINDOWS)
|
|
|
|
-#define PYTHON_EXECUTABLE L"pythonw.exe"
|
|
+#define PYTHON_EXECUTABLE PYTHON_EXECUTABLE_WITH_VERSION
|
|
#define EXECUTABLEPATH_VALUE L"WindowedExecutablePath"
|
|
|
|
#else
|
|
|
|
-#define PYTHON_EXECUTABLE L"python.exe"
|
|
+#define PYTHON_EXECUTABLE PYTHON_EXECUTABLE_WITH_VERSION
|
|
#define EXECUTABLEPATH_VALUE L"ExecutablePath"
|
|
|
|
#endif
|
|
@@ -925,7 +925,7 @@ static COMMAND path_command;
|
|
static COMMAND * find_on_path(wchar_t * name)
|
|
{
|
|
wchar_t * pathext;
|
|
- size_t varsize;
|
|
+ size_t requiredSize;
|
|
wchar_t * context = NULL;
|
|
wchar_t * extension;
|
|
COMMAND * result = NULL;
|
|
@@ -942,18 +942,23 @@ static COMMAND * find_on_path(wchar_t * name)
|
|
}
|
|
else {
|
|
/* No extension - search using registered extensions. */
|
|
- rc = _wdupenv_s(&pathext, &varsize, L"PATHEXT");
|
|
- if (rc == 0) {
|
|
- extension = wcstok_s(pathext, L";", &context);
|
|
- while (extension) {
|
|
- len = SearchPathW(NULL, name, extension, MSGSIZE, path_command.value, NULL);
|
|
- if (len) {
|
|
- result = &path_command;
|
|
- break;
|
|
+ _wgetenv_s(&requiredSize, NULL, 0, L"PATHEXT");
|
|
+ if (requiredSize > 0) {
|
|
+ pathext = (wchar_t *)malloc(requiredSize * sizeof(wchar_t));
|
|
+ /* No extension - search using registered extensions. */
|
|
+ rc = _wgetenv_s(&requiredSize, pathext, requiredSize, L"PATHEXT");
|
|
+ if (rc == 0) {
|
|
+ extension = wcstok_s(pathext, L";", &context);
|
|
+ while (extension) {
|
|
+ len = SearchPathW(NULL, name, extension, MSGSIZE, path_command.value, NULL);
|
|
+ if (len) {
|
|
+ result = &path_command;
|
|
+ break;
|
|
+ }
|
|
+ extension = wcstok_s(NULL, L";", &context);
|
|
}
|
|
- extension = wcstok_s(NULL, L";", &context);
|
|
+ free(pathext);
|
|
}
|
|
- free(pathext);
|
|
}
|
|
}
|
|
return result;
|
|
@@ -1913,7 +1918,7 @@ process(int argc, wchar_t ** argv)
|
|
if (_wfopen_s(&f, venv_cfg_path, L"r")) {
|
|
error(RC_BAD_VENV_CFG, L"Cannot read '%ls'", venv_cfg_path);
|
|
}
|
|
- cb = fread_s(buffer, sizeof(buffer), sizeof(buffer[0]),
|
|
+ cb = fread(buffer, sizeof(buffer[0]),
|
|
sizeof(buffer) / sizeof(buffer[0]), f);
|
|
fclose(f);
|
|
|
|
diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c
|
|
index 1f78d99..0f2da80 100644
|
|
--- a/PC/msvcrtmodule.c
|
|
+++ b/PC/msvcrtmodule.c
|
|
@@ -22,7 +22,9 @@
|
|
#include <io.h>
|
|
#include <conio.h>
|
|
#include <sys/locking.h>
|
|
+#ifdef _DEBUG
|
|
#include <crtdbg.h>
|
|
+#endif
|
|
#include <windows.h>
|
|
|
|
#ifdef _MSC_VER
|
|
diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc
|
|
index 1186264..84b2917 100644
|
|
--- a/PC/pylauncher.rc
|
|
+++ b/PC/pylauncher.rc
|
|
@@ -12,17 +12,17 @@
|
|
1 RT_MANIFEST "python.manifest"
|
|
|
|
#if defined(PY_ICON)
|
|
-1 ICON DISCARDABLE "icons\python.ico"
|
|
+1 ICON DISCARDABLE "icons/python.ico"
|
|
#elif defined(PYW_ICON)
|
|
-1 ICON DISCARDABLE "icons\pythonw.ico"
|
|
+1 ICON DISCARDABLE "icons/pythonw.ico"
|
|
#else
|
|
-1 ICON DISCARDABLE "icons\launcher.ico"
|
|
-2 ICON DISCARDABLE "icons\py.ico"
|
|
-3 ICON DISCARDABLE "icons\pyc.ico"
|
|
-4 ICON DISCARDABLE "icons\pyd.ico"
|
|
-5 ICON DISCARDABLE "icons\python.ico"
|
|
-6 ICON DISCARDABLE "icons\pythonw.ico"
|
|
-7 ICON DISCARDABLE "icons\setup.ico"
|
|
+1 ICON DISCARDABLE "icons/launcher.ico"
|
|
+2 ICON DISCARDABLE "icons/py.ico"
|
|
+3 ICON DISCARDABLE "icons/pyc.ico"
|
|
+4 ICON DISCARDABLE "icons/pyd.ico"
|
|
+5 ICON DISCARDABLE "icons/python.ico"
|
|
+6 ICON DISCARDABLE "icons/pythonw.ico"
|
|
+7 ICON DISCARDABLE "icons/setup.ico"
|
|
#endif
|
|
|
|
1 USAGE "launcher-usage.txt"
|
|
@@ -64,4 +64,4 @@ BEGIN
|
|
BEGIN
|
|
VALUE "Translation", 0x0, 1200
|
|
END
|
|
-END
|
|
\ No newline at end of file
|
|
+END
|
|
diff --git a/PC/python3dll.c b/PC/python3dll.c
|
|
index 50e7a96..8b524fd 100755
|
|
--- a/PC/python3dll.c
|
|
+++ b/PC/python3dll.c
|
|
@@ -3,6 +3,7 @@
|
|
|
|
/* Generated by Tools/scripts/stable_abi.py */
|
|
|
|
+#ifdef _MSC_VER
|
|
#ifdef _M_IX86
|
|
#define DECORATE "_"
|
|
#else
|
|
@@ -13,6 +14,13 @@
|
|
__pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name))
|
|
#define EXPORT_DATA(name) \
|
|
__pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name ",DATA"))
|
|
+#else
|
|
+// XXX: Why do we need the .dll extension and no DECORATE compared to the MSVC case?
|
|
+#define EXPORT_FUNC(name) \
|
|
+ asm(".section .drectve\n\t.ascii \" -export:" #name "=\\\"" PYTHON_DLL_NAME "." #name "\\\" \"");
|
|
+#define EXPORT_DATA(name) \
|
|
+ asm(".section .drectve\n\t.ascii \" -export:" #name "=\\\"" PYTHON_DLL_NAME "." #name "\\\",DATA \"");
|
|
+#endif
|
|
|
|
EXPORT_FUNC(_Py_BuildValue_SizeT)
|
|
EXPORT_FUNC(_Py_CheckRecursiveCall)
|
|
diff --git a/PC/python_exe.rc b/PC/python_exe.rc
|
|
index c3d3bff..dde0e53 100644
|
|
--- a/PC/python_exe.rc
|
|
+++ b/PC/python_exe.rc
|
|
@@ -12,7 +12,7 @@
|
|
// current versions of Windows.
|
|
1 RT_MANIFEST "python.manifest"
|
|
|
|
-1 ICON DISCARDABLE "icons\python.ico"
|
|
+1 ICON DISCARDABLE "icons/python.ico"
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
diff --git a/PC/pythonw_exe.rc b/PC/pythonw_exe.rc
|
|
index 38570b7..7ce1043 100644
|
|
--- a/PC/pythonw_exe.rc
|
|
+++ b/PC/pythonw_exe.rc
|
|
@@ -12,7 +12,7 @@
|
|
// current versions of Windows.
|
|
1 RT_MANIFEST "python.manifest"
|
|
|
|
-1 ICON DISCARDABLE "icons\pythonw.ico"
|
|
+1 ICON DISCARDABLE "icons/pythonw.ico"
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
diff --git a/PC/winreg.c b/PC/winreg.c
|
|
index f668cf3..08548a7 100644
|
|
--- a/PC/winreg.c
|
|
+++ b/PC/winreg.c
|
|
@@ -18,6 +18,25 @@
|
|
#include "structmember.h" // PyMemberDef
|
|
#include <windows.h>
|
|
|
|
+#ifndef SIZEOF_HKEY
|
|
+/* used only here */
|
|
+#if defined(MS_WIN64)
|
|
+# define SIZEOF_HKEY 8
|
|
+#elif defined(MS_WIN32)
|
|
+# define SIZEOF_HKEY 4
|
|
+#else
|
|
+# error "SIZEOF_HKEY is not defined"
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#ifndef REG_LEGAL_CHANGE_FILTER
|
|
+#define REG_LEGAL_CHANGE_FILTER (\
|
|
+ REG_NOTIFY_CHANGE_NAME |\
|
|
+ REG_NOTIFY_CHANGE_ATTRIBUTES |\
|
|
+ REG_NOTIFY_CHANGE_LAST_SET |\
|
|
+ REG_NOTIFY_CHANGE_SECURITY )
|
|
+#endif
|
|
+
|
|
static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK);
|
|
static BOOL clinic_HKEY_converter(PyObject *ob, void *p);
|
|
static PyObject *PyHKEY_FromHKEY(HKEY h);
|
|
@@ -806,6 +825,7 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ)
|
|
case REG_BINARY:
|
|
/* ALSO handle ALL unknown data types here. Even if we can't
|
|
support it natively, we should handle the bits. */
|
|
+ /* fallthrough */
|
|
default:
|
|
if (retDataSize == 0) {
|
|
Py_INCREF(Py_None);
|
|
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
|
|
index e20bd53..c035b6b 100644
|
|
--- a/Python/bltinmodule.c
|
|
+++ b/Python/bltinmodule.c
|
|
@@ -1,6 +1,7 @@
|
|
/* Built-in functions */
|
|
|
|
#include "Python.h"
|
|
+#include "iscygpty.h"
|
|
#include <ctype.h>
|
|
#include "pycore_ast.h" // _PyAST_Validate()
|
|
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
|
@@ -2135,7 +2136,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|
Py_DECREF(tmp);
|
|
if (fd < 0 && PyErr_Occurred())
|
|
return NULL;
|
|
- tty = fd == fileno(stdin) && isatty(fd);
|
|
+ tty = fd == fileno(stdin) && (isatty(fd) || is_cygpty(fd));
|
|
}
|
|
if (tty) {
|
|
tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(fileno));
|
|
@@ -2148,7 +2149,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|
Py_DECREF(tmp);
|
|
if (fd < 0 && PyErr_Occurred())
|
|
return NULL;
|
|
- tty = fd == fileno(stdout) && isatty(fd);
|
|
+ tty = fd == fileno(stdout) && (isatty(fd) || is_cygpty(fd));
|
|
}
|
|
}
|
|
|
|
diff --git a/Python/dynamic_annotations.c b/Python/dynamic_annotations.c
|
|
index 7febaa0..70d5b3d 100644
|
|
--- a/Python/dynamic_annotations.c
|
|
+++ b/Python/dynamic_annotations.c
|
|
@@ -27,7 +27,7 @@
|
|
* Author: Kostya Serebryany
|
|
*/
|
|
|
|
-#ifdef _MSC_VER
|
|
+#ifdef MS_WINDOWS
|
|
# include <windows.h>
|
|
#endif
|
|
|
|
diff --git a/Python/dynload_win.c b/Python/dynload_win.c
|
|
index 5dc4095..fcb7321 100644
|
|
--- a/Python/dynload_win.c
|
|
+++ b/Python/dynload_win.c
|
|
@@ -4,6 +4,7 @@
|
|
#include "Python.h"
|
|
#include "pycore_fileutils.h" // _Py_add_relfile()
|
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
|
+#include "pycore_initconfig.h"
|
|
|
|
#ifdef HAVE_DIRECT_H
|
|
#include <direct.h>
|
|
@@ -170,8 +171,7 @@ static char *GetPythonImport (HINSTANCE hModule)
|
|
Return whether the DLL was found.
|
|
*/
|
|
extern HMODULE PyWin_DLLhModule;
|
|
-static int
|
|
-_Py_CheckPython3(void)
|
|
+int _Py_CheckPython3(void)
|
|
{
|
|
static int python3_checked = 0;
|
|
static HANDLE hPython3;
|
|
@@ -224,7 +224,21 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
|
|
dl_funcptr p;
|
|
char funcname[258], *import_python;
|
|
|
|
- _Py_CheckPython3();
|
|
+ int use_legacy = 0;
|
|
+ DWORD load_library_flags = 0;
|
|
+
|
|
+ _Py_get_env_flag(1, &use_legacy, "PYTHONLEGACYWINDOWSDLLLOADING");
|
|
+
|
|
+ if (use_legacy) {
|
|
+ load_library_flags = LOAD_WITH_ALTERED_SEARCH_PATH;
|
|
+ } else {
|
|
+ load_library_flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
|
|
+ LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
|
|
+ }
|
|
+
|
|
+#ifdef _MSC_VER
|
|
+ _Py_CheckPython3();
|
|
+#endif
|
|
|
|
#if USE_UNICODE_WCHAR_CACHE
|
|
const wchar_t *wpathname = _PyUnicode_AsUnicode(pathname);
|
|
@@ -248,9 +262,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
|
|
AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to
|
|
ensure DLLs adjacent to the PYD are preferred. */
|
|
Py_BEGIN_ALLOW_THREADS
|
|
- hDLL = LoadLibraryExW(wpathname, NULL,
|
|
- LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
|
|
- LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
|
|
+ hDLL = LoadLibraryExW(wpathname, NULL, load_library_flags);
|
|
Py_END_ALLOW_THREADS
|
|
#if !USE_UNICODE_WCHAR_CACHE
|
|
PyMem_Free(wpathname);
|
|
diff --git a/Python/fileutils.c b/Python/fileutils.c
|
|
index c86ed40..e459255 100644
|
|
--- a/Python/fileutils.c
|
|
+++ b/Python/fileutils.c
|
|
@@ -1,4 +1,5 @@
|
|
#include "Python.h"
|
|
+#include "iscygpty.h"
|
|
#include "pycore_fileutils.h" // fileutils definitions
|
|
#include "pycore_runtime.h" // _PyRuntime
|
|
#include "osdefs.h" // SEP
|
|
@@ -71,7 +72,7 @@ _Py_device_encoding(int fd)
|
|
int valid;
|
|
Py_BEGIN_ALLOW_THREADS
|
|
_Py_BEGIN_SUPPRESS_IPH
|
|
- valid = isatty(fd);
|
|
+ valid = isatty(fd) || is_cygpty(fd);
|
|
_Py_END_SUPPRESS_IPH
|
|
Py_END_ALLOW_THREADS
|
|
if (!valid)
|
|
@@ -1809,12 +1810,12 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held)
|
|
depending on heap usage). */
|
|
if (gil_held) {
|
|
Py_BEGIN_ALLOW_THREADS
|
|
- if (isatty(fd)) {
|
|
+ if (isatty(fd) || is_cygpty(fd)) {
|
|
count = 32767;
|
|
}
|
|
Py_END_ALLOW_THREADS
|
|
} else {
|
|
- if (isatty(fd)) {
|
|
+ if (isatty(fd) || is_cygpty(fd)) {
|
|
count = 32767;
|
|
}
|
|
}
|
|
@@ -2004,19 +2005,31 @@ int
|
|
_Py_isabs(const wchar_t *path)
|
|
{
|
|
#ifdef MS_WINDOWS
|
|
+ // create a copy of path and replace all forward slashes with backslashes
|
|
+ // pathccskiproot does not handle forward slashes
|
|
+ wchar_t *path_copy = _wcsdup(path);
|
|
+ if (path_copy == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+ Py_NormalizeSepsPathcchW(path_copy);
|
|
+
|
|
const wchar_t *tail;
|
|
- HRESULT hr = PathCchSkipRoot(path, &tail);
|
|
- if (FAILED(hr) || path == tail) {
|
|
+ HRESULT hr = PathCchSkipRoot(path_copy, &tail);
|
|
+ if (FAILED(hr) || path_copy == tail) {
|
|
+ free(path_copy);
|
|
return 0;
|
|
}
|
|
- if (tail == &path[1] && (path[0] == SEP || path[0] == ALTSEP)) {
|
|
+ if (tail == &path_copy[1] && (path_copy[0] == SEP || path_copy[0] == ALTSEP)) {
|
|
// Exclude paths with leading SEP
|
|
+ free(path_copy);
|
|
return 0;
|
|
}
|
|
- if (tail == &path[2] && path[1] == L':') {
|
|
+ if (tail == &path_copy[2] && path_copy[1] == L':') {
|
|
// Exclude drive-relative paths (e.g. C:filename.ext)
|
|
+ free(path_copy);
|
|
return 0;
|
|
}
|
|
+ free(path_copy);
|
|
return 1;
|
|
#else
|
|
return (path[0] == SEP);
|
|
@@ -2049,7 +2062,11 @@ _Py_abspath(const wchar_t *path, wchar_t **abspath_p)
|
|
}
|
|
|
|
#ifdef MS_WINDOWS
|
|
- return _PyOS_getfullpathname(path, abspath_p);
|
|
+ if (_PyOS_getfullpathname(path, abspath_p) < 0){
|
|
+ return -1;
|
|
+ }
|
|
+ *abspath_p = _Py_normpath(*abspath_p, -1);
|
|
+ return 0;
|
|
#else
|
|
wchar_t cwd[MAXPATHLEN + 1];
|
|
cwd[Py_ARRAY_LENGTH(cwd) - 1] = 0;
|
|
@@ -2093,6 +2110,8 @@ join_relfile(wchar_t *buffer, size_t bufsize,
|
|
const wchar_t *dirname, const wchar_t *relfile)
|
|
{
|
|
#ifdef MS_WINDOWS
|
|
+ Py_NormalizeSepsPathcchW(dirname);
|
|
+ Py_NormalizeSepsPathcchW(relfile);
|
|
if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile,
|
|
PATHCCH_ALLOW_LONG_PATHS))) {
|
|
return -1;
|
|
@@ -2195,11 +2214,16 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
|
wchar_t *minP2 = path; // the beginning of the destination range
|
|
wchar_t lastC = L'\0'; // the last ljusted character, p2[-1] in most cases
|
|
|
|
+ const wchar_t sep = Py_GetSepW(NULL);
|
|
+#ifdef ALTSEP
|
|
+ const wchar_t altsep = Py_GetAltSepW(NULL);
|
|
+#endif
|
|
+
|
|
#define IS_END(x) (pEnd ? (x) == pEnd : !*(x))
|
|
#ifdef ALTSEP
|
|
-#define IS_SEP(x) (*(x) == SEP || *(x) == ALTSEP)
|
|
+#define IS_SEP(x) (*(x) == sep || *(x) == altsep)
|
|
#else
|
|
-#define IS_SEP(x) (*(x) == SEP)
|
|
+#define IS_SEP(x) (*(x) == sep)
|
|
#endif
|
|
#define SEP_OR_END(x) (IS_SEP(x) || IS_END(x))
|
|
|
|
@@ -2210,7 +2234,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
|
path++;
|
|
}
|
|
p1 = p2 = minP2 = path;
|
|
- lastC = SEP;
|
|
+ lastC = sep;
|
|
}
|
|
#ifdef MS_WINDOWS
|
|
// Skip past drive segment and update minP2
|
|
@@ -2224,13 +2248,13 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
|
// and network paths, including the first segment.
|
|
else if (IS_SEP(&p1[0]) && IS_SEP(&p1[1])) {
|
|
int sepCount = 2;
|
|
- *p2++ = SEP;
|
|
- *p2++ = SEP;
|
|
+ *p2++ = sep;
|
|
+ *p2++ = sep;
|
|
p1 += 2;
|
|
for (; !IS_END(p1) && sepCount; ++p1) {
|
|
if (IS_SEP(p1)) {
|
|
--sepCount;
|
|
- *p2++ = lastC = SEP;
|
|
+ *p2++ = lastC = sep;
|
|
} else {
|
|
*p2++ = lastC = *p1;
|
|
}
|
|
@@ -2243,7 +2267,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
|
*p2++ = *p1++;
|
|
*p2++ = *p1++;
|
|
minP2 = p2 - 1; // Absolute path has SEP at minP2
|
|
- lastC = SEP;
|
|
+ lastC = sep;
|
|
}
|
|
#endif /* MS_WINDOWS */
|
|
|
|
@@ -2251,18 +2275,18 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
|
for (; !IS_END(p1); ++p1) {
|
|
wchar_t c = *p1;
|
|
#ifdef ALTSEP
|
|
- if (c == ALTSEP) {
|
|
- c = SEP;
|
|
+ if (c == altsep) {
|
|
+ c = sep;
|
|
}
|
|
#endif
|
|
- if (lastC == SEP) {
|
|
+ if (lastC == sep) {
|
|
if (c == L'.') {
|
|
int sep_at_1 = SEP_OR_END(&p1[1]);
|
|
int sep_at_2 = !sep_at_1 && SEP_OR_END(&p1[2]);
|
|
if (sep_at_2 && p1[1] == L'.') {
|
|
wchar_t *p3 = p2;
|
|
- while (p3 != minP2 && *--p3 == SEP) { }
|
|
- while (p3 != minP2 && *(p3 - 1) != SEP) { --p3; }
|
|
+ while (p3 != minP2 && *--p3 == sep) { }
|
|
+ while (p3 != minP2 && *(p3 - 1) != sep) { --p3; }
|
|
if (p2 == minP2
|
|
|| (p3[0] == L'.' && p3[1] == L'.' && IS_SEP(&p3[2])))
|
|
{
|
|
@@ -2271,7 +2295,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
|
*p2++ = L'.';
|
|
*p2++ = L'.';
|
|
lastC = L'.';
|
|
- } else if (p3[0] == SEP) {
|
|
+ } else if (p3[0] == sep) {
|
|
// Absolute path, so absorb segment
|
|
p2 = p3 + 1;
|
|
} else {
|
|
@@ -2282,7 +2306,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
|
} else {
|
|
*p2++ = lastC = c;
|
|
}
|
|
- } else if (c == SEP) {
|
|
+ } else if (c == sep) {
|
|
} else {
|
|
*p2++ = lastC = c;
|
|
}
|
|
@@ -2292,7 +2316,7 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
|
}
|
|
*p2 = L'\0';
|
|
if (p2 != minP2) {
|
|
- while (--p2 != minP2 && *p2 == SEP) {
|
|
+ while (--p2 != minP2 && *p2 == sep) {
|
|
*p2 = L'\0';
|
|
}
|
|
} else {
|
|
diff --git a/Python/frozenmain.c b/Python/frozenmain.c
|
|
index 8743e08..c6f5f19 100644
|
|
--- a/Python/frozenmain.c
|
|
+++ b/Python/frozenmain.c
|
|
@@ -3,6 +3,7 @@
|
|
#include "Python.h"
|
|
#include "pycore_runtime.h" // _PyRuntime_Initialize()
|
|
#include <locale.h>
|
|
+#include "iscygpty.h"
|
|
|
|
#ifdef MS_WINDOWS
|
|
extern void PyWinFreeze_ExeInit(void);
|
|
@@ -71,7 +72,7 @@ Py_FrozenMain(int argc, char **argv)
|
|
sts = 0;
|
|
}
|
|
|
|
- if (inspect && isatty((int)fileno(stdin))) {
|
|
+ if (inspect && (isatty((int)fileno(stdin)) || is_cygpty((int)fileno(stdin))))
|
|
sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
|
|
}
|
|
|
|
diff --git a/Python/getcompiler.c b/Python/getcompiler.c
|
|
index a5d2623..4b0b9b3 100644
|
|
--- a/Python/getcompiler.c
|
|
+++ b/Python/getcompiler.c
|
|
@@ -7,10 +7,40 @@
|
|
|
|
// Note the __clang__ conditional has to come before the __GNUC__ one because
|
|
// clang pretends to be GCC.
|
|
-#if defined(__clang__)
|
|
+#if defined(__clang__) && !defined(_WIN32)
|
|
#define COMPILER "[Clang " __clang_version__ "]"
|
|
#elif defined(__GNUC__)
|
|
-#define COMPILER "[GCC " __VERSION__ "]"
|
|
+/* To not break compatibility with things that determine
|
|
+ CPU arch by calling get_build_version in msvccompiler.py
|
|
+ (such as NumPy) add "32 bit" or "64 bit (AMD64)" on Windows
|
|
+ and also use a space as a separator rather than a newline. */
|
|
+#if defined(_WIN32)
|
|
+#define COMP_SEP " "
|
|
+#if defined(__x86_64__)
|
|
+#define ARCH_SUFFIX " 64 bit (AMD64)"
|
|
+#elif defined(__aarch64__)
|
|
+#define ARCH_SUFFIX " 64 bit (ARM64)"
|
|
+#elif defined(__arm__)
|
|
+#define ARCH_SUFFIX " 32 bit (ARM)"
|
|
+#else
|
|
+#define ARCH_SUFFIX " 32 bit"
|
|
+#endif
|
|
+#else
|
|
+#define COMP_SEP "\n"
|
|
+#define ARCH_SUFFIX ""
|
|
+#endif
|
|
+#if defined(__clang__)
|
|
+#define str(x) #x
|
|
+#define xstr(x) str(x)
|
|
+#define COMPILER COMP_SEP "[GCC Clang " xstr(__clang_major__) "." \
|
|
+ xstr(__clang_minor__) "." xstr(__clang_patchlevel__) ARCH_SUFFIX "]"
|
|
+#else
|
|
+#if defined(_UCRT)
|
|
+#define COMPILER COMP_SEP "[GCC UCRT " __VERSION__ ARCH_SUFFIX "]"
|
|
+#else
|
|
+#define COMPILER COMP_SEP "[GCC " __VERSION__ ARCH_SUFFIX "]"
|
|
+#endif
|
|
+#endif
|
|
// Generic fallbacks.
|
|
#elif defined(__cplusplus)
|
|
#define COMPILER "[C++]"
|
|
diff --git a/Python/initconfig.c b/Python/initconfig.c
|
|
index d81cbaf..c54d238 100644
|
|
--- a/Python/initconfig.c
|
|
+++ b/Python/initconfig.c
|
|
@@ -176,7 +176,7 @@ static const char usage_envvars[] =
|
|
"PYTHONVERBOSE : trace import statements (-v)\n"
|
|
"PYTHONWARNINGS=arg : warning control (-W arg)\n";
|
|
|
|
-#if defined(MS_WINDOWS)
|
|
+#if defined(_MSC_VER)
|
|
# define PYTHONHOMEHELP "<prefix>\\python{major}{minor}"
|
|
#else
|
|
# define PYTHONHOMEHELP "<prefix>/lib/pythonX.X"
|
|
diff --git a/Python/iscygpty.c b/Python/iscygpty.c
|
|
new file mode 100755
|
|
index 0000000..722f88f
|
|
--- /dev/null
|
|
+++ b/Python/iscygpty.c
|
|
@@ -0,0 +1,185 @@
|
|
+/*
|
|
+ * iscygpty.c -- part of ptycheck
|
|
+ * https://github.com/k-takata/ptycheck
|
|
+ *
|
|
+ * Copyright (c) 2015-2017 K.Takata
|
|
+ *
|
|
+ * You can redistribute it and/or modify it under the terms of either
|
|
+ * the MIT license (as described below) or the Vim license.
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
+ * a copy of this software and associated documentation files (the
|
|
+ * "Software"), to deal in the Software without restriction, including
|
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
+ * the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be
|
|
+ * included in all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+ */
|
|
+
|
|
+#ifdef _WIN32
|
|
+
|
|
+#include <ctype.h>
|
|
+#include <io.h>
|
|
+#include <wchar.h>
|
|
+#include <windows.h>
|
|
+
|
|
+#ifdef USE_FILEEXTD
|
|
+/* VC 7.1 or earlier doesn't support SAL. */
|
|
+# if !defined(_MSC_VER) || (_MSC_VER < 1400)
|
|
+# define __out
|
|
+# define __in
|
|
+# define __in_opt
|
|
+# endif
|
|
+/* Win32 FileID API Library:
|
|
+ * http://www.microsoft.com/en-us/download/details.aspx?id=22599
|
|
+ * Needed for WinXP. */
|
|
+# include <fileextd.h>
|
|
+#else /* USE_FILEEXTD */
|
|
+/* VC 8 or earlier. */
|
|
+# if defined(_MSC_VER) && (_MSC_VER < 1500)
|
|
+# ifdef ENABLE_STUB_IMPL
|
|
+# define STUB_IMPL
|
|
+# else
|
|
+# error "Win32 FileID API Library is required for VC2005 or earlier."
|
|
+# endif
|
|
+# endif
|
|
+#endif /* USE_FILEEXTD */
|
|
+
|
|
+
|
|
+#include "iscygpty.h"
|
|
+
|
|
+//#define USE_DYNFILEID
|
|
+#ifdef USE_DYNFILEID
|
|
+typedef BOOL (WINAPI *pfnGetFileInformationByHandleEx)(
|
|
+ HANDLE hFile,
|
|
+ FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
|
|
+ LPVOID lpFileInformation,
|
|
+ DWORD dwBufferSize
|
|
+);
|
|
+static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL;
|
|
+
|
|
+# ifndef USE_FILEEXTD
|
|
+static BOOL WINAPI stub_GetFileInformationByHandleEx(
|
|
+ HANDLE hFile,
|
|
+ FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
|
|
+ LPVOID lpFileInformation,
|
|
+ DWORD dwBufferSize
|
|
+ )
|
|
+{
|
|
+ return FALSE;
|
|
+}
|
|
+# endif
|
|
+
|
|
+static void setup_fileid_api(void)
|
|
+{
|
|
+ if (pGetFileInformationByHandleEx != NULL) {
|
|
+ return;
|
|
+ }
|
|
+ pGetFileInformationByHandleEx = (pfnGetFileInformationByHandleEx)
|
|
+ GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
|
|
+ "GetFileInformationByHandleEx");
|
|
+ if (pGetFileInformationByHandleEx == NULL) {
|
|
+# ifdef USE_FILEEXTD
|
|
+ pGetFileInformationByHandleEx = GetFileInformationByHandleEx;
|
|
+# else
|
|
+ pGetFileInformationByHandleEx = stub_GetFileInformationByHandleEx;
|
|
+# endif
|
|
+ }
|
|
+}
|
|
+#else
|
|
+# define pGetFileInformationByHandleEx GetFileInformationByHandleEx
|
|
+# define setup_fileid_api()
|
|
+#endif
|
|
+
|
|
+
|
|
+#define is_wprefix(s, prefix) \
|
|
+ (wcsncmp((s), (prefix), sizeof(prefix) / sizeof(WCHAR) - 1) == 0)
|
|
+
|
|
+/* Check if the fd is a cygwin/msys's pty. */
|
|
+int is_cygpty(int fd)
|
|
+{
|
|
+#ifdef STUB_IMPL
|
|
+ return 0;
|
|
+#else
|
|
+ HANDLE h;
|
|
+ int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * (MAX_PATH - 1);
|
|
+ FILE_NAME_INFO *nameinfo;
|
|
+ WCHAR *p = NULL;
|
|
+
|
|
+ setup_fileid_api();
|
|
+
|
|
+ h = (HANDLE) _get_osfhandle(fd);
|
|
+ if (h == INVALID_HANDLE_VALUE) {
|
|
+ return 0;
|
|
+ }
|
|
+ /* Cygwin/msys's pty is a pipe. */
|
|
+ if (GetFileType(h) != FILE_TYPE_PIPE) {
|
|
+ return 0;
|
|
+ }
|
|
+ nameinfo = malloc(size + sizeof(WCHAR));
|
|
+ if (nameinfo == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+ /* Check the name of the pipe:
|
|
+ * '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master' */
|
|
+ if (pGetFileInformationByHandleEx(h, FileNameInfo, nameinfo, size)) {
|
|
+ nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0';
|
|
+ p = nameinfo->FileName;
|
|
+ if (is_wprefix(p, L"\\cygwin-")) { /* Cygwin */
|
|
+ p += 8;
|
|
+ } else if (is_wprefix(p, L"\\msys-")) { /* MSYS and MSYS2 */
|
|
+ p += 6;
|
|
+ } else {
|
|
+ p = NULL;
|
|
+ }
|
|
+ if (p != NULL) {
|
|
+ while (*p && isxdigit(*p)) /* Skip 16-digit hexadecimal. */
|
|
+ ++p;
|
|
+ if (is_wprefix(p, L"-pty")) {
|
|
+ p += 4;
|
|
+ } else {
|
|
+ p = NULL;
|
|
+ }
|
|
+ }
|
|
+ if (p != NULL) {
|
|
+ while (*p && isdigit(*p)) /* Skip pty number. */
|
|
+ ++p;
|
|
+ if (is_wprefix(p, L"-from-master")) {
|
|
+ //p += 12;
|
|
+ } else if (is_wprefix(p, L"-to-master")) {
|
|
+ //p += 10;
|
|
+ } else {
|
|
+ p = NULL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ free(nameinfo);
|
|
+ return (p != NULL);
|
|
+#endif /* STUB_IMPL */
|
|
+}
|
|
+
|
|
+/* Check if at least one cygwin/msys pty is used. */
|
|
+int is_cygpty_used(void)
|
|
+{
|
|
+ int fd, ret = 0;
|
|
+
|
|
+ for (fd = 0; fd < 3; fd++) {
|
|
+ ret |= is_cygpty(fd);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#endif /* _WIN32 */
|
|
+
|
|
+/* vim: set ts=4 sw=4: */
|
|
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
|
|
index be0f97c..7eb9006 100644
|
|
--- a/Python/pathconfig.c
|
|
+++ b/Python/pathconfig.c
|
|
@@ -2,7 +2,7 @@
|
|
|
|
#include "Python.h"
|
|
#include "marshal.h" // PyMarshal_ReadObjectFromString
|
|
-#include "osdefs.h" // DELIM
|
|
+#include "osdefs.h" // DELIM, SEP
|
|
#include "pycore_initconfig.h"
|
|
#include "pycore_fileutils.h"
|
|
#include "pycore_pathconfig.h"
|
|
@@ -18,6 +18,158 @@
|
|
extern "C" {
|
|
#endif
|
|
|
|
+#ifdef __MINGW32__
|
|
+#define wcstok wcstok_s
|
|
+#include <windows.h>
|
|
+#endif
|
|
+
|
|
+static int
|
|
+Py_StartsWithA(const char * str, const char * prefix)
|
|
+{
|
|
+ while(*prefix)
|
|
+ {
|
|
+ if(*prefix++ != *str++)
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+static int
|
|
+Py_StartsWithW(const wchar_t * str, const wchar_t * prefix)
|
|
+{
|
|
+ while(*prefix)
|
|
+ {
|
|
+ if(*prefix++ != *str++)
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+char
|
|
+Py_GetSepA(const char *name)
|
|
+{
|
|
+ static char sep = '\0';
|
|
+#ifdef _WIN32
|
|
+ /* https://msdn.microsoft.com/en-gb/library/windows/desktop/aa365247%28v=vs.85%29.aspx
|
|
+ * The "\\?\" prefix .. indicate that the path should be passed to the system with minimal
|
|
+ * modification, which means that you cannot use forward slashes to represent path separators
|
|
+ */
|
|
+ if (name != NULL && Py_StartsWithA(name, "\\\\?\\") != 0)
|
|
+ {
|
|
+ return '\\';
|
|
+ }
|
|
+#endif
|
|
+ if (sep != '\0')
|
|
+ return sep;
|
|
+#if defined(__MINGW32__)
|
|
+ char* msystem = getenv("MSYSTEM");
|
|
+ if (msystem != NULL && strcmp(msystem, "") != 0)
|
|
+ sep = '/';
|
|
+ else
|
|
+ sep = '\\';
|
|
+#else
|
|
+ sep = SEP;
|
|
+#endif
|
|
+ return sep;
|
|
+}
|
|
+
|
|
+static char
|
|
+Py_GetAltSepA(const char *name)
|
|
+{
|
|
+ char sep = Py_GetSepA(name);
|
|
+ if (sep == '/')
|
|
+ return '\\';
|
|
+ return '/';
|
|
+}
|
|
+
|
|
+void
|
|
+Py_NormalizeSepsA(char *name)
|
|
+{
|
|
+ assert(name != NULL);
|
|
+ char sep = Py_GetSepA(name);
|
|
+ char altsep = Py_GetAltSepA(name);
|
|
+ char* seps;
|
|
+ if (name[0] != '\0' && name[1] == ':') {
|
|
+ name[0] = toupper(name[0]);
|
|
+ }
|
|
+ seps = strchr(name, altsep);
|
|
+ while(seps) {
|
|
+ *seps = sep;
|
|
+ seps = strchr(seps, altsep);
|
|
+ }
|
|
+}
|
|
+
|
|
+wchar_t
|
|
+Py_GetSepW(const wchar_t *name)
|
|
+{
|
|
+ static wchar_t sep = L'\0';
|
|
+#ifdef _WIN32
|
|
+ /* https://msdn.microsoft.com/en-gb/library/windows/desktop/aa365247%28v=vs.85%29.aspx
|
|
+ * The "\\?\" prefix .. indicate that the path should be passed to the system with minimal
|
|
+ * modification, which means that you cannot use forward slashes to represent path separators
|
|
+ */
|
|
+ if (name != NULL && Py_StartsWithW(name, L"\\\\?\\") != 0)
|
|
+ {
|
|
+ return L'\\';
|
|
+ }
|
|
+#endif
|
|
+ if (sep != L'\0')
|
|
+ return sep;
|
|
+#if defined(__MINGW32__)
|
|
+ char* msystem = getenv("MSYSTEM");
|
|
+ if (msystem != NULL && strcmp(msystem, "") != 0)
|
|
+ sep = L'/';
|
|
+ else
|
|
+ sep = L'\\';
|
|
+#else
|
|
+ sep = SEP;
|
|
+#endif
|
|
+ return sep;
|
|
+}
|
|
+
|
|
+wchar_t
|
|
+Py_GetAltSepW(const wchar_t *name)
|
|
+{
|
|
+ char sep = Py_GetSepW(name);
|
|
+ if (sep == L'/')
|
|
+ return L'\\';
|
|
+ return L'/';
|
|
+}
|
|
+
|
|
+void
|
|
+Py_NormalizeSepsW(wchar_t *name)
|
|
+{
|
|
+ assert(name != NULL);
|
|
+ wchar_t sep = Py_GetSepW(name);
|
|
+ wchar_t altsep = Py_GetAltSepW(name);
|
|
+ wchar_t* seps;
|
|
+ if (name[0] != L'\0' && name[1] == L':') {
|
|
+ name[0] = towupper(name[0]);
|
|
+ }
|
|
+ seps = wcschr(name, altsep);
|
|
+ while(seps) {
|
|
+ *seps = sep;
|
|
+ seps = wcschr(seps, altsep);
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+Py_NormalizeSepsPathcchW(wchar_t *name)
|
|
+{
|
|
+#ifdef MS_WINDOWS
|
|
+ assert(name != NULL);
|
|
+ wchar_t sep = '\\';
|
|
+ wchar_t altsep = '/';
|
|
+ wchar_t* seps;
|
|
+ seps = wcschr(name, altsep);
|
|
+ while(seps) {
|
|
+ *seps = sep;
|
|
+ seps = wcschr(seps, altsep);
|
|
+ }
|
|
+#endif
|
|
+}
|
|
|
|
/* External interface */
|
|
|
|
@@ -317,6 +469,7 @@ _Py_SetProgramFullPath(const wchar_t *program_full_path)
|
|
if (has_value && _Py_path_config.program_full_path == NULL) {
|
|
path_out_of_memory(__func__);
|
|
}
|
|
+ Py_NormalizeSepsW(_Py_path_config.program_name);
|
|
}
|
|
|
|
|
|
@@ -509,7 +662,7 @@ _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p)
|
|
}
|
|
#endif /* All others */
|
|
|
|
- PyObject *path0_obj = PyUnicode_FromWideChar(path0, n);
|
|
+ PyObject *path0_obj = PyUnicode_FromWideChar(_Py_normpath(path0, -1), n);
|
|
if (path0_obj == NULL) {
|
|
return -1;
|
|
}
|
|
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
|
|
index 9248e97..1d53e12 100644
|
|
--- a/Python/pylifecycle.c
|
|
+++ b/Python/pylifecycle.c
|
|
@@ -31,6 +31,7 @@
|
|
|
|
extern void _PyIO_Fini(void);
|
|
|
|
+#include "iscygpty.h"
|
|
#include <locale.h> // setlocale()
|
|
#include <stdlib.h> // getenv()
|
|
|
|
@@ -2954,7 +2955,7 @@ Py_Exit(int sts)
|
|
int
|
|
Py_FdIsInteractive(FILE *fp, const char *filename)
|
|
{
|
|
- if (isatty((int)fileno(fp)))
|
|
+ if (isatty((int)fileno(fp)) || is_cygpty((int)fileno(fp)))
|
|
return 1;
|
|
if (!Py_InteractiveFlag)
|
|
return 0;
|
|
@@ -2967,7 +2968,7 @@ Py_FdIsInteractive(FILE *fp, const char *filename)
|
|
int
|
|
_Py_FdIsInteractive(FILE *fp, PyObject *filename)
|
|
{
|
|
- if (isatty((int)fileno(fp))) {
|
|
+ if (isatty((int)fileno(fp)) || is_cygpty((int)fileno(fp))) {
|
|
return 1;
|
|
}
|
|
if (!Py_InteractiveFlag) {
|
|
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
|
|
index 8bab703..fed0adb 100644
|
|
--- a/Python/sysmodule.c
|
|
+++ b/Python/sysmodule.c
|
|
@@ -43,7 +43,7 @@ Data members:
|
|
#include <windows.h>
|
|
#endif /* MS_WINDOWS */
|
|
|
|
-#ifdef MS_COREDLL
|
|
+#if defined(MS_WINDOWS) && defined(Py_ENABLE_SHARED)
|
|
extern void *PyWin_DLLhModule;
|
|
/* A string loaded from the DLL at startup: */
|
|
extern const char *PyWin_DLLVersionString;
|
|
@@ -2923,7 +2923,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
|
|
SET_SYS_FROM_STRING("byteorder", "little");
|
|
#endif
|
|
|
|
-#ifdef MS_COREDLL
|
|
+#if defined(MS_WINDOWS) && defined(Py_ENABLE_SHARED)
|
|
SET_SYS("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule));
|
|
SET_SYS_FROM_STRING("winver", PyWin_DLLVersionString);
|
|
#endif
|
|
diff --git a/Python/thread_nt.h b/Python/thread_nt.h
|
|
index 084bd58..f8a6765 100644
|
|
--- a/Python/thread_nt.h
|
|
+++ b/Python/thread_nt.h
|
|
@@ -360,8 +360,9 @@ PyThread_release_lock(PyThread_type_lock aLock)
|
|
{
|
|
dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
|
|
|
- if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
|
|
+ if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) {
|
|
dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError()));
|
|
+ }
|
|
}
|
|
|
|
/* minimum/maximum thread stack sizes supported */
|
|
diff --git a/Python/traceback.c b/Python/traceback.c
|
|
index 7f47349..23fda62 100644
|
|
--- a/Python/traceback.c
|
|
+++ b/Python/traceback.c
|
|
@@ -323,7 +323,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
|
|
filepath = PyBytes_AS_STRING(filebytes);
|
|
|
|
/* Search tail of filename in sys.path before giving up */
|
|
- tail = strrchr(filepath, SEP);
|
|
+ tail = strrchr(filepath, Py_GetSepA(filepath));
|
|
if (tail == NULL)
|
|
tail = filepath;
|
|
else
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 1c25abd..5cf7085 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -202,9 +202,11 @@ AC_SUBST([FREEZE_MODULE])
|
|
AC_SUBST([FREEZE_MODULE_DEPS])
|
|
AC_SUBST([PYTHON_FOR_BUILD_DEPS])
|
|
|
|
+NATIVE_PYTHON_SEARCH_PATH_MINGW=`echo $host | grep -Eq 'mingw*' && echo "$MINGW_PREFIX/bin" || echo $PATH`
|
|
AC_CHECK_PROGS([PYTHON_FOR_REGEN],
|
|
[python$PACKAGE_VERSION python3.10 python3.9 python3.8 python3.7 python3.6 python3 python],
|
|
- [python3])
|
|
+ [python3],
|
|
+ [$NATIVE_PYTHON_SEARCH_PATH_MINGW])
|
|
AC_SUBST(PYTHON_FOR_REGEN)
|
|
|
|
AC_MSG_CHECKING([Python for regen version])
|
|
@@ -545,6 +547,9 @@ then
|
|
*-*-cygwin*)
|
|
ac_sys_system=Cygwin
|
|
;;
|
|
+ *-*-mingw*)
|
|
+ ac_sys_system=MINGW
|
|
+ ;;
|
|
*-*-vxworks*)
|
|
ac_sys_system=VxWorks
|
|
;;
|
|
@@ -580,6 +585,7 @@ then
|
|
linux*) MACHDEP="linux";;
|
|
cygwin*) MACHDEP="cygwin";;
|
|
darwin*) MACHDEP="darwin";;
|
|
+ mingw*) MACHDEP="win32";;
|
|
'') MACHDEP="unknown";;
|
|
esac
|
|
fi
|
|
@@ -605,6 +611,9 @@ if test "$cross_compiling" = yes; then
|
|
;;
|
|
wasm32-*-* | wasm64-*-*)
|
|
_host_cpu=$host_cpu
|
|
+ ;;
|
|
+ *-*-mingw*)
|
|
+ _host_cpu=
|
|
;;
|
|
*)
|
|
# for now, limit cross builds to known configurations
|
|
@@ -612,6 +621,14 @@ if test "$cross_compiling" = yes; then
|
|
AC_MSG_ERROR([cross build not supported for $host])
|
|
esac
|
|
_PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}"
|
|
+
|
|
+ case "$host_os" in
|
|
+ mingw*)
|
|
+ # As sys.platform() return 'win32' to build python and extantions
|
|
+ # we will use 'mingw' (in setup.py and etc.)
|
|
+ _PYTHON_HOST_PLATFORM=mingw
|
|
+ ;;
|
|
+ esac
|
|
fi
|
|
|
|
# Some systems cannot stand _XOPEN_SOURCE being defined at all; they
|
|
@@ -723,6 +740,65 @@ then
|
|
AC_DEFINE(_INCLUDE__STDC_A1_SOURCE, 1, Define to include mbstate_t for mbrtowc)
|
|
fi
|
|
|
|
+# On 'semi-native' build systems (MSYS*/Cygwin targeting MinGW-w64)
|
|
+# _sysconfigdata.py will contain paths that are correct only in the
|
|
+# build environment. This means external modules will fail to build
|
|
+# without setting up the same env and also that the build of Python
|
|
+# itself will fail as the paths are not correct for the host tools.
|
|
+#
|
|
+# To work around these issues a set of _b2h variables are created:
|
|
+# prefix_b2h, srcdir_b2h, abs_srcdir_b2h
|
|
+# and abs_builddir_b2h
|
|
+# .. where b2h stands for build to host. sysconfig.py replaces path
|
|
+# prefixes matching the non-b2h versions with the b2h equivalents.
|
|
+#
|
|
+# (note this assumes the host compilers are native and *not* cross
|
|
+# - in the 'semi-native' scenario only that is.)
|
|
+
|
|
+AC_DEFUN([ABS_PATH_HOST],
|
|
+[$1=$(cd $$2 && pwd)
|
|
+ case $build_os in
|
|
+ mingw*)
|
|
+ case $host_os in
|
|
+ mingw*) $1=$(cd $$2 && pwd -W) ;;
|
|
+ *) ;;
|
|
+ esac
|
|
+ ;;
|
|
+ cygwin*)
|
|
+ case $host_os in
|
|
+ mingw*) $1=$(cygpath -w -m $$2) ;;
|
|
+ *) ;;
|
|
+ esac
|
|
+ ;;
|
|
+ esac
|
|
+AC_SUBST([$1])
|
|
+])
|
|
+
|
|
+AC_MSG_CHECKING(absolute host location of prefix)
|
|
+ABS_PATH_HOST([prefix_b2h],[prefix])
|
|
+AC_MSG_RESULT([$prefix_b2h])
|
|
+
|
|
+AC_MSG_CHECKING(absolute host location of srcdir)
|
|
+ABS_PATH_HOST([srcdir_b2h],[srcdir])
|
|
+AC_MSG_RESULT([$srcdir_b2h])
|
|
+
|
|
+AC_MSG_CHECKING(absolute host location of abs_srcdir)
|
|
+ABS_PATH_HOST([abs_srcdir_b2h],[srcdir])
|
|
+AC_MSG_RESULT([$abs_srcdir_b2h])
|
|
+
|
|
+my_builddir=.
|
|
+AC_MSG_CHECKING(Absolute host location of abs_builddir)
|
|
+ABS_PATH_HOST([abs_builddir_b2h],[my_builddir])
|
|
+AC_MSG_RESULT([$abs_builddir_b2h])
|
|
+
|
|
+AC_MSG_CHECKING([for init system calls])
|
|
+AC_SUBST(INITSYS)
|
|
+case $host in
|
|
+ *-*-mingw*) INITSYS=nt;;
|
|
+ *) INITSYS=posix;;
|
|
+esac
|
|
+AC_MSG_RESULT([$INITSYS])
|
|
+
|
|
# Record the configure-time value of MACOSX_DEPLOYMENT_TARGET,
|
|
# it may influence the way we can build extensions, so distutils
|
|
# needs to check it
|
|
@@ -1163,6 +1239,28 @@ AC_CACHE_CHECK([for -Wl,--no-as-needed], [ac_cv_wl_no_as_needed], [
|
|
])
|
|
AC_SUBST(NO_AS_NEEDED)
|
|
|
|
+# initialize default configuration
|
|
+py_config=
|
|
+case $host in
|
|
+ *-*-mingw*) py_config=mingw ;;
|
|
+esac
|
|
+if test -n "$py_config" ; then
|
|
+ AC_MSG_NOTICE([loading configure defaults from .../Misc/config_$py_config"])
|
|
+ . "$srcdir/Misc/config_$py_config"
|
|
+fi
|
|
+
|
|
+# initialize defaults for cross-builds
|
|
+if test "$cross_compiling" = yes; then
|
|
+ py_config=$host_os
|
|
+ case $py_config in
|
|
+ mingw32*) py_config=mingw32 ;;
|
|
+ esac
|
|
+ if test -f "$srcdir/Misc/cross_$py_config" ; then
|
|
+ AC_MSG_NOTICE([loading cross defaults from .../Misc/cross_$py_config"])
|
|
+ . "$srcdir/Misc/cross_$py_config"
|
|
+ fi
|
|
+fi
|
|
+
|
|
AC_MSG_CHECKING([for the Android API level])
|
|
cat > conftest.c <<EOF
|
|
#ifdef __ANDROID__
|
|
@@ -1275,6 +1373,7 @@ AC_ARG_WITH([suffix],
|
|
[Emscripten/browser*], [EXEEXT=.js],
|
|
[Emscripten/node*], [EXEEXT=.js],
|
|
[WASI/*], [EXEEXT=.wasm],
|
|
+ [MINGW*], [EXEEXT=.exe],
|
|
[EXEEXT=]
|
|
)
|
|
])
|
|
@@ -1298,6 +1397,10 @@ else
|
|
fi
|
|
rmdir CaseSensitiveTestDir
|
|
|
|
+AS_CASE([$ac_sys_system],
|
|
+ [MINGW], [BUILDEXEEXT=".exe"]
|
|
+)
|
|
+
|
|
case $ac_sys_system in
|
|
hp*|HP*)
|
|
case $CC in
|
|
@@ -1475,6 +1578,11 @@ if test $enable_shared = "yes"; then
|
|
LDLIBRARY='libpython$(LDVERSION).dll.a'
|
|
DLLLIBRARY='libpython$(LDVERSION).dll'
|
|
;;
|
|
+ MINGW*)
|
|
+ LDLIBRARY='libpython$(LDVERSION).dll.a'
|
|
+ DLLLIBRARY='libpython$(LDVERSION).dll'
|
|
+ BLDLIBRARY='-L. -lpython$(LDVERSION)'
|
|
+ ;;
|
|
SunOS*)
|
|
LDLIBRARY='libpython$(LDVERSION).so'
|
|
BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
|
|
@@ -1525,6 +1633,9 @@ else # shared is disabled
|
|
BLDLIBRARY='$(LIBRARY)'
|
|
LDLIBRARY='libpython$(LDVERSION).dll.a'
|
|
;;
|
|
+ MINGW*)
|
|
+ LDLIBRARY='libpython$(LDVERSION).a'
|
|
+ ;;
|
|
esac
|
|
fi
|
|
|
|
@@ -1618,6 +1729,10 @@ AC_SUBST(LINK_PYTHON_OBJS)
|
|
AC_SUBST(AR)
|
|
AC_CHECK_TOOLS(AR, ar aal, ar)
|
|
|
|
+# windres program
|
|
+AC_SUBST(WINDRES)
|
|
+AC_CHECK_TOOL(WINDRES, windres)
|
|
+
|
|
# tweak ARFLAGS only if the user didn't set it on the command line
|
|
AC_SUBST(ARFLAGS)
|
|
if test -z "$ARFLAGS"
|
|
@@ -2498,6 +2613,53 @@ then
|
|
BASECFLAGS="$BASECFLAGS $ac_arch_flags"
|
|
fi
|
|
|
|
+dnl NOTE:
|
|
+dnl - GCC 4.4+ for mingw* require and use posix threads(pthreads-w32)
|
|
+dnl - Host may contain installed pthreads-w32.
|
|
+dnl - On windows platform only NT-thread model is supported.
|
|
+dnl To avoid miss detection scipt first will check for NT-thread model
|
|
+dnl and if is not found will try to detect build options for pthread
|
|
+dnl model. Autodetection could be overiden if variable with_nt_threads
|
|
+dnl is set in "Site Configuration" (see autoconf manual).
|
|
+dnl If NT-thread model is enabled script skips some checks that
|
|
+dnl impact build process. When a new functionality is added, developers
|
|
+dnl are responsible to update configure script to avoid thread models
|
|
+dnl to be mixed.
|
|
+
|
|
+AC_MSG_CHECKING([for --with-nt-threads])
|
|
+AC_ARG_WITH(nt-threads,
|
|
+ AS_HELP_STRING([--with-nt-threads], [build with windows threads (default is system-dependent)]),
|
|
+[
|
|
+ case $withval in
|
|
+ no) with_nt_threads=no;;
|
|
+ yes) with_nt_threads=yes;;
|
|
+ *) with_nt_threads=yes;;
|
|
+ esac
|
|
+], [
|
|
+ case $host in
|
|
+ *-*-mingw*) with_nt_threads=yes;;
|
|
+ *) with_nt_threads=no;;
|
|
+ esac
|
|
+])
|
|
+AC_MSG_RESULT([$with_nt_threads])
|
|
+
|
|
+if test $with_nt_threads = yes ; then
|
|
+AC_MSG_CHECKING([whether linking with nt-threads work])
|
|
+AC_LINK_IFELSE([
|
|
+ AC_LANG_PROGRAM([[#include <process.h>]],[[_beginthread(0, 0, 0);]])
|
|
+ ],
|
|
+ [AC_MSG_RESULT([yes])],
|
|
+ [AC_MSG_ERROR([failed to link with nt-threads])])
|
|
+fi
|
|
+
|
|
+if test $with_nt_threads = yes ; then
|
|
+ dnl temporary default flag to avoid additional pthread checks
|
|
+ dnl and initilize other ac..thread flags to no
|
|
+ ac_cv_pthread_is_default=no
|
|
+ ac_cv_kthread=no
|
|
+ ac_cv_pthread=no
|
|
+ dnl ac_cv_kpthread is set to no if default is yes (see below)
|
|
+else
|
|
# On some compilers, pthreads are available without further options
|
|
# (e.g. MacOS X). On some of these systems, the compiler will not
|
|
# complain if unaccepted options are passed (e.g. gcc on Mac OS X).
|
|
@@ -2609,6 +2771,8 @@ int main(void){
|
|
CC="$ac_save_cc"])
|
|
fi
|
|
|
|
+fi
|
|
+
|
|
# If we have set a CC compiler flag for thread support then
|
|
# check if it works for CXX, too.
|
|
ac_cv_cxx_thread=no
|
|
@@ -2629,6 +2793,10 @@ elif test "$ac_cv_pthread" = "yes"
|
|
then
|
|
CXX="$CXX -pthread"
|
|
ac_cv_cxx_thread=yes
|
|
+elif test $with_nt_threads = yes
|
|
+then
|
|
+ dnl set to always to skip extra pthread check below
|
|
+ ac_cv_cxx_thread=always
|
|
fi
|
|
|
|
if test $ac_cv_cxx_thread = yes
|
|
@@ -2663,11 +2831,11 @@ AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.])
|
|
|
|
# checks for header files
|
|
AC_CHECK_HEADERS([ \
|
|
- alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \
|
|
+ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h endian.h errno.h fcntl.h grp.h \
|
|
ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/memfd.h \
|
|
linux/random.h linux/soundcard.h \
|
|
- linux/tipc.h linux/wait.h netdb.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \
|
|
- sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \
|
|
+ linux/tipc.h linux/wait.h netdb.h netinet/in.h netpacket/packet.h poll.h process.h pty.h \
|
|
+ setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \
|
|
sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \
|
|
sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \
|
|
sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \
|
|
@@ -2675,9 +2843,24 @@ AC_CHECK_HEADERS([ \
|
|
sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \
|
|
termios.h util.h utime.h utmp.h \
|
|
])
|
|
+
|
|
+case $host in
|
|
+ *-*-mingw*) ;;
|
|
+ *) AC_CHECK_HEADERS([dlfcn.h]);;
|
|
+esac
|
|
+
|
|
+
|
|
AC_HEADER_DIRENT
|
|
AC_HEADER_MAJOR
|
|
|
|
+# If using nt threads, don't look for pthread.h or thread.h
|
|
+if test "x$with_nt_threads" = xno ; then
|
|
+AC_HEADER_STDC
|
|
+AC_CHECK_HEADERS(pthread.h sched.h thread.h)
|
|
+AC_HEADER_DIRENT
|
|
+AC_HEADER_MAJOR
|
|
+fi
|
|
+
|
|
# bluetooth/bluetooth.h has been known to not compile with -std=c99.
|
|
# http://permalink.gmane.org/gmane.linux.bluez.kernel/22294
|
|
SAVE_CFLAGS=$CFLAGS
|
|
@@ -2852,6 +3035,10 @@ dnl LFS does not work with Emscripten 3.1
|
|
AS_CASE([$ac_sys_system],
|
|
[Emscripten], [have_largefile_support="no"]
|
|
)
|
|
+dnl Activate on windows platforms (32&64-bit) where off_t(4) < fpos_t(8)
|
|
+AS_CASE([$ac_sys_system],
|
|
+ [MINGW], [have_largefile_support="yes"]
|
|
+)
|
|
AS_VAR_IF([have_largefile_support], [yes], [
|
|
AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1,
|
|
[Defined to enable large file support when an off_t is bigger than a long
|
|
@@ -2882,6 +3069,10 @@ elif test "$ac_cv_pthread" = "yes"
|
|
then CC="$CC -pthread"
|
|
fi
|
|
|
|
+if test $with_nt_threads = yes ; then
|
|
+ dnl skip check for pthread_t if NT-thread model is enabled
|
|
+ ac_cv_have_pthread_t=skip
|
|
+else
|
|
AC_CACHE_CHECK([for pthread_t], [ac_cv_have_pthread_t], [
|
|
AC_COMPILE_IFELSE([
|
|
AC_LANG_PROGRAM([[#include <pthread.h>]], [[pthread_t x; x = *(pthread_t*)0;]])
|
|
@@ -2913,7 +3104,7 @@ AS_VAR_IF([ac_cv_pthread_key_t_is_arithmetic_type], [yes], [
|
|
AC_DEFINE(PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT, 1,
|
|
[Define if pthread_key_t is compatible with int.])
|
|
])
|
|
-
|
|
+fi
|
|
CC="$ac_save_cc"
|
|
|
|
AC_SUBST(OTHER_LIBTOOL_OPT)
|
|
@@ -3089,6 +3280,9 @@ if test -z "$SHLIB_SUFFIX"; then
|
|
CYGWIN*) SHLIB_SUFFIX=.dll;;
|
|
*) SHLIB_SUFFIX=.so;;
|
|
esac
|
|
+ case $host_os in
|
|
+ mingw*) SHLIB_SUFFIX=.pyd;;
|
|
+ esac
|
|
fi
|
|
AC_MSG_RESULT($SHLIB_SUFFIX)
|
|
|
|
@@ -3218,6 +3412,10 @@ then
|
|
CYGWIN*)
|
|
LDSHARED="gcc -shared -Wl,--enable-auto-image-base"
|
|
LDCXXSHARED="g++ -shared -Wl,--enable-auto-image-base";;
|
|
+ MINGW*)
|
|
+ LDSHARED='$(CC) -shared -Wl,--enable-auto-image-base'
|
|
+ LDCXXSHARED='$(CXX) -shared -Wl,--enable-auto-image-base'
|
|
+ ;;
|
|
*) LDSHARED="ld";;
|
|
esac
|
|
fi
|
|
@@ -3341,6 +3539,11 @@ then
|
|
VxWorks*)
|
|
LINKFORSHARED='-Wl,-export-dynamic';;
|
|
esac
|
|
+ case $host in
|
|
+ *-*-mingw*)
|
|
+ # for https://bugs.python.org/issue40458 on MINGW
|
|
+ LINKFORSHARED="-Wl,--stack,2000000";;
|
|
+ esac
|
|
fi
|
|
AC_MSG_RESULT($LINKFORSHARED)
|
|
|
|
@@ -3385,7 +3588,12 @@ AC_MSG_RESULT($SHLIBS)
|
|
|
|
# checks for libraries
|
|
AC_CHECK_LIB(sendfile, sendfile)
|
|
-AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV
|
|
+
|
|
+case $host in
|
|
+ *-*-mingw*) ;;
|
|
+ *) AC_CHECK_LIB(dl, dlopen) ;; # Dynamic linking for SunOS/Solaris and SYSV
|
|
+esac
|
|
+
|
|
AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX
|
|
|
|
|
|
@@ -3448,16 +3656,30 @@ AS_VAR_IF([have_uuid], [missing], [
|
|
|
|
AS_VAR_IF([have_uuid], [missing], [have_uuid=no])
|
|
|
|
+if test $with_nt_threads = yes ; then
|
|
+ dnl do not search for sem_init if NT-thread model is enabled
|
|
+ :
|
|
+else
|
|
# 'Real Time' functions on Solaris
|
|
# posix4 on Solaris 2.6
|
|
# pthread (first!) on Linux
|
|
AC_SEARCH_LIBS(sem_init, pthread rt posix4)
|
|
+fi
|
|
|
|
# check if we need libintl for locale functions
|
|
+case $host in
|
|
+ *-*-mingw*)
|
|
+ dnl Native windows build don't use libintl (see _localemodule.c).
|
|
+ dnl Also we don't like setup.py to add "intl" library to the list
|
|
+ dnl when build _locale module.
|
|
+ ;;
|
|
+ *)
|
|
AC_CHECK_LIB(intl, textdomain,
|
|
[AC_DEFINE(WITH_LIBINTL, 1,
|
|
[Define to 1 if libintl is needed for locale functions.])
|
|
LIBS="-lintl $LIBS"])
|
|
+ ;;
|
|
+esac
|
|
|
|
# checks for system dependent C++ extensions support
|
|
case "$ac_sys_system" in
|
|
@@ -3645,7 +3867,7 @@ else
|
|
fi
|
|
|
|
if test "$with_system_ffi" = "yes" && test -n "$PKG_CONFIG"; then
|
|
- LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ *$//'`"
|
|
+ LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ .*$//'`"
|
|
else
|
|
LIBFFI_INCLUDEDIR=""
|
|
fi
|
|
@@ -3780,6 +4002,12 @@ AS_CASE([$ac_sys_system],
|
|
[OSSAUDIODEV_LIBS=""]
|
|
)
|
|
|
|
+dnl On MINGW, you need to link against ws2_32 and iphlpapi for sockets to work
|
|
+AS_CASE([$ac_sys_system],
|
|
+ [MINGW], [SOCKET_LIBS="-lws2_32 -liphlpapi"],
|
|
+ [SOCKET_LIBS=""]
|
|
+)
|
|
+
|
|
dnl detect sqlite3 from Emscripten emport
|
|
PY_CHECK_EMSCRIPTEN_PORT([LIBSQLITE3], [-sUSE_SQLITE3])
|
|
|
|
@@ -4042,6 +4270,18 @@ AS_VAR_IF([with_dbmliborder], [error], [
|
|
])
|
|
AC_MSG_RESULT($with_dbmliborder)
|
|
|
|
+case $host in
|
|
+ *-*-mingw*)
|
|
+ CFLAGS_NODIST="$CFLAGS_NODIST -D_WIN32_WINNT=0x0602";;
|
|
+esac
|
|
+
|
|
+# Determine if windows modules should be used.
|
|
+AC_SUBST(USE_WIN32_MODULE)
|
|
+USE_WIN32_MODULE='#'
|
|
+case $host in
|
|
+ *-*-mingw*) USE_WIN32_MODULE=;;
|
|
+esac
|
|
+
|
|
# Templates for things AC_DEFINEd more than once.
|
|
# For a single AC_DEFINE, no template is needed.
|
|
AH_TEMPLATE(_REENTRANT,
|
|
@@ -4076,6 +4316,11 @@ then
|
|
CXX="$CXX -pthread"
|
|
fi
|
|
posix_threads=yes
|
|
+elif test $with_nt_threads = yes
|
|
+then
|
|
+ posix_threads=no
|
|
+ AC_DEFINE(NT_THREADS, 1,
|
|
+ [Define to 1 if you want to use native NT threads])
|
|
else
|
|
if test ! -z "$withval" -a -d "$withval"
|
|
then LDFLAGS="$LDFLAGS -L$withval"
|
|
@@ -4450,11 +4695,14 @@ AC_MSG_RESULT($with_freelists)
|
|
AC_MSG_CHECKING(for --with-c-locale-coercion)
|
|
AC_ARG_WITH(c-locale-coercion,
|
|
AS_HELP_STRING([--with-c-locale-coercion],
|
|
- [enable C locale coercion to a UTF-8 based locale (default is yes)]))
|
|
+ [enable C locale coercion to a UTF-8 based locale (default is yes on Unix, no on Windows)]))
|
|
|
|
if test -z "$with_c_locale_coercion"
|
|
then
|
|
- with_c_locale_coercion="yes"
|
|
+ case $host in
|
|
+ *-*-mingw*) with_c_locale_coercion="no";;
|
|
+ *) with_c_locale_coercion="yes";;
|
|
+ esac
|
|
fi
|
|
if test "$with_c_locale_coercion" != "no"
|
|
then
|
|
@@ -4555,12 +4803,36 @@ then
|
|
fi
|
|
;;
|
|
esac
|
|
+ case $host in
|
|
+ *-*-mingw*)
|
|
+ DYNLOADFILE="dynload_win.o"
|
|
+ extra_machdep_objs="$extra_machdep_objs PC/dl_nt.o"
|
|
+ CFLAGS_NODIST="$CFLAGS_NODIST -DPY3_DLLNAME='L\"$DLLLIBRARY\"'"
|
|
+ case $host in
|
|
+ i686*)
|
|
+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-32\"'"
|
|
+ ;;
|
|
+ armv7*)
|
|
+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-arm32\"'"
|
|
+ ;;
|
|
+ aarch64*)
|
|
+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"${VERSION}-arm64\"'"
|
|
+ ;;
|
|
+ *)
|
|
+ CFLAGS_NODIST="$CFLAGS_NODIST -DMS_DLL_ID='\"$VERSION\"'"
|
|
+ ;;
|
|
+ esac
|
|
+ ;;
|
|
+ esac
|
|
fi
|
|
AC_MSG_RESULT($DYNLOADFILE)
|
|
if test "$DYNLOADFILE" != "dynload_stub.o"
|
|
then
|
|
+ have_dynamic_loading=yes
|
|
AC_DEFINE(HAVE_DYNAMIC_LOADING, 1,
|
|
[Defined when any dynamic module loading is enabled.])
|
|
+else
|
|
+ have_dynamic_loading=no
|
|
fi
|
|
|
|
# MACHDEP_OBJS can be set to platform-specific object files needed by Python
|
|
@@ -4580,13 +4852,22 @@ else
|
|
fi
|
|
|
|
# checks for library functions
|
|
+if test $with_nt_threads = yes ; then
|
|
+ dnl GCC(mingw) 4.4+ require and use posix threads(pthreads-w32)
|
|
+ dnl and host may contain installed pthreads-w32.
|
|
+ dnl Skip checks for some functions declared in pthreads-w32 if
|
|
+ dnl NT-thread model is enabled.
|
|
+ ac_cv_func_pthread_kill=skip
|
|
+ ac_cv_func_sem_open=skip
|
|
+ ac_cv_func_sched_setscheduler=skip
|
|
+fi
|
|
AC_CHECK_FUNCS([ \
|
|
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
|
|
copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
|
|
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
|
|
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
|
|
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
|
|
- getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \
|
|
+ getgrnam_r getgrouplist getgroups getitimer getloadavg getlogin \
|
|
getpeername getpgid getpid getppid getpriority _getpty \
|
|
getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \
|
|
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
|
|
@@ -4599,7 +4880,7 @@ AC_CHECK_FUNCS([ \
|
|
sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \
|
|
sem_timedwait sem_unlink sendfile setegid seteuid setgid sethostname \
|
|
setitimer setlocale setpgid setpgrp setpriority setregid setresgid \
|
|
- setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \
|
|
+ setresuid setreuid setsid setuid setvbuf sigaction sigaltstack \
|
|
sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \
|
|
sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \
|
|
sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \
|
|
@@ -4829,7 +5110,13 @@ PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [
|
|
])
|
|
|
|
dnl PY_CHECK_NETDB_FUNC(FUNCTION)
|
|
-AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [#include <netdb.h>])])
|
|
+AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [
|
|
+#ifdef _WIN32
|
|
+ #include <winsock.h>
|
|
+#else
|
|
+ #include <netdb.h>
|
|
+#endif
|
|
+])])
|
|
|
|
PY_CHECK_NETDB_FUNC([hstrerror])
|
|
dnl not available in WASI yet
|
|
@@ -4838,13 +5125,19 @@ PY_CHECK_NETDB_FUNC([getservbyport])
|
|
PY_CHECK_NETDB_FUNC([gethostbyname])
|
|
PY_CHECK_NETDB_FUNC([gethostbyaddr])
|
|
PY_CHECK_NETDB_FUNC([getprotobyname])
|
|
+PY_CHECK_NETDB_FUNC([gethostname])
|
|
+PY_CHECK_NETDB_FUNC([shutdown])
|
|
|
|
dnl PY_CHECK_SOCKET_FUNC(FUNCTION)
|
|
AC_DEFUN([PY_CHECK_SOCKET_FUNC], [PY_CHECK_FUNC([$1], [
|
|
+#ifdef _WIN32
|
|
+#include <ws2tcpip.h>
|
|
+#else
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
+#endif
|
|
])])
|
|
|
|
PY_CHECK_SOCKET_FUNC([inet_aton])
|
|
@@ -4945,6 +5238,9 @@ WITH_SAVE_ENV([
|
|
])
|
|
])
|
|
|
|
+case $host in
|
|
+ *-*-mingw*) ;;
|
|
+ *)
|
|
AC_CHECK_FUNCS(clock_gettime, [], [
|
|
AC_CHECK_LIB(rt, clock_gettime, [
|
|
LIBS="$LIBS -lrt"
|
|
@@ -4965,6 +5261,8 @@ AC_CHECK_FUNCS(clock_settime, [], [
|
|
AC_DEFINE(HAVE_CLOCK_SETTIME, 1)
|
|
])
|
|
])
|
|
+ ;;
|
|
+esac
|
|
|
|
AC_CHECK_FUNCS(clock_nanosleep, [], [
|
|
AC_CHECK_LIB(rt, clock_nanosleep, [
|
|
@@ -5163,18 +5461,33 @@ if test $ac_cv_header_time_altzone = yes; then
|
|
AC_DEFINE(HAVE_ALTZONE, 1, [Define this if your time.h defines altzone.])
|
|
fi
|
|
|
|
+AC_CHECK_HEADERS([ws2tcpip.h])
|
|
AC_CACHE_CHECK([for addrinfo], [ac_cv_struct_addrinfo],
|
|
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <netdb.h>]], [[struct addrinfo a]])],
|
|
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|
+#ifdef HAVE_WS2TCPIP_H
|
|
+# include <ws2tcpip.h>
|
|
+#else
|
|
+# include <netdb.h>
|
|
+#endif]],
|
|
+ [[struct addrinfo a]])],
|
|
[ac_cv_struct_addrinfo=yes],
|
|
[ac_cv_struct_addrinfo=no]))
|
|
if test $ac_cv_struct_addrinfo = yes; then
|
|
- AC_DEFINE(HAVE_ADDRINFO, 1, [struct addrinfo (netdb.h)])
|
|
+ AC_DEFINE(HAVE_ADDRINFO, 1, [struct addrinfo])
|
|
fi
|
|
|
|
AC_CACHE_CHECK([for sockaddr_storage], [ac_cv_struct_sockaddr_storage],
|
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|
-# include <sys/types.h>
|
|
-# include <sys/socket.h>]], [[struct sockaddr_storage s]])],
|
|
+#ifdef HAVE_WS2TCPIP_H
|
|
+#include <ws2tcpip.h>
|
|
+#endif
|
|
+#ifdef HAVE_SYS_TYPES_H
|
|
+#include <sys/types.h>
|
|
+#endif
|
|
+#ifdef HAVE_SYS_SOCKET_H
|
|
+#include <sys/socket.h>
|
|
+#endif]],
|
|
+ [[struct sockaddr_storage s]])],
|
|
[ac_cv_struct_sockaddr_storage=yes],
|
|
[ac_cv_struct_sockaddr_storage=no]))
|
|
if test $ac_cv_struct_sockaddr_storage = yes; then
|
|
@@ -5508,6 +5821,10 @@ dnl actually works. For FreeBSD versions <= 7.2,
|
|
dnl the kernel module that provides POSIX semaphores
|
|
dnl isn't loaded by default, so an attempt to call
|
|
dnl sem_open results in a 'Signal 12' error.
|
|
+if test $with_nt_threads = yes ; then
|
|
+ dnl skip posix semaphores test if NT-thread model is enabled
|
|
+ ac_cv_posix_semaphores_enabled=no
|
|
+fi
|
|
AC_CACHE_CHECK([whether POSIX semaphores are enabled], [ac_cv_posix_semaphores_enabled],
|
|
AC_RUN_IFELSE([
|
|
AC_LANG_SOURCE([
|
|
@@ -5541,6 +5858,14 @@ AS_VAR_IF([ac_cv_posix_semaphores_enabled], [no], [
|
|
])
|
|
|
|
dnl Multiprocessing check for broken sem_getvalue
|
|
+if test $with_nt_threads = yes ; then
|
|
+ dnl Skip test if NT-thread model is enabled.
|
|
+ dnl NOTE the test case below fail for pthreads-w32 as:
|
|
+ dnl - SEM_FAILED is not defined;
|
|
+ dnl - sem_open is a stub;
|
|
+ dnl - sem_getvalue work(!).
|
|
+ ac_cv_broken_sem_getvalue=skip
|
|
+fi
|
|
AC_CACHE_CHECK([for broken sem_getvalue], [ac_cv_broken_sem_getvalue],
|
|
AC_RUN_IFELSE([
|
|
AC_LANG_SOURCE([
|
|
@@ -5577,7 +5902,10 @@ AS_VAR_IF([ac_cv_broken_sem_getvalue], [yes], [
|
|
)
|
|
])
|
|
|
|
-AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include <dlfcn.h>]])
|
|
+case $host in
|
|
+ *-*-mingw*) ;;
|
|
+ *) AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include <dlfcn.h>]]);;
|
|
+esac
|
|
|
|
# determine what size digit to use for Python's longs
|
|
AC_MSG_CHECKING([digit size for Python's longs])
|
|
@@ -5664,6 +5992,71 @@ esac
|
|
# check for endianness
|
|
AC_C_BIGENDIAN
|
|
|
|
+AC_SUBST(PYD_PLATFORM_TAG)
|
|
+# Special case of PYD_PLATFORM_TAG with python build with mingw.
|
|
+# Python can with compiled with clang or gcc and linked
|
|
+# to msvcrt or ucrt. To avoid conflicts between them
|
|
+# we are selecting the extension as based on the compiler
|
|
+# and the runtime they link to
|
|
+# gcc + x86_64 + msvcrt = cp{version number}-x86_64
|
|
+# gcc + i686 + msvcrt = cp{version number}-i686
|
|
+# gcc + x86_64 + ucrt = cp{version number}-x86_64-ucrt
|
|
+# clang + x86_64 + ucrt = cp{version number}-x86_64-clang
|
|
+# clang + i686 + ucrt = cp{version number}-i686-clang
|
|
+
|
|
+PYD_PLATFORM_TAG=""
|
|
+case $host in
|
|
+ *-*-mingw*)
|
|
+ # check if we are linking to ucrt
|
|
+ AC_MSG_CHECKING(whether linking to ucrt)
|
|
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
|
+ #include <stdio.h>
|
|
+ #ifndef _UCRT
|
|
+ #error no ucrt
|
|
+ #endif
|
|
+ int main(){ return 0; }
|
|
+ ]])],[linking_to_ucrt=yes],[linking_to_ucrt=no])
|
|
+ AC_MSG_RESULT($linking_to_ucrt)
|
|
+ ;;
|
|
+esac
|
|
+case $host_os in
|
|
+ mingw*)
|
|
+ AC_MSG_CHECKING(PYD_PLATFORM_TAG)
|
|
+ case $host in
|
|
+ i686-*-mingw*)
|
|
+ if test -n "${cc_is_clang}"; then
|
|
+ # it is CLANG32
|
|
+ PYD_PLATFORM_TAG="mingw_i686_clang"
|
|
+ else
|
|
+ if test $linking_to_ucrt = no; then
|
|
+ PYD_PLATFORM_TAG="mingw_i686"
|
|
+ else
|
|
+ PYD_PLATFORM_TAG="mingw_i686_ucrt"
|
|
+ fi
|
|
+ fi
|
|
+ ;;
|
|
+ x86_64-*-mingw*)
|
|
+ if test -n "${cc_is_clang}"; then
|
|
+ # it is CLANG64
|
|
+ PYD_PLATFORM_TAG="mingw_x86_64_clang"
|
|
+ else
|
|
+ if test $linking_to_ucrt = no; then
|
|
+ PYD_PLATFORM_TAG="mingw_x86_64"
|
|
+ else
|
|
+ PYD_PLATFORM_TAG="mingw_x86_64_ucrt"
|
|
+ fi
|
|
+ fi
|
|
+ ;;
|
|
+ aarch64-*-mingw*)
|
|
+ PYD_PLATFORM_TAG+="mingw_aarch64"
|
|
+ ;;
|
|
+ armv7-*-mingw*)
|
|
+ PYD_PLATFORM_TAG+="mingw_armv7"
|
|
+ ;;
|
|
+ esac
|
|
+ AC_MSG_RESULT($PYD_PLATFORM_TAG)
|
|
+esac
|
|
+
|
|
# ABI version string for Python extension modules. This appears between the
|
|
# periods in shared library file names, e.g. foo.<SOABI>.so. It is calculated
|
|
# from the following attributes which affect the ABI of this Python build (in
|
|
@@ -5696,7 +6089,12 @@ if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then
|
|
fi
|
|
|
|
AC_SUBST(EXT_SUFFIX)
|
|
-EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX}
|
|
+VERSION_NO_DOTS=$(echo $LDVERSION | tr -d .)
|
|
+if test -n "${PYD_PLATFORM_TAG}"; then
|
|
+ EXT_SUFFIX=".cp${VERSION_NO_DOTS}-${PYD_PLATFORM_TAG}${SHLIB_SUFFIX}"
|
|
+else
|
|
+ EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX}
|
|
+fi
|
|
|
|
AC_MSG_CHECKING(LDVERSION)
|
|
LDVERSION='$(VERSION)$(ABIFLAGS)'
|
|
@@ -5704,7 +6102,7 @@ AC_MSG_RESULT($LDVERSION)
|
|
|
|
# On Android and Cygwin the shared libraries must be linked with libpython.
|
|
AC_SUBST(LIBPYTHON)
|
|
-if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin"; then
|
|
+if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin" -o "$MACHDEP" = "win32"; then
|
|
LIBPYTHON="-lpython${VERSION}${ABIFLAGS}"
|
|
else
|
|
LIBPYTHON=''
|
|
@@ -6073,11 +6471,16 @@ then
|
|
[Define if you have struct stat.st_mtimensec])
|
|
fi
|
|
|
|
+if test -n "$PKG_CONFIG"; then
|
|
+ NCURSESW_INCLUDEDIR="`"$PKG_CONFIG" ncursesw --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ .*$//'`"
|
|
+else
|
|
+ NCURSESW_INCLUDEDIR=""
|
|
+fi
|
|
+AC_SUBST(NCURSESW_INCLUDEDIR)
|
|
+
|
|
# first curses header check
|
|
ac_save_cppflags="$CPPFLAGS"
|
|
-if test "$cross_compiling" = no; then
|
|
- CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
|
|
-fi
|
|
+CPPFLAGS="$CPPFLAGS -I$NCURSESW_INCLUDEDIR"
|
|
|
|
AC_CHECK_HEADERS(curses.h ncurses.h)
|
|
|
|
@@ -6243,7 +6646,10 @@ fi
|
|
|
|
AC_CHECK_TYPE(socklen_t,,
|
|
AC_DEFINE(socklen_t,int,
|
|
- [Define to `int' if <sys/socket.h> does not define.]),[
|
|
+ [Define to `int' if <sys/socket.h> or <ws2tcpip.h> does not define.]),[
|
|
+#ifdef HAVE_WS2TCPIP_H
|
|
+#include <ws2tcpip.h>
|
|
+#endif
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
#include <sys/types.h>
|
|
#endif
|
|
@@ -6333,6 +6739,27 @@ do
|
|
THREADHEADERS="$THREADHEADERS \$(srcdir)/$h"
|
|
done
|
|
|
|
+case $host in
|
|
+ *-*-mingw*)
|
|
+ dnl Required for windows builds as Objects/exceptions.c require
|
|
+ dnl "errmap.h" from $srcdir/PC.
|
|
+ dnl Note we cannot use BASECPPFLAGS as autogenerated pyconfig.h
|
|
+ dnl has to be before customized located in ../PC.
|
|
+ dnl (-I. at end is workaround for setup.py logic)
|
|
+ CPPFLAGS="-I\$(srcdir)/PC $CPPFLAGS -I."
|
|
+ ;;
|
|
+esac
|
|
+
|
|
+dnl Python interpreter main program for frozen scripts
|
|
+AC_SUBST(PYTHON_OBJS_FROZENMAIN)
|
|
+PYTHON_OBJS_FROZENMAIN="Python/frozenmain.o"
|
|
+case $host in
|
|
+ *-*-mingw*)
|
|
+ dnl 'PC/frozen_dllmain.c' - not yet
|
|
+ PYTHON_OBJS_FROZENMAIN=
|
|
+ ;;
|
|
+esac
|
|
+
|
|
AC_SUBST(SRCDIRS)
|
|
SRCDIRS="\
|
|
Modules \
|
|
@@ -6354,6 +6781,10 @@ SRCDIRS="\
|
|
Python \
|
|
Python/frozen_modules \
|
|
Python/deepfreeze"
|
|
+case $host in
|
|
+ *-*-mingw*) SRCDIRS="$SRCDIRS PC";;
|
|
+esac
|
|
+
|
|
AC_MSG_CHECKING(for build directories)
|
|
for dir in $SRCDIRS; do
|
|
if test ! -d $dir; then
|
|
@@ -6362,6 +6793,38 @@ for dir in $SRCDIRS; do
|
|
done
|
|
AC_MSG_RESULT(done)
|
|
|
|
+# For mingw build need additional library for linking
|
|
+case $host in
|
|
+ *-*-mingw*)
|
|
+ LIBS="$LIBS -lversion -lshlwapi -lpathcch -lbcrypt"
|
|
+ AC_PROG_AWK
|
|
+ if test "$AWK" = "gawk"; then
|
|
+ awk_extra_flag="--non-decimal-data"
|
|
+ fi
|
|
+ AC_MSG_CHECKING([FIELD3])
|
|
+ FIELD3=$($AWK $awk_extra_flag '\
|
|
+ /^#define PY_RELEASE_LEVEL_/ {levels[$2]=$3} \
|
|
+ /^#define PY_MICRO_VERSION[[:space:]]+/ {micro=$3} \
|
|
+ /^#define PY_RELEASE_LEVEL[[:space:]]+/ {level=levels[$3]} \
|
|
+ /^#define PY_RELEASE_SERIAL[[:space:]]+/ {serial=$3} \
|
|
+ END {print micro * 1000 + level * 10 + serial}' \
|
|
+ $srcdir/Include/patchlevel.h
|
|
+ )
|
|
+
|
|
+ AC_MSG_RESULT([${FIELD3}])
|
|
+ RCFLAGS="$RCFLAGS -DFIELD3=$FIELD3 -O COFF"
|
|
+
|
|
+ case $host in
|
|
+ i686*) RCFLAGS="$RCFLAGS --target=pe-i386" ;;
|
|
+ x86_64*) RCFLAGS="$RCFLAGS --target=pe-x86-64" ;;
|
|
+ *) ;;
|
|
+ esac
|
|
+ ;;
|
|
+ *)
|
|
+ ;;
|
|
+esac
|
|
+AC_SUBST(RCFLAGS)
|
|
+
|
|
# Availability of -O2:
|
|
AC_CACHE_CHECK([for -O2], [ac_cv_compile_o2], [
|
|
saved_cflags="$CFLAGS"
|
|
@@ -6971,7 +7434,6 @@ PY_STDLIB_MOD_SIMPLE([_json])
|
|
PY_STDLIB_MOD_SIMPLE([_lsprof])
|
|
PY_STDLIB_MOD_SIMPLE([_opcode])
|
|
PY_STDLIB_MOD_SIMPLE([_pickle])
|
|
-PY_STDLIB_MOD_SIMPLE([_posixsubprocess])
|
|
PY_STDLIB_MOD_SIMPLE([_queue])
|
|
PY_STDLIB_MOD_SIMPLE([_random])
|
|
PY_STDLIB_MOD_SIMPLE([select])
|
|
@@ -6982,7 +7444,7 @@ PY_STDLIB_MOD_SIMPLE([_zoneinfo])
|
|
|
|
dnl multiprocessing modules
|
|
PY_STDLIB_MOD([_multiprocessing],
|
|
- [], [test "$ac_cv_func_sem_unlink" = "yes"],
|
|
+ [], [test "$ac_cv_func_sem_unlink" = "yes" -o "$MACHDEP" = "win32"],
|
|
[-I\$(srcdir)/Modules/_multiprocessing])
|
|
PY_STDLIB_MOD([_posixshmem],
|
|
[], [test "$have_posix_shmem" = "yes"],
|
|
@@ -7002,11 +7464,15 @@ PY_STDLIB_MOD([fcntl],
|
|
[], [test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes"],
|
|
[], [$FCNTL_LIBS])
|
|
PY_STDLIB_MOD([mmap],
|
|
- [], [test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes"])
|
|
+ [], m4_flatten([test "$ac_cv_header_sys_mman_h" = "yes"
|
|
+ -a "$ac_cv_header_sys_stat_h" = "yes"
|
|
+ -o "$MACHDEP" = "win32"]))
|
|
PY_STDLIB_MOD([_socket],
|
|
[], m4_flatten([test "$ac_cv_header_sys_socket_h" = "yes"
|
|
-a "$ac_cv_header_sys_types_h" = "yes"
|
|
- -a "$ac_cv_header_netinet_in_h" = "yes"]))
|
|
+ -a "$ac_cv_header_netinet_in_h" = "yes"
|
|
+ -o "$MACHDEP" = "win32"]),
|
|
+ [], [$SOCKET_LIBS])
|
|
|
|
dnl platform specific extensions
|
|
PY_STDLIB_MOD([grp], [], [test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes])
|
|
@@ -7021,6 +7487,7 @@ PY_STDLIB_MOD([_scproxy],
|
|
PY_STDLIB_MOD([spwd], [], [test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes])
|
|
PY_STDLIB_MOD([syslog], [], [test "$ac_cv_header_syslog_h" = yes])
|
|
PY_STDLIB_MOD([termios], [], [test "$ac_cv_header_termios_h" = yes])
|
|
+PY_STDLIB_MOD([_posixsubprocess], [], [test "$MACHDEP" != "win32"])
|
|
|
|
dnl _elementtree loads libexpat via CAPI hook in pyexpat
|
|
PY_STDLIB_MOD([pyexpat], [], [], [$LIBEXPAT_CFLAGS], [$LIBEXPAT_LDFLAGS])
|
|
@@ -7083,25 +7550,35 @@ PY_STDLIB_MOD([_lzma], [], [test "$have_liblzma" = yes],
|
|
|
|
dnl OpenSSL bindings
|
|
PY_STDLIB_MOD([_ssl], [], [test "$ac_cv_working_openssl_ssl" = yes],
|
|
- [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS])
|
|
+ [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS -lws2_32])
|
|
PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes],
|
|
[$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS])
|
|
|
|
+dnl windows specific modules
|
|
+PY_STDLIB_MOD([msvcrt], [test "$MACHDEP" = "win32"])
|
|
+PY_STDLIB_MOD([_winapi], [test "$MACHDEP" = "win32"])
|
|
+PY_STDLIB_MOD([_msi], [test "$MACHDEP" = "win32"], [], [],
|
|
+ [-lmsi -lcabinet -lrpcrt4])
|
|
+PY_STDLIB_MOD([winsound], [test "$MACHDEP" = "win32"], [], [],
|
|
+ [-lwinmm])
|
|
+PY_STDLIB_MOD([_overlapped], [test "$MACHDEP" = "win32"], [], [],
|
|
+ [-lws2_32])
|
|
+
|
|
dnl test modules
|
|
PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes])
|
|
PY_STDLIB_MOD([_testclinic], [test "$TEST_MODULES" = yes])
|
|
-PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes])
|
|
+PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes], [], [-DPY3_DLLNAME="\"$DLLLIBRARY\""], [])
|
|
PY_STDLIB_MOD([_testbuffer], [test "$TEST_MODULES" = yes])
|
|
-PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes])
|
|
-PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes])
|
|
+PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes])
|
|
+PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes])
|
|
PY_STDLIB_MOD([_xxtestfuzz], [test "$TEST_MODULES" = yes])
|
|
-PY_STDLIB_MOD([_ctypes_test], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes], [], [-lm])
|
|
+PY_STDLIB_MOD([_ctypes_test], [test "$TEST_MODULES" = yes], [test "$have_dynamic_loading" = yes], [], [-lm])
|
|
|
|
dnl Limited API template modules.
|
|
dnl The limited C API is not compatible with the Py_TRACE_REFS macro.
|
|
dnl Emscripten does not support shared libraries yet.
|
|
-PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes])
|
|
-PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes])
|
|
+PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$have_dynamic_loading" = yes])
|
|
+PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$have_dynamic_loading" = yes])
|
|
|
|
# substitute multiline block, must come after last PY_STDLIB_MOD()
|
|
AC_SUBST([MODULE_BLOCK])
|
|
diff --git a/mingw_ignorefile.txt b/mingw_ignorefile.txt
|
|
new file mode 100755
|
|
index 0000000..54093f1
|
|
--- /dev/null
|
|
+++ b/mingw_ignorefile.txt
|
|
@@ -0,0 +1,42 @@
|
|
+ctypes.test.test_loading.LoaderTest.test_load_dll_with_flags
|
|
+distutils.tests.test_bdist_dumb.BuildDumbTestCase.test_simple_built
|
|
+distutils.tests.test_cygwinccompiler.CygwinCCompilerTestCase.test_get_versions
|
|
+distutils.tests.test_util.UtilTestCase.test_change_root
|
|
+test.datetimetester.TestLocalTimeDisambiguation_Fast.*
|
|
+test.datetimetester.TestLocalTimeDisambiguation_Pure.*
|
|
+test.test_cmath.CMathTests.test_specific_values
|
|
+test.test_cmd_line_script.CmdLineTest.test_consistent_sys_path_for_direct_execution
|
|
+test.test_compileall.CommandLineTestsNoSourceEpoch.*
|
|
+test.test_compileall.CommandLineTestsWithSourceEpoch.*
|
|
+test.test_compileall.CompileallTestsWithoutSourceEpoch.*
|
|
+test.test_compileall.CompileallTestsWithSourceEpoch.*
|
|
+test.test_import.ImportTests.test_dll_dependency_import
|
|
+test.test_math.MathTests.*
|
|
+test.test_ntpath.NtCommonTest.test_import
|
|
+test.test_os.StatAttributeTests.test_stat_block_device
|
|
+test.test_os.TestScandir.test_attributes
|
|
+test.test_os.UtimeTests.test_large_time
|
|
+test.test_platform.PlatformTest.test_architecture_via_symlink
|
|
+test.test_regrtest.ProgramsTestCase.test_pcbuild_rt
|
|
+test.test_regrtest.ProgramsTestCase.test_tools_buildbot_test
|
|
+test.test_site._pthFileTests.*
|
|
+test.test_site.HelperFunctionsTests.*
|
|
+test.test_site.StartupImportTests.*
|
|
+test.test_ssl.*
|
|
+test.test_strptime.CalculationTests.*
|
|
+test.test_strptime.StrptimeTests.test_weekday
|
|
+test.test_strptime.TimeRETests.test_compile
|
|
+test.test_tools.test_i18n.Test_pygettext.test_POT_Creation_Date
|
|
+test.test_venv.BasicTest.*
|
|
+test.test_venv.EnsurePipTest.*
|
|
+test.test_sysconfig.TestSysConfig.test_user_similar
|
|
+test.test_tcl.TclTest.testLoadWithUNC
|
|
+# flaky
|
|
+test.test__xxsubinterpreters.*
|
|
+test.test_asyncio.test_subprocess.SubprocessProactorTests.test_stdin_broken_pipe
|
|
+test.test_asynchat.TestAsynchat.test_line_terminator2
|
|
+test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_gc_aclose_09
|
|
+test.test_concurrent_futures.ThreadPoolShutdownTest.test_interpreter_shutdown
|
|
+test.test_asynchat.TestNotConnected.test_disallow_negative_terminator
|
|
+test.test_logging.SysLogHandlerTest.*
|
|
+test.test_logging.IPv6SysLogHandlerTest.*
|
|
diff --git a/mingw_smoketests.py b/mingw_smoketests.py
|
|
new file mode 100755
|
|
index 0000000..ca1f652
|
|
--- /dev/null
|
|
+++ b/mingw_smoketests.py
|
|
@@ -0,0 +1,358 @@
|
|
+#!/usr/bin/env python3
|
|
+# Copyright 2017 Christoph Reiter
|
|
+#
|
|
+# Permission is hereby granted, free of charge, to any person obtaining
|
|
+# a copy of this software and associated documentation files (the
|
|
+# "Software"), to deal in the Software without restriction, including
|
|
+# without limitation the rights to use, copy, modify, merge, publish,
|
|
+# distribute, sublicense, and/or sell copies of the Software, and to
|
|
+# permit persons to whom the Software is furnished to do so, subject to
|
|
+# the following conditions:
|
|
+#
|
|
+# The above copyright notice and this permission notice shall be included
|
|
+# in all copies or substantial portions of the Software.
|
|
+#
|
|
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+
|
|
+"""The goal of this test suite is collect tests for update regressions
|
|
+and to test msys2 related modifications like for path handling.
|
|
+Feel free to extend.
|
|
+"""
|
|
+
|
|
+import os
|
|
+import unittest
|
|
+import sysconfig
|
|
+
|
|
+if os.environ.get("MSYSTEM", ""):
|
|
+ SEP = "/"
|
|
+else:
|
|
+ SEP = "\\"
|
|
+
|
|
+if sysconfig.is_python_build():
|
|
+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1"
|
|
+
|
|
+_UCRT = sysconfig.get_platform() not in ('mingw_x86_64', 'mingw_i686')
|
|
+
|
|
+
|
|
+class Tests(unittest.TestCase):
|
|
+
|
|
+ def test_zoneinfo(self):
|
|
+ # https://github.com/msys2-contrib/cpython-mingw/issues/32
|
|
+ import zoneinfo
|
|
+ self.assertTrue(any(os.path.exists(p) for p in zoneinfo.TZPATH))
|
|
+ zoneinfo.ZoneInfo("America/Sao_Paulo")
|
|
+
|
|
+ def test_userdir_path_sep(self):
|
|
+ # Make sure os.path and pathlib use the same path separators
|
|
+ from unittest import mock
|
|
+ from os.path import expanduser
|
|
+ from pathlib import Path
|
|
+
|
|
+ profiles = ["C:\\foo", "C:/foo"]
|
|
+ for profile in profiles:
|
|
+ with mock.patch.dict(os.environ, {"USERPROFILE": profile}):
|
|
+ self.assertEqual(expanduser("~"), os.path.normpath(expanduser("~")))
|
|
+ self.assertEqual(str(Path("~").expanduser()), expanduser("~"))
|
|
+ self.assertEqual(str(Path.home()), expanduser("~"))
|
|
+
|
|
+ def test_sysconfig_schemes(self):
|
|
+ # https://github.com/msys2/MINGW-packages/issues/9319
|
|
+ import sysconfig
|
|
+ from distutils.dist import Distribution
|
|
+ from distutils.command.install import install
|
|
+
|
|
+ names = ['scripts', 'purelib', 'platlib', 'data', 'include']
|
|
+ for scheme in ["nt", "nt_user"]:
|
|
+ for name in names:
|
|
+ c = install(Distribution({"name": "foobar"}))
|
|
+ c.user = (scheme == "nt_user")
|
|
+ c.finalize_options()
|
|
+ if name == "include":
|
|
+ dist_path = os.path.dirname(getattr(c, "install_" + "headers"))
|
|
+ else:
|
|
+ dist_path = getattr(c, "install_" + name)
|
|
+ sys_path = sysconfig.get_path(name, scheme)
|
|
+ self.assertEqual(dist_path, sys_path, (scheme, name))
|
|
+
|
|
+ def test_ctypes_find_library(self):
|
|
+ from ctypes.util import find_library
|
|
+ from ctypes import cdll
|
|
+ self.assertTrue(cdll.msvcrt)
|
|
+ if _UCRT:
|
|
+ self.assertIsNone(find_library('c'))
|
|
+ else:
|
|
+ self.assertEqual(find_library('c'), 'msvcrt.dll')
|
|
+
|
|
+ def test_ctypes_dlopen(self):
|
|
+ import ctypes
|
|
+ import sys
|
|
+ self.assertEqual(ctypes.RTLD_GLOBAL, 0)
|
|
+ self.assertEqual(ctypes.RTLD_GLOBAL, ctypes.RTLD_LOCAL)
|
|
+ self.assertFalse(hasattr(sys, 'setdlopenflags'))
|
|
+ self.assertFalse(hasattr(sys, 'getdlopenflags'))
|
|
+ self.assertFalse([n for n in dir(os) if n.startswith("RTLD_")])
|
|
+
|
|
+ def test_time_no_unix_stuff(self):
|
|
+ import time
|
|
+ self.assertFalse([n for n in dir(time) if n.startswith("clock_")])
|
|
+ self.assertFalse([n for n in dir(time) if n.startswith("CLOCK_")])
|
|
+ self.assertFalse([n for n in dir(time) if n.startswith("pthread_")])
|
|
+ self.assertFalse(hasattr(time, 'tzset'))
|
|
+
|
|
+ def test_strftime(self):
|
|
+ import time
|
|
+ with self.assertRaises(ValueError):
|
|
+ time.strftime('%Y', (12345,) + (0,) * 8)
|
|
+
|
|
+ def test_sep(self):
|
|
+ self.assertEqual(os.sep, SEP)
|
|
+
|
|
+ def test_module_file_path(self):
|
|
+ import asyncio
|
|
+ import zlib
|
|
+ self.assertEqual(zlib.__file__, os.path.normpath(zlib.__file__))
|
|
+ self.assertEqual(asyncio.__file__, os.path.normpath(asyncio.__file__))
|
|
+
|
|
+ def test_importlib_frozen_path_sep(self):
|
|
+ import importlib._bootstrap_external
|
|
+ self.assertEqual(importlib._bootstrap_external.path_sep, SEP)
|
|
+
|
|
+ def test_os_commonpath(self):
|
|
+ self.assertEqual(
|
|
+ os.path.commonpath(
|
|
+ [os.path.join("C:", os.sep, "foo", "bar"),
|
|
+ os.path.join("C:", os.sep, "foo")]),
|
|
+ os.path.join("C:", os.sep, "foo"))
|
|
+
|
|
+ def test_pathlib(self):
|
|
+ import pathlib
|
|
+
|
|
+ p = pathlib.Path("foo") / pathlib.Path("foo")
|
|
+ self.assertEqual(str(p), os.path.normpath(p))
|
|
+
|
|
+ def test_modules_import(self):
|
|
+ import sqlite3
|
|
+ import ssl
|
|
+ import ctypes
|
|
+ import curses
|
|
+
|
|
+ def test_c_modules_import(self):
|
|
+ import _decimal
|
|
+
|
|
+ def test_socket_inet_ntop(self):
|
|
+ import socket
|
|
+ self.assertTrue(hasattr(socket, "inet_ntop"))
|
|
+
|
|
+ def test_socket_inet_pton(self):
|
|
+ import socket
|
|
+ self.assertTrue(hasattr(socket, "inet_pton"))
|
|
+
|
|
+ def test_multiprocessing_queue(self):
|
|
+ from multiprocessing import Queue
|
|
+ Queue(0)
|
|
+
|
|
+ #def test_socket_timout_normal_error(self):
|
|
+ # import urllib.request
|
|
+ # from urllib.error import URLError
|
|
+
|
|
+ # try:
|
|
+ # urllib.request.urlopen(
|
|
+ # 'http://localhost', timeout=0.0001).close()
|
|
+ # except URLError:
|
|
+ # pass
|
|
+
|
|
+ def test_threads(self):
|
|
+ from concurrent.futures import ThreadPoolExecutor
|
|
+
|
|
+ with ThreadPoolExecutor(1) as pool:
|
|
+ for res in pool.map(lambda *x: None, range(10000)):
|
|
+ pass
|
|
+
|
|
+ def test_sysconfig(self):
|
|
+ import sysconfig
|
|
+ # This should be able to execute without exceptions
|
|
+ sysconfig.get_config_vars()
|
|
+
|
|
+ def test_sqlite_enable_load_extension(self):
|
|
+ # Make sure --enable-loadable-sqlite-extensions is used
|
|
+ import sqlite3
|
|
+ self.assertTrue(sqlite3.Connection.enable_load_extension)
|
|
+
|
|
+ def test_venv_creation(self):
|
|
+ import tempfile
|
|
+ import venv
|
|
+ import subprocess
|
|
+ import shutil
|
|
+ with tempfile.TemporaryDirectory() as tmp:
|
|
+ builder = venv.EnvBuilder()
|
|
+ builder.create(tmp)
|
|
+ assert os.path.exists(os.path.join(tmp, "bin", "activate"))
|
|
+ assert os.path.exists(os.path.join(tmp, "bin", "python.exe"))
|
|
+ assert os.path.exists(os.path.join(tmp, "bin", "python3.exe"))
|
|
+ subprocess.check_call([shutil.which("bash.exe"), os.path.join(tmp, "bin", "activate")])
|
|
+
|
|
+ # This will not work in in-tree build
|
|
+ if not sysconfig.is_python_build():
|
|
+ op = subprocess.check_output(
|
|
+ [
|
|
+ os.path.join(tmp, "bin", "python.exe"),
|
|
+ "-c",
|
|
+ "print('Hello World')"
|
|
+ ],
|
|
+ cwd=tmp,
|
|
+ )
|
|
+ assert op.decode().strip() == "Hello World"
|
|
+
|
|
+ def test_has_mktime(self):
|
|
+ from time import mktime, gmtime
|
|
+ mktime(gmtime())
|
|
+
|
|
+ def test_platform_things(self):
|
|
+ import sys
|
|
+ import sysconfig
|
|
+ import platform
|
|
+ import importlib.machinery
|
|
+ self.assertEqual(sys.implementation.name, "cpython")
|
|
+ self.assertEqual(sys.platform, "win32")
|
|
+ self.assertTrue(sysconfig.get_platform().startswith("mingw"))
|
|
+ self.assertTrue(sysconfig.get_config_var('SOABI').startswith("cpython-"))
|
|
+ ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
|
|
+ self.assertTrue(ext_suffix.endswith(".pyd"))
|
|
+ self.assertTrue("mingw" in ext_suffix)
|
|
+ self.assertEqual(sysconfig.get_config_var('SHLIB_SUFFIX'), ".pyd")
|
|
+ ext_suffixes = importlib.machinery.EXTENSION_SUFFIXES
|
|
+ self.assertTrue(ext_suffix in ext_suffixes)
|
|
+ self.assertTrue(".pyd" in ext_suffixes)
|
|
+ if sysconfig.get_platform().startswith('mingw_i686'):
|
|
+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-32')
|
|
+ elif sysconfig.get_platform().startswith('mingw_aarch64'):
|
|
+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-arm64')
|
|
+ elif sysconfig.get_platform().startswith('mingw_armv7'):
|
|
+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])) + '-arm32')
|
|
+ else:
|
|
+ self.assertEqual(sys.winver, ".".join(map(str, sys.version_info[:2])))
|
|
+ self.assertEqual(platform.python_implementation(), "CPython")
|
|
+ self.assertEqual(platform.system(), "Windows")
|
|
+ self.assertTrue(isinstance(sys.api_version, int) and sys.api_version > 0)
|
|
+
|
|
+ def test_sys_getpath(self):
|
|
+ # everything sourced from getpath.py
|
|
+ import sys
|
|
+
|
|
+ def assertNormpath(path):
|
|
+ self.assertEqual(path, os.path.normpath(path))
|
|
+
|
|
+ assertNormpath(sys.executable)
|
|
+ assertNormpath(sys._base_executable)
|
|
+ assertNormpath(sys.prefix)
|
|
+ assertNormpath(sys.base_prefix)
|
|
+ assertNormpath(sys.exec_prefix)
|
|
+ assertNormpath(sys.base_exec_prefix)
|
|
+ assertNormpath(sys.platlibdir)
|
|
+ assertNormpath(sys._stdlib_dir)
|
|
+ for p in sys.path:
|
|
+ assertNormpath(p)
|
|
+
|
|
+ def test_site(self):
|
|
+ import site
|
|
+
|
|
+ self.assertEqual(len(site.getsitepackages()), 1)
|
|
+
|
|
+ def test_c_ext_build(self):
|
|
+ import tempfile
|
|
+ import sys
|
|
+ import subprocess
|
|
+ import textwrap
|
|
+ from pathlib import Path
|
|
+
|
|
+ with tempfile.TemporaryDirectory() as tmppro:
|
|
+ subprocess.check_call([sys.executable, "-m", "ensurepip", "--user"])
|
|
+ with Path(tmppro, "setup.py").open("w") as f:
|
|
+ f.write(
|
|
+ textwrap.dedent(
|
|
+ """\
|
|
+ from setuptools import setup, Extension
|
|
+
|
|
+ setup(
|
|
+ name='cwrapper',
|
|
+ version='1.0',
|
|
+ ext_modules=[
|
|
+ Extension(
|
|
+ 'cwrapper',
|
|
+ sources=['cwrapper.c']),
|
|
+ ],
|
|
+ )
|
|
+ """
|
|
+ )
|
|
+ )
|
|
+ with Path(tmppro, "cwrapper.c").open("w") as f:
|
|
+ f.write(
|
|
+ textwrap.dedent(
|
|
+ """\
|
|
+ #include <Python.h>
|
|
+ static PyObject *
|
|
+ helloworld(PyObject *self, PyObject *args)
|
|
+ {
|
|
+ printf("Hello World\\n");
|
|
+ Py_RETURN_NONE;
|
|
+ }
|
|
+ static PyMethodDef
|
|
+ myMethods[] = {
|
|
+ { "helloworld", helloworld, METH_NOARGS, "Prints Hello World" },
|
|
+ { NULL, NULL, 0, NULL }
|
|
+ };
|
|
+ static struct PyModuleDef cwrapper = {
|
|
+ PyModuleDef_HEAD_INIT,
|
|
+ "cwrapper",
|
|
+ "Test Module",
|
|
+ -1,
|
|
+ myMethods
|
|
+ };
|
|
+
|
|
+ PyMODINIT_FUNC
|
|
+ PyInit_cwrapper(void)
|
|
+ {
|
|
+ return PyModule_Create(&cwrapper);
|
|
+ }
|
|
+ """
|
|
+ )
|
|
+ )
|
|
+ subprocess.check_call(
|
|
+ [sys.executable, "-c", "import struct"],
|
|
+ )
|
|
+ subprocess.check_call(
|
|
+ [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "wheel",
|
|
+ ],
|
|
+ )
|
|
+ subprocess.check_call(
|
|
+ [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ tmppro,
|
|
+ ],
|
|
+ )
|
|
+ subprocess.check_call(
|
|
+ [sys.executable, "-c", "import cwrapper"],
|
|
+ )
|
|
+
|
|
+
|
|
+
|
|
+def suite():
|
|
+ return unittest.TestLoader().loadTestsFromName(__name__)
|
|
+
|
|
+
|
|
+if __name__ == '__main__':
|
|
+ unittest.main(defaultTest='suite')
|
|
diff --git a/pyconfig.h.in b/pyconfig.h.in
|
|
index 75f1d90..3b89b9e 100644
|
|
--- a/pyconfig.h.in
|
|
+++ b/pyconfig.h.in
|
|
@@ -60,7 +60,7 @@
|
|
/* Define to 1 if you have the `acosh' function. */
|
|
#undef HAVE_ACOSH
|
|
|
|
-/* struct addrinfo (netdb.h) */
|
|
+/* struct addrinfo */
|
|
#undef HAVE_ADDRINFO
|
|
|
|
/* Define to 1 if you have the `alarm' function. */
|
|
@@ -1521,6 +1521,9 @@
|
|
/* Define if mvwdelch in curses.h is an expression. */
|
|
#undef MVWDELCH_IS_EXPRESSION
|
|
|
|
+/* Define to 1 if you want to use native NT threads */
|
|
+#undef NT_THREADS
|
|
+
|
|
/* Define to the address where bug reports for this package should be sent. */
|
|
#undef PACKAGE_BUGREPORT
|
|
|
|
@@ -1836,7 +1839,7 @@
|
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
|
#undef size_t
|
|
|
|
-/* Define to `int' if <sys/socket.h> does not define. */
|
|
+/* Define to `int' if <sys/socket.h> or <ws2tcpip.h> does not define. */
|
|
#undef socklen_t
|
|
|
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
|
diff --git a/setup.py b/setup.py
|
|
index 4f122b6..e4f15d8 100644
|
|
--- a/setup.py
|
|
+++ b/setup.py
|
|
@@ -77,9 +77,24 @@ def get_platform():
|
|
return sys.platform
|
|
|
|
|
|
+# On MSYS, os.system needs to be wrapped with sh.exe
|
|
+# as otherwise all the io redirection will fail.
|
|
+# Arguably, this could happen inside the real os.system
|
|
+# rather than this monkey patch.
|
|
+if sys.platform == "win32" and os.environ.get("MSYSTEM", ""):
|
|
+ os_system = os.system
|
|
+ def msys_system(command):
|
|
+ command_in_sh = 'sh.exe -c "%s"' % command.replace("\\", "\\\\")
|
|
+ return os_system(command_in_sh)
|
|
+ os.system = msys_system
|
|
+
|
|
+ # set PYTHONLEGACYWINDOWSDLLLOADING to 1 to load DLLs from PATH
|
|
+ # This is needed while building core extensions of Python
|
|
+ os.environ["PYTHONLEGACYWINDOWSDLLLOADING"] = "1"
|
|
+
|
|
CROSS_COMPILING = ("_PYTHON_HOST_PLATFORM" in os.environ)
|
|
HOST_PLATFORM = get_platform()
|
|
-MS_WINDOWS = (HOST_PLATFORM == 'win32')
|
|
+MS_WINDOWS = (HOST_PLATFORM == 'win32' or HOST_PLATFORM == 'mingw')
|
|
CYGWIN = (HOST_PLATFORM == 'cygwin')
|
|
MACOS = (HOST_PLATFORM == 'darwin')
|
|
AIX = (HOST_PLATFORM.startswith('aix'))
|
|
@@ -687,7 +702,7 @@ def check_extension_import(self, ext):
|
|
def add_multiarch_paths(self):
|
|
# Debian/Ubuntu multiarch support.
|
|
# https://wiki.ubuntu.com/MultiarchSpec
|
|
- tmpfile = os.path.join(self.build_temp, 'multiarch')
|
|
+ tmpfile = os.path.join(self.build_temp, 'multiarch').replace('\\','/')
|
|
if not os.path.exists(self.build_temp):
|
|
os.makedirs(self.build_temp)
|
|
ret = run_command(
|
|
@@ -712,7 +727,7 @@ def add_multiarch_paths(self):
|
|
opt = ''
|
|
if CROSS_COMPILING:
|
|
opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE')
|
|
- tmpfile = os.path.join(self.build_temp, 'multiarch')
|
|
+ tmpfile = os.path.join(self.build_temp, 'multiarch').replace('\\','/')
|
|
if not os.path.exists(self.build_temp):
|
|
os.makedirs(self.build_temp)
|
|
ret = run_command(
|
|
@@ -774,7 +789,7 @@ def add_search_path(line):
|
|
pass
|
|
|
|
def add_cross_compiling_paths(self):
|
|
- tmpfile = os.path.join(self.build_temp, 'ccpaths')
|
|
+ tmpfile = os.path.join(self.build_temp, 'ccpaths').replace('\\','/')
|
|
if not os.path.exists(self.build_temp):
|
|
os.makedirs(self.build_temp)
|
|
# bpo-38472: With a German locale, GCC returns "gcc-Version 9.1.0
|
|
@@ -796,14 +811,25 @@ def add_cross_compiling_paths(self):
|
|
elif line.startswith("End of search list"):
|
|
in_incdirs = False
|
|
elif (is_gcc or is_clang) and line.startswith("LIBRARY_PATH"):
|
|
- for d in line.strip().split("=")[1].split(":"):
|
|
+ for d in line.strip().split("=")[1].split(os.pathsep):
|
|
d = os.path.normpath(d)
|
|
- if '/gcc/' not in d:
|
|
+ if '/gcc/' not in d and '/clang/' not in d:
|
|
add_dir_to_list(self.compiler.library_dirs,
|
|
d)
|
|
elif (is_gcc or is_clang) and in_incdirs and '/gcc/' not in line and '/clang/' not in line:
|
|
add_dir_to_list(self.compiler.include_dirs,
|
|
line.strip())
|
|
+ if is_clang:
|
|
+ ret = run_command('%s -print-search-dirs >%s' % (CC, tmpfile))
|
|
+ if ret == 0:
|
|
+ with open(tmpfile) as fp:
|
|
+ for line in fp.readlines():
|
|
+ if line.startswith("libraries:"):
|
|
+ for d in line.strip().split("=")[1].split(os.pathsep):
|
|
+ d = os.path.normpath(d)
|
|
+ if '/gcc/' not in d and '/clang/' not in d:
|
|
+ add_dir_to_list(self.compiler.library_dirs,
|
|
+ d)
|
|
finally:
|
|
os.unlink(tmpfile)
|
|
|
|
@@ -849,10 +875,10 @@ def configure_compiler(self):
|
|
if not CROSS_COMPILING:
|
|
add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
|
|
add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
|
|
+ self.add_multiarch_paths()
|
|
# only change this for cross builds for 3.3, issues on Mageia
|
|
if CROSS_COMPILING:
|
|
self.add_cross_compiling_paths()
|
|
- self.add_multiarch_paths()
|
|
self.add_ldflags_cppflags()
|
|
|
|
def init_inc_lib_dirs(self):
|
|
@@ -898,7 +924,7 @@ def init_inc_lib_dirs(self):
|
|
if HOST_PLATFORM == 'hp-ux11':
|
|
self.lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32']
|
|
|
|
- if MACOS:
|
|
+ if MACOS or MS_WINDOWS:
|
|
# This should work on any unixy platform ;-)
|
|
# If the user has bothered specifying additional -I and -L flags
|
|
# in OPT and LDFLAGS we might as well use them here.
|
|
@@ -970,11 +996,15 @@ def detect_simple_extensions(self):
|
|
# grp(3)
|
|
self.addext(Extension('grp', ['grpmodule.c']))
|
|
|
|
- self.addext(Extension('_socket', ['socketmodule.c']))
|
|
+ self.addext(Extension(
|
|
+ '_socket', ['socketmodule.c'],
|
|
+ libraries=(['ws2_32', 'iphlpapi'] if MS_WINDOWS else None)))
|
|
self.addext(Extension('spwd', ['spwdmodule.c']))
|
|
|
|
# select(2); not on ancient System V
|
|
- self.addext(Extension('select', ['selectmodule.c']))
|
|
+ self.addext(Extension(
|
|
+ 'select', ['selectmodule.c'],
|
|
+ libraries=(['ws2_32'] if MS_WINDOWS else None)))
|
|
|
|
# Memory-mapped files (also works on Win32).
|
|
self.addext(Extension('mmap', ['mmapmodule.c']))
|
|
@@ -1033,12 +1063,15 @@ def detect_test_extensions(self):
|
|
['_xxtestfuzz/_xxtestfuzz.c', '_xxtestfuzz/fuzzer.c']
|
|
))
|
|
|
|
+ if MS_WINDOWS:
|
|
+ self.add(Extension('_testconsole', ['../PC/_testconsole.c']))
|
|
+
|
|
def detect_readline_curses(self):
|
|
# readline
|
|
readline_termcap_library = ""
|
|
curses_library = ""
|
|
# Cannot use os.popen here in py3k.
|
|
- tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib')
|
|
+ tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib').replace('\\','/')
|
|
if not os.path.exists(self.build_temp):
|
|
os.makedirs(self.build_temp)
|
|
# Determine if readline is already linked against curses or tinfo.
|
|
@@ -1101,6 +1134,8 @@ def detect_readline_curses(self):
|
|
# readline package
|
|
if find_file('readline/rlconf.h', self.inc_dirs, []) is None:
|
|
do_readline = False
|
|
+ if MS_WINDOWS:
|
|
+ do_readline = False
|
|
if do_readline:
|
|
readline_libs = [readline_lib]
|
|
if readline_termcap_library:
|
|
@@ -1124,8 +1159,7 @@ def detect_readline_curses(self):
|
|
panel_library = 'panel'
|
|
if curses_library == 'ncursesw':
|
|
curses_defines.append(('HAVE_NCURSESW', '1'))
|
|
- if not CROSS_COMPILING:
|
|
- curses_includes.append('/usr/include/ncursesw')
|
|
+ curses_includes.append(sysconfig.get_config_var("NCURSESW_INCLUDEDIR"))
|
|
# Bug 1464056: If _curses.so links with ncursesw,
|
|
# _curses_panel.so must link with panelw.
|
|
panel_library = 'panelw'
|
|
@@ -1209,7 +1243,7 @@ def detect_dbm_gdbm(self):
|
|
if dbm_args:
|
|
dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":")
|
|
else:
|
|
- dbm_order = "gdbm:ndbm:bdb".split(":")
|
|
+ dbm_order = []
|
|
dbmext = None
|
|
for cand in dbm_order:
|
|
if cand == "ndbm":
|
|
@@ -1282,6 +1316,19 @@ def detect_platform_specific_exts(self):
|
|
# macOS-only, needs SystemConfiguration and CoreFoundation framework
|
|
self.addext(Extension('_scproxy', ['_scproxy.c']))
|
|
|
|
+ # Windows-only modules
|
|
+ if MS_WINDOWS:
|
|
+ srcdir = sysconfig.get_config_var('srcdir')
|
|
+ pc_srcdir = os.path.abspath(os.path.join(srcdir, 'PC'))
|
|
+
|
|
+ self.addext(Extension('_msi',
|
|
+ [os.path.join(pc_srcdir, '_msi.c')]))
|
|
+
|
|
+ self.addext(Extension('winsound',
|
|
+ [os.path.join(pc_srcdir, 'winsound.c')]))
|
|
+
|
|
+ self.addext(Extension('_overlapped', ['overlapped.c']))
|
|
+
|
|
def detect_compress_exts(self):
|
|
# Andrew Kuchling's zlib module.
|
|
self.addext(Extension('zlib', ['zlibmodule.c']))
|
|
@@ -1329,9 +1376,10 @@ def detect_multiprocessing(self):
|
|
if (
|
|
sysconfig.get_config_var('HAVE_SEM_OPEN') and not
|
|
sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')
|
|
- ):
|
|
+ ) or MS_WINDOWS:
|
|
multiprocessing_srcs.append('_multiprocessing/semaphore.c')
|
|
- self.addext(Extension('_multiprocessing', multiprocessing_srcs))
|
|
+ self.addext(Extension('_multiprocessing', multiprocessing_srcs,
|
|
+ libraries=(['ws2_32'] if MS_WINDOWS else None), include_dirs=["Modules/_multiprocessing"]))
|
|
self.addext(Extension('_posixshmem', ['_multiprocessing/posixshmem.c']))
|
|
|
|
def detect_uuid(self):
|
|
@@ -1414,11 +1462,16 @@ def detect_ctypes(self):
|
|
include_dirs=include_dirs,
|
|
extra_compile_args=extra_compile_args,
|
|
extra_link_args=extra_link_args,
|
|
- libraries=[],
|
|
+ libraries=(['ole32', 'oleaut32', 'uuid'] if MS_WINDOWS else []),
|
|
+ export_symbols=(
|
|
+ ['DllGetClassObject PRIVATE', 'DllCanUnloadNow PRIVATE']
|
|
+ if MS_WINDOWS else None
|
|
+ ),
|
|
sources=sources)
|
|
self.add(ext)
|
|
# function my_sqrt() needs libm for sqrt()
|
|
- self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c']))
|
|
+ self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'],
|
|
+ libraries=(['oleaut32'] if MS_WINDOWS else [])))
|
|
|
|
ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
|
|
ffi_lib = None
|
|
@@ -1568,7 +1621,7 @@ def copy_scripts(self):
|
|
else:
|
|
newfilename = filename + minoronly
|
|
log.info(f'renaming {filename} to {newfilename}')
|
|
- os.rename(filename, newfilename)
|
|
+ os.replace(filename, newfilename)
|
|
newoutfiles.append(newfilename)
|
|
if filename in updated_files:
|
|
newupdated_files.append(newfilename)
|