Skip to content

Commit 92d4e5d

Browse files
Merge branch 'main' into wip-compile-module
2 parents cb551e7 + e733dc9 commit 92d4e5d

22 files changed

+274
-75
lines changed

.github/workflows/reusable-wasi.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ env:
1313
jobs:
1414
build-wasi-reusable:
1515
name: 'build and test'
16-
runs-on: ubuntu-24.04
16+
runs-on: ubuntu-24.04-arm
1717
timeout-minutes: 60
1818
env:
19-
WASMTIME_VERSION: 38.0.2
19+
WASMTIME_VERSION: 38.0.3
2020
WASI_SDK_VERSION: 25
2121
WASI_SDK_PATH: /opt/wasi-sdk
2222
CROSS_BUILD_PYTHON: cross-build/build
@@ -40,7 +40,7 @@ jobs:
4040
if: steps.cache-wasi-sdk.outputs.cache-hit != 'true'
4141
run: |
4242
mkdir "${WASI_SDK_PATH}" && \
43-
curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux.tar.gz" | \
43+
curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-arm64-linux.tar.gz" | \
4444
tar --strip-components 1 --directory "${WASI_SDK_PATH}" --extract --gunzip
4545
- name: "Configure ccache action"
4646
uses: hendrikmuhs/ccache-action@v1.2

Doc/library/code.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ build applications which provide an interactive interpreter prompt.
2929
module.
3030

3131

32-
.. class:: InteractiveConsole(locals=None, filename="<console>", local_exit=False)
32+
.. class:: InteractiveConsole(locals=None, filename="<console>", *, local_exit=False)
3333

3434
Closely emulate the behavior of the interactive Python interpreter. This class
3535
builds on :class:`InteractiveInterpreter` and adds prompting using the familiar

Include/internal/pycore_ceval.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ PyAPI_FUNC(PyObject *) _PyEval_ImportName(PyThreadState *, _PyInterpreterFrame *
301301
PyAPI_FUNC(PyObject *)_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs);
302302
PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys);
303303
PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr);
304+
PyAPI_FUNC(bool) _PyEval_NoToolsForUnwind(PyThreadState *tstate);
304305
PyAPI_FUNC(int) _PyEval_UnpackIterableStackRef(PyThreadState *tstate, PyObject *v, int argcnt, int argcntafter, _PyStackRef *sp);
305306
PyAPI_FUNC(void) _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame);
306307
PyAPI_FUNC(PyObject **) _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_ssize_t nargs, PyObject **scratch);

Lib/_pyrepl/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ class ColorSpan(NamedTuple):
6363
def str_width(c: str) -> int:
6464
if ord(c) < 128:
6565
return 1
66+
# gh-139246 for zero-width joiner and combining characters
67+
if unicodedata.combining(c):
68+
return 0
69+
category = unicodedata.category(c)
70+
if category == "Cf" and c != "\u00ad":
71+
return 0
6672
w = unicodedata.east_asian_width(c)
6773
if w in ("N", "Na", "H", "A"):
6874
return 1

Lib/encodings/__init__.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import codecs
3232
import sys
33+
from _codecs import _normalize_encoding
3334
from . import aliases
3435

3536
_cache = {}
@@ -55,18 +56,7 @@ def normalize_encoding(encoding):
5556
if isinstance(encoding, bytes):
5657
encoding = str(encoding, "ascii")
5758

58-
chars = []
59-
punct = False
60-
for c in encoding:
61-
if c.isalnum() or c == '.':
62-
if punct and chars:
63-
chars.append('_')
64-
if c.isascii():
65-
chars.append(c)
66-
punct = False
67-
else:
68-
punct = True
69-
return ''.join(chars)
59+
return _normalize_encoding(encoding)
7060

7161
def search_function(encoding):
7262

Lib/enum.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP',
1111
'global_flag_repr', 'global_enum_repr', 'global_str', 'global_enum',
1212
'EnumCheck', 'CONTINUOUS', 'NAMED_FLAGS', 'UNIQUE',
13-
'pickle_by_global_name', 'pickle_by_enum_name',
13+
'pickle_by_global_name', 'pickle_by_enum_name', 'show_flag_values',
14+
'bin',
1415
]
1516

1617

Lib/test/test_enum.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5324,7 +5324,7 @@ def __new__(cls, value, label):
53245324
class MiscTestCase(unittest.TestCase):
53255325

53265326
def test__all__(self):
5327-
support.check__all__(self, enum, not_exported={'bin', 'show_flag_values'})
5327+
support.check__all__(self, enum)
53285328

53295329
@cpython_only
53305330
def test_lazy_import(self):

Lib/test/test_monitoring.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,25 @@ def f():
10791079

10801080
self.assertEqual(events, expected)
10811081

1082+
# gh-140373
1083+
def test_gen_unwind(self):
1084+
def gen():
1085+
yield 1
1086+
1087+
def f():
1088+
g = gen()
1089+
next(g)
1090+
g.close()
1091+
1092+
recorders = (
1093+
UnwindRecorder,
1094+
)
1095+
events = self.get_events(f, TEST_TOOL, recorders)
1096+
expected = [
1097+
("unwind", GeneratorExit, "gen"),
1098+
]
1099+
self.assertEqual(events, expected)
1100+
10821101
class LineRecorder:
10831102

10841103
event_type = E.LINE

Lib/test/test_pyrepl/test_utils.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,29 @@
55

66
class TestUtils(TestCase):
77
def test_str_width(self):
8-
characters = ['a', '1', '_', '!', '\x1a', '\u263A', '\uffb9']
8+
characters = [
9+
'a',
10+
'1',
11+
'_',
12+
'!',
13+
'\x1a',
14+
'\u263A',
15+
'\uffb9',
16+
'\N{LATIN SMALL LETTER E WITH ACUTE}', # é
17+
'\N{LATIN SMALL LETTER E WITH CEDILLA}', # ȩ
18+
'\u00ad',
19+
]
920
for c in characters:
1021
self.assertEqual(str_width(c), 1)
1122

23+
zero_width_characters = [
24+
'\N{COMBINING ACUTE ACCENT}',
25+
'\N{ZERO WIDTH JOINER}',
26+
]
27+
for c in zero_width_characters:
28+
with self.subTest(character=c):
29+
self.assertEqual(str_width(c), 0)
30+
1231
characters = [chr(99989), chr(99999)]
1332
for c in characters:
1433
self.assertEqual(str_width(c), 2)
@@ -25,6 +44,8 @@ def test_wlen(self):
2544

2645
self.assertEqual(wlen('hello'), 5)
2746
self.assertEqual(wlen('hello' + '\x1a'), 7)
47+
self.assertEqual(wlen('e\N{COMBINING ACUTE ACCENT}'), 1)
48+
self.assertEqual(wlen('a\N{ZERO WIDTH JOINER}b'), 2)
2849

2950
def test_prev_next_window(self):
3051
def gen_normal():

Lib/test/test_sys_setprofile.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ def g(p):
272272
self.check_events(g, [(1, 'call', g_ident, None),
273273
(2, 'call', f_ident, None),
274274
(2, 'return', f_ident, 0),
275+
(2, 'call', f_ident, None),
276+
(2, 'return', f_ident, None),
275277
(1, 'return', g_ident, None),
276278
], check_args=True)
277279

0 commit comments

Comments
 (0)