Skip to content

Commit 8699b81

Browse files
authored
Merge branch 'main' into zipapp_issue
2 parents 43210be + 3a555f0 commit 8699b81

File tree

10 files changed

+79
-45
lines changed

10 files changed

+79
-45
lines changed

Lib/asyncio/tasks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def __init__(self, coro, *, loop=None, name=None, context=None,
110110
self.__eager_start()
111111
else:
112112
self._loop.call_soon(self.__step, context=self._context)
113-
_register_task(self)
113+
_py_register_task(self)
114114

115115
def __del__(self):
116116
if self._state == futures._PENDING and self._log_destroy_pending:

Lib/glob.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,9 @@ class _PathGlobber(_GlobberBase):
533533
"""Provides shell-style pattern matching and globbing for pathlib paths.
534534
"""
535535

536-
lexists = operator.methodcaller('exists', follow_symlinks=False)
536+
@staticmethod
537+
def lexists(path):
538+
return path.info.exists(follow_symlinks=False)
537539

538540
@staticmethod
539541
def scandir(path):

Lib/pathlib/_abc.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,11 @@ def walk(self, top_down=True, on_error=None, follow_symlinks=False):
316316
paths.append((path, dirnames, filenames))
317317
try:
318318
for child in path.iterdir():
319-
try:
320-
if child.info.is_dir(follow_symlinks=follow_symlinks):
321-
if not top_down:
322-
paths.append(child)
323-
dirnames.append(child.name)
324-
else:
325-
filenames.append(child.name)
326-
except OSError:
319+
if child.info.is_dir(follow_symlinks=follow_symlinks):
320+
if not top_down:
321+
paths.append(child)
322+
dirnames.append(child.name)
323+
else:
327324
filenames.append(child.name)
328325
except OSError as error:
329326
if on_error is not None:
@@ -356,7 +353,8 @@ def copy(self, target, follow_symlinks=True, dirs_exist_ok=False,
356353
create = target._copy_writer._create
357354
except AttributeError:
358355
raise TypeError(f"Target is not writable: {target}") from None
359-
return create(self, follow_symlinks, dirs_exist_ok, preserve_metadata)
356+
create(self, follow_symlinks, dirs_exist_ok, preserve_metadata)
357+
return target.joinpath() # Empty join to ensure fresh metadata.
360358

361359
def copy_into(self, target_dir, *, follow_symlinks=True,
362360
dirs_exist_ok=False, preserve_metadata=False):

Lib/pathlib/_local.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,8 @@ def copy(self, target, follow_symlinks=True, dirs_exist_ok=False,
10981098
create = target._copy_writer._create
10991099
except AttributeError:
11001100
raise TypeError(f"Target is not writable: {target}") from None
1101-
return create(self, follow_symlinks, dirs_exist_ok, preserve_metadata)
1101+
create(self, follow_symlinks, dirs_exist_ok, preserve_metadata)
1102+
return target.joinpath() # Empty join to ensure fresh metadata.
11021103

11031104
def copy_into(self, target_dir, *, follow_symlinks=True,
11041105
dirs_exist_ok=False, preserve_metadata=False):
@@ -1128,10 +1129,12 @@ def move(self, target):
11281129
else:
11291130
ensure_different_files(self, target)
11301131
try:
1131-
return self.replace(target)
1132+
os.replace(self, target)
11321133
except OSError as err:
11331134
if err.errno != EXDEV:
11341135
raise
1136+
else:
1137+
return target.joinpath() # Empty join to ensure fresh metadata.
11351138
# Fall back to copy+delete.
11361139
target = self.copy(target, follow_symlinks=False, preserve_metadata=True)
11371140
self._delete()

Lib/test/test_asyncio/test_eager_task_factory.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,15 @@ class PyEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase
268268
Task = tasks._PyTask
269269

270270
def setUp(self):
271+
self._all_tasks = asyncio.all_tasks
271272
self._current_task = asyncio.current_task
272273
asyncio.current_task = asyncio.tasks.current_task = asyncio.tasks._py_current_task
274+
asyncio.all_tasks = asyncio.tasks.all_tasks = asyncio.tasks._py_all_tasks
273275
return super().setUp()
274276

275277
def tearDown(self):
276278
asyncio.current_task = asyncio.tasks.current_task = self._current_task
279+
asyncio.all_tasks = asyncio.tasks.all_tasks = self._all_tasks
277280
return super().tearDown()
278281

279282

@@ -285,11 +288,14 @@ class CEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase)
285288

286289
def setUp(self):
287290
self._current_task = asyncio.current_task
291+
self._all_tasks = asyncio.all_tasks
288292
asyncio.current_task = asyncio.tasks.current_task = asyncio.tasks._c_current_task
293+
asyncio.all_tasks = asyncio.tasks.all_tasks = asyncio.tasks._c_all_tasks
289294
return super().setUp()
290295

291296
def tearDown(self):
292297
asyncio.current_task = asyncio.tasks.current_task = self._current_task
298+
asyncio.all_tasks = asyncio.tasks.all_tasks = self._all_tasks
293299
return super().tearDown()
294300

295301

Lib/test/test_asyncio/test_free_threading.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ async def coro():
3333
for _ in range(100):
3434
tasks.add(tg.create_task(coro()))
3535

36-
all_tasks = self.all_tasks(loop)
36+
all_tasks = asyncio.all_tasks(loop)
3737
self.assertEqual(len(all_tasks), 101)
3838

3939
for task in all_tasks:
@@ -77,15 +77,15 @@ async def main():
7777
for i in range(1000):
7878
with lock:
7979
asyncio.create_task(coro())
80-
tasks = self.all_tasks(loop)
80+
tasks = asyncio.all_tasks(loop)
8181
done.wait()
8282

8383
runner = threading.Thread(target=lambda: asyncio.run(main()))
8484

8585
def check():
8686
started.wait()
8787
with lock:
88-
self.assertSetEqual(tasks & self.all_tasks(loop), tasks)
88+
self.assertSetEqual(tasks & asyncio.all_tasks(loop), tasks)
8989

9090
threads = [threading.Thread(target=check) for _ in range(10)]
9191
runner.start()
@@ -167,15 +167,23 @@ async def main():
167167

168168

169169
class TestPyFreeThreading(TestFreeThreading, TestCase):
170-
all_tasks = staticmethod(asyncio.tasks._py_all_tasks)
171170

172171
def setUp(self):
173172
self._old_current_task = asyncio.current_task
174173
asyncio.current_task = asyncio.tasks.current_task = asyncio.tasks._py_current_task
174+
self._old_all_tasks = asyncio.all_tasks
175+
asyncio.all_tasks = asyncio.tasks.all_tasks = asyncio.tasks._py_all_tasks
176+
self._old_Task = asyncio.Task
177+
asyncio.Task = asyncio.tasks.Task = asyncio.tasks._PyTask
178+
self._old_Future = asyncio.Future
179+
asyncio.Future = asyncio.futures.Future = asyncio.futures._PyFuture
175180
return super().setUp()
176181

177182
def tearDown(self):
178183
asyncio.current_task = asyncio.tasks.current_task = self._old_current_task
184+
asyncio.all_tasks = asyncio.tasks.all_tasks = self._old_all_tasks
185+
asyncio.Task = asyncio.tasks.Task = self._old_Task
186+
asyncio.Future = asyncio.tasks.Future = self._old_Future
179187
return super().tearDown()
180188

181189
def factory(self, loop, coro, **kwargs):
@@ -184,15 +192,23 @@ def factory(self, loop, coro, **kwargs):
184192

185193
@unittest.skipUnless(hasattr(asyncio.tasks, "_c_all_tasks"), "requires _asyncio")
186194
class TestCFreeThreading(TestFreeThreading, TestCase):
187-
all_tasks = staticmethod(getattr(asyncio.tasks, "_c_all_tasks", None))
188195

189196
def setUp(self):
190197
self._old_current_task = asyncio.current_task
191198
asyncio.current_task = asyncio.tasks.current_task = asyncio.tasks._c_current_task
199+
self._old_all_tasks = asyncio.all_tasks
200+
asyncio.all_tasks = asyncio.tasks.all_tasks = asyncio.tasks._c_all_tasks
201+
self._old_Task = asyncio.Task
202+
asyncio.Task = asyncio.tasks.Task = asyncio.tasks._CTask
203+
self._old_Future = asyncio.Future
204+
asyncio.Future = asyncio.futures.Future = asyncio.futures._CFuture
192205
return super().setUp()
193206

194207
def tearDown(self):
195208
asyncio.current_task = asyncio.tasks.current_task = self._old_current_task
209+
asyncio.all_tasks = asyncio.tasks.all_tasks = self._old_all_tasks
210+
asyncio.Task = asyncio.tasks.Task = self._old_Task
211+
asyncio.Future = asyncio.futures.Future = self._old_Future
196212
return super().tearDown()
197213

198214

Lib/test/test_pathlib/test_pathlib_abc.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,7 @@ def test_glob_posix(self):
11071107
p = P(self.base)
11081108
q = p / "FILEa"
11091109
given = set(p.glob("FILEa"))
1110-
expect = {q} if q.exists() else set()
1110+
expect = {q} if q.info.exists() else set()
11111111
self.assertEqual(given, expect)
11121112
self.assertEqual(set(p.glob("FILEa*")), set())
11131113

@@ -1391,17 +1391,17 @@ def test_copy_file(self):
13911391
target = base / 'copyA'
13921392
result = source.copy(target)
13931393
self.assertEqual(result, target)
1394-
self.assertTrue(target.exists())
1395-
self.assertEqual(source.read_text(), target.read_text())
1394+
self.assertTrue(result.info.exists())
1395+
self.assertEqual(source.read_text(), result.read_text())
13961396

13971397
def test_copy_file_to_existing_file(self):
13981398
base = self.cls(self.base)
13991399
source = base / 'fileA'
14001400
target = base / 'dirB' / 'fileB'
14011401
result = source.copy(target)
14021402
self.assertEqual(result, target)
1403-
self.assertTrue(target.exists())
1404-
self.assertEqual(source.read_text(), target.read_text())
1403+
self.assertTrue(result.info.exists())
1404+
self.assertEqual(source.read_text(), result.read_text())
14051405

14061406
def test_copy_file_to_existing_directory(self):
14071407
base = self.cls(self.base)
@@ -1416,8 +1416,8 @@ def test_copy_file_empty(self):
14161416
source.write_bytes(b'')
14171417
result = source.copy(target)
14181418
self.assertEqual(result, target)
1419-
self.assertTrue(target.exists())
1420-
self.assertEqual(target.read_bytes(), b'')
1419+
self.assertTrue(result.info.exists())
1420+
self.assertEqual(result.read_bytes(), b'')
14211421

14221422
def test_copy_file_to_itself(self):
14231423
base = self.cls(self.base)
@@ -1432,13 +1432,13 @@ def test_copy_dir_simple(self):
14321432
target = base / 'copyC'
14331433
result = source.copy(target)
14341434
self.assertEqual(result, target)
1435-
self.assertTrue(target.is_dir())
1436-
self.assertTrue(target.joinpath('dirD').is_dir())
1437-
self.assertTrue(target.joinpath('dirD', 'fileD').is_file())
1438-
self.assertEqual(target.joinpath('dirD', 'fileD').read_text(),
1435+
self.assertTrue(result.info.is_dir())
1436+
self.assertTrue(result.joinpath('dirD').info.is_dir())
1437+
self.assertTrue(result.joinpath('dirD', 'fileD').info.is_file())
1438+
self.assertEqual(result.joinpath('dirD', 'fileD').read_text(),
14391439
"this is file D\n")
1440-
self.assertTrue(target.joinpath('fileC').is_file())
1441-
self.assertTrue(target.joinpath('fileC').read_text(),
1440+
self.assertTrue(result.joinpath('fileC').info.is_file())
1441+
self.assertTrue(result.joinpath('fileC').read_text(),
14421442
"this is file C\n")
14431443

14441444
def test_copy_dir_complex(self, follow_symlinks=True):
@@ -1462,7 +1462,7 @@ def ordered_walk(path):
14621462

14631463
# Compare the source and target trees
14641464
source_walk = ordered_walk(source)
1465-
target_walk = ordered_walk(target)
1465+
target_walk = ordered_walk(result)
14661466
for source_item, target_item in zip(source_walk, target_walk, strict=True):
14671467
self.assertEqual(source_item[0].parts[len(source.parts):],
14681468
target_item[0].parts[len(target.parts):]) # dirpath
@@ -1472,12 +1472,12 @@ def ordered_walk(path):
14721472
for filename in source_item[2]:
14731473
source_file = source_item[0].joinpath(filename)
14741474
target_file = target_item[0].joinpath(filename)
1475-
if follow_symlinks or not source_file.is_symlink():
1475+
if follow_symlinks or not source_file.info.is_symlink():
14761476
# Regular file.
14771477
self.assertEqual(source_file.read_bytes(), target_file.read_bytes())
1478-
elif source_file.is_dir():
1478+
elif source_file.info.is_dir():
14791479
# Symlink to directory.
1480-
self.assertTrue(target_file.is_dir())
1480+
self.assertTrue(target_file.info.is_dir())
14811481
self.assertEqual(source_file.readlink(), target_file.readlink())
14821482
else:
14831483
# Symlink to file.
@@ -1503,13 +1503,13 @@ def test_copy_dir_to_existing_directory_dirs_exist_ok(self):
15031503
target.joinpath('dirD').mkdir()
15041504
result = source.copy(target, dirs_exist_ok=True)
15051505
self.assertEqual(result, target)
1506-
self.assertTrue(target.is_dir())
1507-
self.assertTrue(target.joinpath('dirD').is_dir())
1508-
self.assertTrue(target.joinpath('dirD', 'fileD').is_file())
1509-
self.assertEqual(target.joinpath('dirD', 'fileD').read_text(),
1506+
self.assertTrue(result.info.is_dir())
1507+
self.assertTrue(result.joinpath('dirD').info.is_dir())
1508+
self.assertTrue(result.joinpath('dirD', 'fileD').info.is_file())
1509+
self.assertEqual(result.joinpath('dirD', 'fileD').read_text(),
15101510
"this is file D\n")
1511-
self.assertTrue(target.joinpath('fileC').is_file())
1512-
self.assertTrue(target.joinpath('fileC').read_text(),
1511+
self.assertTrue(result.joinpath('fileC').info.is_file())
1512+
self.assertTrue(result.joinpath('fileC').read_text(),
15131513
"this is file C\n")
15141514

15151515
def test_copy_dir_to_itself(self):
@@ -1524,15 +1524,15 @@ def test_copy_dir_into_itself(self):
15241524
target = base / 'dirC' / 'dirD' / 'copyC'
15251525
self.assertRaises(OSError, source.copy, target)
15261526
self.assertRaises(OSError, source.copy, target, follow_symlinks=False)
1527-
self.assertFalse(target.exists())
1527+
self.assertFalse(target.info.exists())
15281528

15291529
def test_copy_into(self):
15301530
base = self.cls(self.base)
15311531
source = base / 'fileA'
15321532
target_dir = base / 'dirA'
15331533
result = source.copy_into(target_dir)
15341534
self.assertEqual(result, target_dir / 'fileA')
1535-
self.assertTrue(result.exists())
1535+
self.assertTrue(result.info.exists())
15361536
self.assertEqual(source.read_text(), result.read_text())
15371537

15381538
def test_copy_into_empty_name(self):

Lib/test/test_sys.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,13 @@ def test_getallocatedblocks(self):
11001100
# code objects is a large fraction of the total number of
11011101
# references, this can cause the total number of allocated
11021102
# blocks to exceed the total number of references.
1103-
if not support.Py_GIL_DISABLED:
1103+
#
1104+
# For some reason, iOS seems to trigger the "unlikely to happen"
1105+
# case reliably under CI conditions. It's not clear why; but as
1106+
# this test is checking the behavior of getallocatedblock()
1107+
# under garbage collection, we can skip this pre-condition check
1108+
# for now. See GH-130384.
1109+
if not support.Py_GIL_DISABLED and not support.is_apple_mobile:
11041110
self.assertLess(a, sys.gettotalrefcount())
11051111
except AttributeError:
11061112
# gettotalrefcount() not available
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Ensure the path returned from :meth:`pathlib.Path.copy` or
2+
:meth:`~pathlib.Path.move` has fresh :attr:`~pathlib.Path.info`.

PCbuild/pcbuild.proj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@
9595
</ItemGroup>
9696

9797
<Target Name="Build">
98-
<MSBuild Projects="@(FreezeProjects)"
98+
<MSBuild Condition="$(Configuration) != 'PGUpdate'"
99+
Projects="@(FreezeProjects)"
99100
Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)"
100101
BuildInParallel="%(BuildInParallel)"
101102
StopOnFirstFailure="true"

0 commit comments

Comments
 (0)