Skip to content

Commit 0820a3c

Browse files
committed
Merge remote-tracking branch 'upstream/main' into jit-isinstance
2 parents 3e86810 + c492ac7 commit 0820a3c

28 files changed

+968
-381
lines changed

Doc/deprecations/pending-removal-in-3.14.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Pending removal in Python 3.14
7878
:meth:`~pathlib.PurePath.relative_to`: passing additional arguments is
7979
deprecated.
8080

81-
* :mod:`pkgutil`: :func:`!pkgutil.find_loader` and :func:!pkgutil.get_loader`
81+
* :mod:`pkgutil`: :func:`!pkgutil.find_loader` and :func:`!pkgutil.get_loader`
8282
now raise :exc:`DeprecationWarning`;
8383
use :func:`importlib.util.find_spec` instead.
8484
(Contributed by Nikita Sobolev in :gh:`97850`.)

Doc/using/windows.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ as ``python3.14.exe``) to be available. The directory will be
9595
administrator. Click Start and search for "Edit environment variables for your
9696
account" for the system settings page to add the path.
9797

98+
Each Python runtime you install will have its own directory for scripts. These
99+
also need to be added to :envvar:`PATH` if you want to use them.
100+
98101
The Python install manager will be automatically updated to new releases. This
99102
does not affect any installs of Python runtimes. Uninstalling the Python install
100103
manager does not uninstall any Python runtimes.
@@ -713,6 +716,16 @@ default).
713716
your ``pythonw.exe`` and ``pyw.exe`` aliases are consistent with your
714717
others.
715718
"
719+
"``pip`` gives me a ""command not found"" error when I type it in my
720+
terminal.","Have you activated a virtual environment? Run the
721+
``.venv\Scripts\activate`` script in your terminal to activate.
722+
"
723+
"","The package may be available but missing the generated executable.
724+
We recommend using the ``python -m pip`` command instead, or alternatively
725+
the ``python -m pip install --force pip`` command will recreate the
726+
executables and show you the path to add to :envvar:`PATH`. These scripts are
727+
separated for each runtime, and so you may need to add multiple paths.
728+
"
716729

717730

718731
.. _windows-embeddable:

Include/internal/pycore_opcode_metadata.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/_pyrepl/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ def gen_colors(buffer: str) -> Iterator[ColorSpan]:
102102
for color in gen_colors_from_token_stream(gen, line_lengths):
103103
yield color
104104
last_emitted = color
105+
except SyntaxError:
106+
return
105107
except tokenize.TokenError as te:
106108
yield from recover_unterminated_string(
107109
te, line_lengths, last_emitted, buffer

Lib/test/test_capi/test_opt.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,23 @@ def testfunc(n):
19421942
self.assertNotIn("_COMPARE_OP_INT", uops)
19431943
self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
19441944

1945+
def test_call_isinstance_guards_removed(self):
1946+
def testfunc(n):
1947+
x = 0
1948+
for _ in range(n):
1949+
y = isinstance(42, int)
1950+
if y:
1951+
x += 1
1952+
return x
1953+
1954+
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
1955+
self.assertEqual(res, TIER2_THRESHOLD)
1956+
self.assertIsNotNone(ex)
1957+
uops = get_opnames(ex)
1958+
self.assertIn("_CALL_ISINSTANCE", uops)
1959+
self.assertNotIn("_GUARD_THIRD_NULL", uops)
1960+
self.assertNotIn("_GUARD_CALLABLE_ISINSTANCE", uops)
1961+
19451962
def test_call_isinstance_is_true(self):
19461963
def testfunc(n):
19471964
x = 0
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import threading
2+
from unittest import TestCase
3+
from test.support import threading_helper
4+
from random import randint
5+
from io import BytesIO
6+
from sys import getsizeof
7+
8+
9+
class TestBytesIO(TestCase):
10+
# Test pretty much everything that can break under free-threading.
11+
# Non-deterministic, but at least one of these things will fail if
12+
# BytesIO object is not free-thread safe.
13+
14+
def check(self, funcs, *args):
15+
barrier = threading.Barrier(len(funcs))
16+
threads = []
17+
18+
for func in funcs:
19+
thread = threading.Thread(target=func, args=(barrier, *args))
20+
21+
threads.append(thread)
22+
23+
with threading_helper.start_threads(threads):
24+
pass
25+
26+
@threading_helper.requires_working_threading()
27+
@threading_helper.reap_threads
28+
def test_free_threading(self):
29+
"""Test for segfaults and aborts."""
30+
31+
def write(barrier, b, *ignore):
32+
barrier.wait()
33+
try: b.write(b'0' * randint(100, 1000))
34+
except ValueError: pass # ignore write fail to closed file
35+
36+
def writelines(barrier, b, *ignore):
37+
barrier.wait()
38+
b.write(b'0\n' * randint(100, 1000))
39+
40+
def truncate(barrier, b, *ignore):
41+
barrier.wait()
42+
try: b.truncate(0)
43+
except: BufferError # ignore exported buffer
44+
45+
def read(barrier, b, *ignore):
46+
barrier.wait()
47+
b.read()
48+
49+
def read1(barrier, b, *ignore):
50+
barrier.wait()
51+
b.read1()
52+
53+
def readline(barrier, b, *ignore):
54+
barrier.wait()
55+
b.readline()
56+
57+
def readlines(barrier, b, *ignore):
58+
barrier.wait()
59+
b.readlines()
60+
61+
def readinto(barrier, b, into, *ignore):
62+
barrier.wait()
63+
b.readinto(into)
64+
65+
def close(barrier, b, *ignore):
66+
barrier.wait()
67+
b.close()
68+
69+
def getvalue(barrier, b, *ignore):
70+
barrier.wait()
71+
b.getvalue()
72+
73+
def getbuffer(barrier, b, *ignore):
74+
barrier.wait()
75+
b.getbuffer()
76+
77+
def iter(barrier, b, *ignore):
78+
barrier.wait()
79+
list(b)
80+
81+
def getstate(barrier, b, *ignore):
82+
barrier.wait()
83+
b.__getstate__()
84+
85+
def setstate(barrier, b, st, *ignore):
86+
barrier.wait()
87+
b.__setstate__(st)
88+
89+
def sizeof(barrier, b, *ignore):
90+
barrier.wait()
91+
getsizeof(b)
92+
93+
self.check([write] * 10, BytesIO())
94+
self.check([writelines] * 10, BytesIO())
95+
self.check([write] * 10 + [truncate] * 10, BytesIO())
96+
self.check([truncate] + [read] * 10, BytesIO(b'0\n'*204800))
97+
self.check([truncate] + [read1] * 10, BytesIO(b'0\n'*204800))
98+
self.check([truncate] + [readline] * 10, BytesIO(b'0\n'*20480))
99+
self.check([truncate] + [readlines] * 10, BytesIO(b'0\n'*20480))
100+
self.check([truncate] + [readinto] * 10, BytesIO(b'0\n'*204800), bytearray(b'0\n'*204800))
101+
self.check([close] + [write] * 10, BytesIO())
102+
self.check([truncate] + [getvalue] * 10, BytesIO(b'0\n'*204800))
103+
self.check([truncate] + [getbuffer] * 10, BytesIO(b'0\n'*204800))
104+
self.check([truncate] + [iter] * 10, BytesIO(b'0\n'*20480))
105+
self.check([truncate] + [getstate] * 10, BytesIO(b'0\n'*204800))
106+
self.check([truncate] + [setstate] * 10, BytesIO(b'0\n'*204800), (b'123', 0, None))
107+
self.check([truncate] + [sizeof] * 10, BytesIO(b'0\n'*204800))
108+
109+
# no tests for seek or tell because they don't break anything

0 commit comments

Comments
 (0)