1 |
commit: e93e6d65fa1ca75f676a227f7918f8b6d747425c |
2 |
Author: Florian Schmaus <flo <AT> geekplace <DOT> eu> |
3 |
AuthorDate: Fri Dec 18 18:46:38 2020 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Dec 31 01:40:42 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=e93e6d65 |
7 |
|
8 |
Make atomic_ofstream a Context Manager |
9 |
|
10 |
This allows using a "with statement" together with instances of |
11 |
atomic_ofstream. Allowing for more readable, less error prone and |
12 |
shorter code. |
13 |
|
14 |
Signed-off-by: Florian Schmaus <flo <AT> geekplace.eu> |
15 |
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> |
16 |
|
17 |
lib/portage/util/__init__.py | 10 +++++++++- |
18 |
1 file changed, 9 insertions(+), 1 deletion(-) |
19 |
|
20 |
diff --git a/lib/portage/util/__init__.py b/lib/portage/util/__init__.py |
21 |
index 0412b2b59..bedcbcfe6 100644 |
22 |
--- a/lib/portage/util/__init__.py |
23 |
+++ b/lib/portage/util/__init__.py |
24 |
@@ -11,6 +11,7 @@ __all__ = ['apply_permissions', 'apply_recursive_permissions', |
25 |
'stack_dicts', 'stack_lists', 'unique_array', 'unique_everseen', 'varexpand', |
26 |
'write_atomic', 'writedict', 'writemsg', 'writemsg_level', 'writemsg_stdout'] |
27 |
|
28 |
+from contextlib import AbstractContextManager |
29 |
from copy import deepcopy |
30 |
import errno |
31 |
import io |
32 |
@@ -1246,7 +1247,7 @@ def apply_secpass_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1, |
33 |
stat_cached=stat_cached, follow_links=follow_links) |
34 |
return all_applied |
35 |
|
36 |
-class atomic_ofstream(ObjectProxy): |
37 |
+class atomic_ofstream(AbstractContextManager, ObjectProxy): |
38 |
"""Write a file atomically via os.rename(). Atomic replacement prevents |
39 |
interprocess interference and prevents corruption of the target |
40 |
file when the write is interrupted (for example, when an 'out of space' |
41 |
@@ -1287,6 +1288,13 @@ class atomic_ofstream(ObjectProxy): |
42 |
encoding=_encodings['fs'], errors='strict'), |
43 |
mode=mode, **kargs)) |
44 |
|
45 |
+ def __exit__(self, exc_type, exc_val, exc_tb): |
46 |
+ if exc_type is not None: |
47 |
+ self.abort() |
48 |
+ else: |
49 |
+ self.close() |
50 |
+ return None |
51 |
+ |
52 |
def _get_target(self): |
53 |
return object.__getattribute__(self, '_file') |