Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions Lib/pathlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,8 @@ def _raw_path(self):
return paths[0]
elif paths:
# Join path segments from the initializer.
path = self.parser.join(*paths)
# Cache the joined path.
paths.clear()
paths.append(path)
return path
return self.parser.join(*paths)
else:
paths.append('')
return ''

@property
Expand Down
22 changes: 22 additions & 0 deletions Lib/test/test_pathlib/test_join.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"""

import unittest
import threading
from test.support import threading_helper

from .support import is_pypi
from .support.lexical_path import LexicalPath
Expand Down Expand Up @@ -158,6 +160,26 @@ def test_parts(self):
parts = p.parts
self.assertEqual(parts, (sep, 'a', 'b'))

@threading_helper.requires_working_threading()
def test_parts_multithreaded(self):
P = self.cls

NUM_THREADS = 10
NUM_ITERS = 10

for _ in range(NUM_ITERS):
b = threading.Barrier(NUM_THREADS)
path = P('a') / 'b' / 'c' / 'd' / 'e'
expected = ('a', 'b', 'c', 'd', 'e')

def check_parts():
b.wait()
self.assertEqual(path.parts, expected)

threads = [threading.Thread(target=check_parts) for _ in range(NUM_THREADS)]
with threading_helper.start_threads(threads):
pass

def test_parent(self):
# Relative
P = self.cls
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix race condition in :class:`pathlib.Path` on the internal ``_raw_paths``
field.
Loading