Skip to content

Commit 6171ed1

Browse files
graingertkumaraditya303
authored andcommitted
pythongh-126639: Add ResourceWarning to NamedTemporaryFile (python#126677)
Co-authored-by: Kumar Aditya <[email protected]>
1 parent aaac7a2 commit 6171ed1

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

Lib/tempfile.py

+23-3
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,19 @@ class _TemporaryFileCloser:
437437
cleanup_called = False
438438
close_called = False
439439

440-
def __init__(self, file, name, delete=True, delete_on_close=True):
440+
def __init__(
441+
self,
442+
file,
443+
name,
444+
delete=True,
445+
delete_on_close=True,
446+
warn_message="Implicitly cleaning up unknown file",
447+
):
441448
self.file = file
442449
self.name = name
443450
self.delete = delete
444451
self.delete_on_close = delete_on_close
452+
self.warn_message = warn_message
445453

446454
def cleanup(self, windows=(_os.name == 'nt'), unlink=_os.unlink):
447455
if not self.cleanup_called:
@@ -469,7 +477,10 @@ def close(self):
469477
self.cleanup()
470478

471479
def __del__(self):
480+
close_called = self.close_called
472481
self.cleanup()
482+
if not close_called:
483+
_warnings.warn(self.warn_message, ResourceWarning)
473484

474485

475486
class _TemporaryFileWrapper:
@@ -483,8 +494,17 @@ class _TemporaryFileWrapper:
483494
def __init__(self, file, name, delete=True, delete_on_close=True):
484495
self.file = file
485496
self.name = name
486-
self._closer = _TemporaryFileCloser(file, name, delete,
487-
delete_on_close)
497+
self._closer = _TemporaryFileCloser(
498+
file,
499+
name,
500+
delete,
501+
delete_on_close,
502+
warn_message=f"Implicitly cleaning up {self!r}",
503+
)
504+
505+
def __repr__(self):
506+
file = self.__dict__['file']
507+
return f"<{type(self).__name__} {file=}>"
488508

489509
def __getattr__(self, name):
490510
# Attribute lookups are delegated to the underlying file

Lib/test/test_tempfile.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -1112,11 +1112,14 @@ def my_func(dir):
11121112
# Testing extreme case, where the file is not explicitly closed
11131113
# f.close()
11141114
return tmp_name
1115-
# Make sure that the garbage collector has finalized the file object.
1116-
gc.collect()
11171115
dir = tempfile.mkdtemp()
11181116
try:
1119-
tmp_name = my_func(dir)
1117+
with self.assertWarnsRegex(
1118+
expected_warning=ResourceWarning,
1119+
expected_regex=r"Implicitly cleaning up <_TemporaryFileWrapper file=.*>",
1120+
):
1121+
tmp_name = my_func(dir)
1122+
support.gc_collect()
11201123
self.assertFalse(os.path.exists(tmp_name),
11211124
f"NamedTemporaryFile {tmp_name!r} "
11221125
f"exists after finalizer ")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:class:`tempfile.NamedTemporaryFile` will now issue a :exc:`ResourceWarning` when it is finalized by the garbage collector without being explicitly closed.

0 commit comments

Comments
 (0)