Visitar URL original
bpo-30028: make test.support.temp_cwd() fork-safe by akruis · Pull Request #1066 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
6 changes: 5 additions & 1 deletion Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -960,10 +960,14 @@ def temp_dir(path=None, quiet=False):
warnings.warn(f'tests may fail, unable to create '
f'temporary directory {path!r}: {exc}',
RuntimeWarning, stacklevel=3)
if dir_created:
pid = os.getpid()
try:
yield path
finally:
if dir_created:
# In case the process forks, let only the parent remove the
# directory. The child has a diffent process id. (bpo-30028)
if dir_created and pid == os.getpid():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is non obvious, can you please add a short comment explaining why you test the pid?

I guess that it's test to avoid that two processes try to remove the directory if the parent uses fork()?

Add bpo-30028 in the comment.

rmtree(path)

@contextlib.contextmanager
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,20 @@ def test_temp_dir__existing_dir__quiet_true(self):
f'temporary directory {path!r}: '),
warn)

@unittest.skipUnless(hasattr(os, "fork"), "test requires os.fork")
def test_temp_dir__forked_child(self):
"""Test that a forked child process does not remove the directory."""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a reference to the issue: bpo-30028

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No other doc string in this file contains a reference to bpo. Therefore I added the reference as a comment.

with support.temp_cwd() as temp_path:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, please don't use fork in a test process. Write a short script run with test.support.script_helper. Otherwise, I expect too many issues like bad handling of KeyboardInterrupt. Use textwrap.dedent() to include the script directly here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (1a0364d). Is the patch now OK?

pid = os.fork()
if pid != 0:
# parent process
os.waitpid(pid, 0) # wait for the child to terminate
# make sure that temp_path is still present
self.assertTrue(os.path.isdir(temp_path))
if pid == 0:
# terminate the child in order to not confuse the test runner
os._exit(0)

# Tests for change_cwd()

def test_change_cwd(self):
Expand Down