Skip to content

Commit 136e870

Browse files
Merge branch '3.10' into backport-e5caf45-3.10
2 parents d013b14 + e70ff77 commit 136e870

12 files changed

Lines changed: 133 additions & 83 deletions

File tree

.github/workflows/build.yml

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ on:
1111
- 'main'
1212
- '3.*'
1313

14-
permissions:
15-
contents: read
14+
permissions: {}
1615

1716
concurrency:
1817
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
@@ -30,7 +29,7 @@ jobs:
3029
run_tests: ${{ steps.check.outputs.run_tests }}
3130
run_ssl_tests: ${{ steps.check.outputs.run_ssl_tests }}
3231
steps:
33-
- uses: actions/checkout@v6
32+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3433
- name: Check for source changes
3534
id: check
3635
run: |
@@ -62,10 +61,10 @@ jobs:
6261
needs: check_source
6362
if: needs.check_source.outputs.run_tests == 'true'
6463
steps:
65-
- uses: actions/checkout@v6
64+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
6665
with:
6766
persist-credentials: false
68-
- uses: actions/setup-python@v6
67+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
6968
- name: Install dependencies
7069
run: |
7170
sudo ./.github/workflows/posix-deps-apt.sh
@@ -97,16 +96,16 @@ jobs:
9796
needs: check_source
9897
if: needs.check_source.outputs.run_tests == 'true'
9998
steps:
100-
- uses: actions/checkout@v6
99+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
101100
with:
102101
persist-credentials: false
103-
- uses: actions/setup-python@v6
102+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
104103
- name: Install dependencies
105104
run: sudo ./.github/workflows/posix-deps-apt.sh
106105
- name: Add ccache to PATH
107106
run: echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
108107
- name: Configure ccache action
109-
uses: hendrikmuhs/ccache-action@v1
108+
uses: hendrikmuhs/ccache-action@5ebbd400eff9e74630f759d94ddd7b6c26299639 # v1.2.20
110109
- name: Check Autoconf version 2.69 and aclocal 1.16.3
111110
run: |
112111
grep "Generated by GNU Autoconf 2.69" configure
@@ -149,7 +148,7 @@ jobs:
149148
env:
150149
IncludeUwp: 'true'
151150
steps:
152-
- uses: actions/checkout@v6
151+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
153152
- name: Build CPython
154153
run: .\PCbuild\build.bat -e -p Win32
155154
- name: Display build info
@@ -165,7 +164,7 @@ jobs:
165164
env:
166165
IncludeUwp: 'true'
167166
steps:
168-
- uses: actions/checkout@v6
167+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
169168
- name: Register MSVC problem matcher
170169
run: echo "::add-matcher::.github/problem-matchers/msvc.json"
171170
- name: Build CPython
@@ -186,7 +185,7 @@ jobs:
186185
HOMEBREW_NO_INSTALL_CLEANUP: 1
187186
PYTHONSTRICTEXTENSIONBUILD: 1
188187
steps:
189-
- uses: actions/checkout@v6
188+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
190189
- name: Install Homebrew dependencies
191190
run: |
192191
brew install pkg-config openssl@3.0 xz gdbm tcl-tk@8
@@ -218,7 +217,7 @@ jobs:
218217
OPENSSL_VER: 3.0.11
219218
PYTHONSTRICTEXTENSIONBUILD: 1
220219
steps:
221-
- uses: actions/checkout@v6
220+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
222221
- name: Register gcc problem matcher
223222
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
224223
- name: Install dependencies
@@ -230,7 +229,7 @@ jobs:
230229
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> "$GITHUB_ENV"
231230
- name: 'Restore OpenSSL build'
232231
id: cache-openssl
233-
uses: actions/cache@v5
232+
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
234233
with:
235234
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
236235
key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
@@ -241,7 +240,7 @@ jobs:
241240
run: |
242241
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
243242
- name: Configure ccache action
244-
uses: hendrikmuhs/ccache-action@v1
243+
uses: hendrikmuhs/ccache-action@5ebbd400eff9e74630f759d94ddd7b6c26299639 # v1.2.20
245244
- name: Configure CPython
246245
run: ./configure --with-pydebug --with-openssl=$OPENSSL_DIR
247246
- name: Build CPython
@@ -267,7 +266,7 @@ jobs:
267266
OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}
268267
LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib
269268
steps:
270-
- uses: actions/checkout@v6
269+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
271270
with:
272271
persist-credentials: false
273272
- name: Register gcc problem matcher
@@ -281,7 +280,7 @@ jobs:
281280
echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> "$GITHUB_ENV"
282281
- name: 'Restore OpenSSL build'
283282
id: cache-openssl
284-
uses: actions/cache@v5
283+
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
285284
with:
286285
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
287286
key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }}
@@ -292,7 +291,7 @@ jobs:
292291
run: |
293292
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
294293
- name: Configure ccache action
295-
uses: hendrikmuhs/ccache-action@v1.2
294+
uses: hendrikmuhs/ccache-action@5ebbd400eff9e74630f759d94ddd7b6c26299639 # v1.2.20
296295
- name: Configure CPython
297296
run: ./configure --with-pydebug --with-openssl=$OPENSSL_DIR
298297
- name: Build CPython

.github/workflows/build_msi.yml

Lines changed: 0 additions & 47 deletions
This file was deleted.

.github/workflows/doc.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ jobs:
3232
name: 'Docs'
3333
runs-on: ubuntu-latest
3434
steps:
35-
- uses: actions/checkout@v6
35+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3636
- name: Register Sphinx problem matcher
3737
run: echo "::add-matcher::.github/problem-matchers/sphinx.json"
3838
- name: 'Set up Python'
39-
uses: actions/setup-python@v6
39+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
4040
with:
4141
python-version: '3.12'
4242
cache: 'pip'
@@ -46,7 +46,7 @@ jobs:
4646
- name: 'Build HTML documentation'
4747
run: make -C Doc/ SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" html
4848
- name: 'Upload'
49-
uses: actions/upload-artifact@v6
49+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
5050
with:
5151
name: doc-html
5252
path: Doc/build/html
@@ -58,10 +58,10 @@ jobs:
5858
name: 'Doctest'
5959
runs-on: ubuntu-latest
6060
steps:
61-
- uses: actions/checkout@v6
61+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
6262
- name: Register Sphinx problem matcher
6363
run: echo "::add-matcher::.github/problem-matchers/sphinx.json"
64-
- uses: actions/cache@v5
64+
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
6565
with:
6666
path: ~/.cache/pip
6767
key: ubuntu-doc-${{ hashFiles('Doc/requirements.txt') }}

.github/workflows/stale.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@ on:
44
schedule:
55
- cron: "0 0 * * *"
66

7-
permissions:
8-
pull-requests: write
7+
permissions: {}
98

109
jobs:
1110
stale:
12-
11+
if: github.repository_owner == 'python'
1312
runs-on: ubuntu-latest
13+
permissions:
14+
pull-requests: write
15+
timeout-minutes: 10
1416

1517
steps:
1618
- name: "Check PRs"
17-
uses: actions/stale@v9
19+
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
1820
with:
1921
repo-token: ${{ secrets.GITHUB_TOKEN }}
2022
stale-pr-message: 'This PR is stale because it has been open for 30 days with no activity.'

.github/workflows/verify-ensurepip-wheels.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ on:
1313
- '.github/workflows/verify-ensurepip-wheels.yml'
1414
- 'Tools/scripts/verify_ensurepip_wheels.py'
1515

16-
permissions:
17-
contents: read
16+
permissions: {}
1817

1918
concurrency:
2019
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
@@ -24,8 +23,8 @@ jobs:
2423
verify:
2524
runs-on: ubuntu-latest
2625
steps:
27-
- uses: actions/checkout@v6
28-
- uses: actions/setup-python@v6
26+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
27+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
2928
with:
3029
python-version: '3'
3130
- name: Compare checksums of bundled pip and setuptools to ones published on PyPI

.github/workflows/verify-expat.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ on:
1111
- 'Modules/expat/**'
1212
- '.github/workflows/verify-expat.yml'
1313

14-
permissions:
15-
contents: read
14+
permissions: {}
1615

1716
concurrency:
1817
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
@@ -23,7 +22,7 @@ jobs:
2322
runs-on: ubuntu-latest
2423
timeout-minutes: 5
2524
steps:
26-
- uses: actions/checkout@v6
25+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2726
with:
2827
persist-credentials: false
2928
- name: Download and verify bundled libexpat files

Doc/library/subprocess.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,12 @@ functions.
618618
the value in ``pw_uid`` will be used. If the value is an integer, it will
619619
be passed verbatim. (POSIX only)
620620

621+
.. note::
622+
623+
Specifying *user* will not drop existing supplementary group memberships!
624+
The caller must also pass ``extra_groups=()`` to reduce the group membership
625+
of the child process for security purposes.
626+
621627
.. availability:: POSIX
622628
.. versionadded:: 3.9
623629

Lib/test/test_webbrowser.py

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import io
2+
import os
13
import webbrowser
24
import unittest
3-
import os
45
import sys
56
import subprocess
67
from unittest import mock
@@ -47,6 +48,14 @@ def _test(self, meth, *, args=[URL], kw={}, options, arguments):
4748
popen_args.pop(popen_args.index(option))
4849
self.assertEqual(popen_args, arguments)
4950

51+
def test_reject_dash_prefixes(self):
52+
browser = self.browser_class(name=CMD_NAME)
53+
with self.assertRaisesRegex(
54+
ValueError,
55+
r"^Invalid URL \(leading dash disallowed\): '--key=val http.*'$"
56+
):
57+
browser.open(f"--key=val {URL}")
58+
5059

5160
class GenericBrowserCommandTest(CommandTestMixin, unittest.TestCase):
5261

@@ -217,6 +226,73 @@ def test_open_new_tab(self):
217226
arguments=['openURL({},new-tab)'.format(URL)])
218227

219228

229+
class MockPopenPipe:
230+
def __init__(self, cmd, mode):
231+
self.cmd = cmd
232+
self.mode = mode
233+
self.pipe = io.StringIO()
234+
self._closed = False
235+
236+
def write(self, buf):
237+
self.pipe.write(buf)
238+
239+
def close(self):
240+
self._closed = True
241+
return None
242+
243+
244+
@unittest.skipUnless(sys.platform == "darwin", "macOS specific test")
245+
class MacOSXOSAScriptTest(unittest.TestCase):
246+
def setUp(self):
247+
# Ensure that 'BROWSER' is not set to 'open' or something else.
248+
# See: https://github.com/python/cpython/issues/131254.
249+
ctx = os_helper.EnvironmentVarGuard()
250+
env = ctx.__enter__()
251+
self.addCleanup(ctx.__exit__)
252+
env.unset("BROWSER")
253+
254+
support.patch(self, os, "popen", self.mock_popen)
255+
self.browser = webbrowser.MacOSXOSAScript("default")
256+
257+
def mock_popen(self, cmd, mode):
258+
self.popen_pipe = MockPopenPipe(cmd, mode)
259+
return self.popen_pipe
260+
261+
def test_default(self):
262+
browser = webbrowser.get()
263+
assert isinstance(browser, webbrowser.MacOSXOSAScript)
264+
self.assertEqual(browser._name, "default")
265+
266+
def test_default_open(self):
267+
url = "https://python.org"
268+
self.browser.open(url)
269+
self.assertTrue(self.popen_pipe._closed)
270+
self.assertEqual(self.popen_pipe.cmd, "/usr/bin/osascript")
271+
script = self.popen_pipe.pipe.getvalue()
272+
self.assertEqual(script.strip(), f'open location "{url}"')
273+
274+
def test_url_quote(self):
275+
self.browser.open('https://python.org/"quote"')
276+
script = self.popen_pipe.pipe.getvalue()
277+
self.assertEqual(
278+
script.strip(), 'open location "https://python.org/%22quote%22"'
279+
)
280+
281+
def test_explicit_browser(self):
282+
browser = webbrowser.MacOSXOSAScript("safari")
283+
browser.open("https://python.org")
284+
script = self.popen_pipe.pipe.getvalue()
285+
self.assertIn('tell application "safari"', script)
286+
self.assertIn('open location "https://python.org"', script)
287+
288+
def test_reject_dash_prefixes(self):
289+
with self.assertRaisesRegex(
290+
ValueError,
291+
r"^Invalid URL \(leading dash disallowed\): '--key=val http.*'$"
292+
):
293+
self.browser.open(f"--key=val {URL}")
294+
295+
220296
class BrowserRegistrationTest(unittest.TestCase):
221297

222298
def setUp(self):

0 commit comments

Comments
 (0)