summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W <robo-eric@gmx.de>2020-10-30 04:56:28 (GMT)
committerGitHub <noreply@github.com>2020-10-30 04:56:28 (GMT)
commit8e409cebad42032bb7d0f2cadd8b1e36081d98af (patch)
tree4347dffac5a388a69782692bfa63075bf8607cdf
parent9129af6050b747f288baa9d4e7d43031647ed222 (diff)
downloadcpython-8e409cebad42032bb7d0f2cadd8b1e36081d98af.zip
cpython-8e409cebad42032bb7d0f2cadd8b1e36081d98af.tar.gz
cpython-8e409cebad42032bb7d0f2cadd8b1e36081d98af.tar.bz2
bpo-42160: tempfile: Reduce overhead of pid check. (GH-22997)
The _RandomSequence class in tempfile used to check the current pid every time its rng property was used. This commit replaces this code with `os.register_at_fork` to reduce the overhead.
-rw-r--r--Lib/tempfile.py22
-rw-r--r--Lib/test/test_tempfile.py4
-rw-r--r--Misc/NEWS.d/next/Library/2020-10-27-00-42-09.bpo-42160.eiLOCi.rst1
3 files changed, 13 insertions, 14 deletions
diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index 770f72c..1bc5c71 100644
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -129,24 +129,22 @@ class _RandomNameSequence:
_RandomNameSequence is an iterator."""
- characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
-
- @property
- def rng(self):
- cur_pid = _os.getpid()
- if cur_pid != getattr(self, '_rng_pid', None):
- self._rng = _Random()
- self._rng_pid = cur_pid
- return self._rng
+ def __init__(self, characters="abcdefghijklmnopqrstuvwxyz0123456789_", length=8, rng=None):
+ if rng is None:
+ rng = _Random()
+ if hasattr(_os, "fork"):
+ # prevent same state after fork
+ _os.register_at_fork(after_in_child=rng.seed)
+ self.rng = rng
+ self.characters = characters
+ self.length = length
def __iter__(self):
return self
def __next__(self):
c = self.characters
- choose = self.rng.choice
- letters = [choose(c) for dummy in range(8)]
- return ''.join(letters)
+ return ''.join(self.rng.choices(c, k=self.length))
def _candidate_tempdir_list():
"""Generate a list of candidate temporary directories which
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index 8ace883..77d710e 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -153,8 +153,8 @@ class TestRandomNameSequence(BaseTestCase):
self.r = tempfile._RandomNameSequence()
super().setUp()
- def test_get_six_char_str(self):
- # _RandomNameSequence returns a six-character string
+ def test_get_eight_char_str(self):
+ # _RandomNameSequence returns a eight-character string
s = next(self.r)
self.nameCheck(s, '', '', '')
diff --git a/Misc/NEWS.d/next/Library/2020-10-27-00-42-09.bpo-42160.eiLOCi.rst b/Misc/NEWS.d/next/Library/2020-10-27-00-42-09.bpo-42160.eiLOCi.rst
new file mode 100644
index 0000000..c5f3091
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-10-27-00-42-09.bpo-42160.eiLOCi.rst
@@ -0,0 +1 @@
+Replaced pid check in ``tempfile._RandomNameSequence`` with ``os.register_at_fork`` to reduce overhead.