|
18 | 18 |
|
19 | 19 | import os |
20 | 20 | import tempfile |
| 21 | +from functools import partial |
21 | 22 |
|
22 | 23 | from django.core.files.utils import FileProxyMixin |
| 24 | +from django.utils.version import PY312 |
23 | 25 |
|
24 | 26 | __all__ = ( |
25 | 27 | "NamedTemporaryFile", |
|
28 | 30 |
|
29 | 31 |
|
30 | 32 | if os.name == "nt": |
31 | | - |
32 | | - class TemporaryFile(FileProxyMixin): |
33 | | - """ |
34 | | - Temporary file object constructor that supports reopening of the |
35 | | - temporary file in Windows. |
36 | | -
|
37 | | - Unlike tempfile.NamedTemporaryFile from the standard library, |
38 | | - __init__() doesn't support the 'delete', 'buffering', 'encoding', or |
39 | | - 'newline' keyword arguments. |
40 | | - """ |
41 | | - |
42 | | - def __init__(self, mode="w+b", bufsize=-1, suffix="", prefix="", dir=None): |
43 | | - fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir) |
44 | | - self.name = name |
45 | | - self.file = os.fdopen(fd, mode, bufsize) |
46 | | - self.close_called = False |
47 | | - |
48 | | - # Because close can be called during shutdown |
49 | | - # we need to cache os.unlink and access it |
50 | | - # as self.unlink only |
51 | | - unlink = os.unlink |
52 | | - |
53 | | - def close(self): |
54 | | - if not self.close_called: |
55 | | - self.close_called = True |
56 | | - try: |
57 | | - self.file.close() |
58 | | - except OSError: |
59 | | - pass |
60 | | - try: |
61 | | - self.unlink(self.name) |
62 | | - except OSError: |
63 | | - pass |
64 | | - |
65 | | - def __del__(self): |
66 | | - self.close() |
67 | | - |
68 | | - def __enter__(self): |
69 | | - self.file.__enter__() |
70 | | - return self |
71 | | - |
72 | | - def __exit__(self, exc, value, tb): |
73 | | - self.file.__exit__(exc, value, tb) |
74 | | - |
75 | | - NamedTemporaryFile = TemporaryFile |
| 33 | + if PY312: |
| 34 | + NamedTemporaryFile = partial(tempfile.NamedTemporaryFile, delete_on_close=False) |
| 35 | + else: |
| 36 | + # TODO: Remove when dropping support for PY311. |
| 37 | + class TemporaryFile(FileProxyMixin): |
| 38 | + """ |
| 39 | + Temporary file object constructor that supports reopening of the |
| 40 | + temporary file in Windows. |
| 41 | +
|
| 42 | + Unlike tempfile.NamedTemporaryFile from the standard library, |
| 43 | + __init__() doesn't support the 'delete', 'buffering', 'encoding', or |
| 44 | + 'newline' keyword arguments. |
| 45 | + """ |
| 46 | + |
| 47 | + def __init__(self, mode="w+b", bufsize=-1, suffix="", prefix="", dir=None): |
| 48 | + fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir) |
| 49 | + self.name = name |
| 50 | + self.file = os.fdopen(fd, mode, bufsize) |
| 51 | + self.close_called = False |
| 52 | + |
| 53 | + # Because close can be called during shutdown |
| 54 | + # we need to cache os.unlink and access it |
| 55 | + # as self.unlink only |
| 56 | + unlink = os.unlink |
| 57 | + |
| 58 | + def close(self): |
| 59 | + if not self.close_called: |
| 60 | + self.close_called = True |
| 61 | + try: |
| 62 | + self.file.close() |
| 63 | + except OSError: |
| 64 | + pass |
| 65 | + try: |
| 66 | + self.unlink(self.name) |
| 67 | + except OSError: |
| 68 | + pass |
| 69 | + |
| 70 | + def __del__(self): |
| 71 | + self.close() |
| 72 | + |
| 73 | + def __enter__(self): |
| 74 | + self.file.__enter__() |
| 75 | + return self |
| 76 | + |
| 77 | + def __exit__(self, exc, value, tb): |
| 78 | + self.file.__exit__(exc, value, tb) |
| 79 | + |
| 80 | + NamedTemporaryFile = TemporaryFile |
76 | 81 | else: |
77 | 82 | NamedTemporaryFile = tempfile.NamedTemporaryFile |
78 | 83 |
|
|
0 commit comments