1ATOMICWRITES(1) atomicwrites ATOMICWRITES(1)
2
3
4
6 atomicwrites - atomicwrites Documentation
7
8 Atomic file writes.
9
10 from atomicwrites import atomic_write
11
12 with atomic_write('foo.txt', overwrite=True) as f:
13 f.write('Hello world.')
14 # "foo.txt" doesn't exist yet.
15
16 # Now it does.
17
18 Features that distinguish it from other similar libraries (see
19 Alternatives and Credit):
20
21 • Race-free assertion that the target file doesn't yet exist. This can
22 be controlled with the overwrite parameter.
23
24 • Windows support, although not well-tested. The MSDN resources are not
25 very explicit about which operations are atomic. I'm basing my as‐
26 sumptions off a comment by Doug Crook, who appears to be a Microsoft
27 employee:
28 FAQ: Is MoveFileEx atomic Frequently asked question: Is MoveFileEx
29 atomic if the existing and new files are both on the same drive?
30
31 The simple answer is "usually, but in some cases it will silently
32 fall-back to a non-atomic method, so don't count on it".
33
34 The implementation of MoveFileEx looks something like this: [...]
35
36 The problem is if the rename fails, you might end up with a Copy‐
37 File, which is definitely not atomic.
38
39 If you really need atomic-or-nothing, you can try calling NtSet‐
40 InformationFile, which is unsupported but is much more likely to
41 be atomic.
42
43 • Simple high-level API that wraps a very flexible class-based API.
44
45 • Consistent error handling across platforms.
46
48 It uses a temporary file in the same directory as the given path. This
49 ensures that the temporary file resides on the same filesystem.
50
51 The temporary file will then be atomically moved to the target loca‐
52 tion: On POSIX, it will use rename if files should be overwritten, oth‐
53 erwise a combination of link and unlink. On Windows, it uses MoveFileEx
54 through stdlib's ctypes with the appropriate flags.
55
56 Note that with link and unlink, there's a timewindow where the file
57 might be available under two entries in the filesystem: The name of the
58 temporary file, and the name of the target file.
59
60 Also note that the permissions of the target file may change this way.
61 In some situations a chmod can be issued without any concurrency prob‐
62 lems, but since that is not always the case, this library doesn't do it
63 by itself.
64
65 fsync
66 On POSIX, fsync is invoked on the temporary file after it is written
67 (to flush file content and metadata), and on the parent directory after
68 the file is moved (to flush filename).
69
70 fsync does not take care of disks' internal buffers, but there don't
71 seem to be any standard POSIX APIs for that. On OS X, fcntl is used
72 with F_FULLFSYNC instead of fsync for that reason.
73
74 On Windows, _commit is used, but there are no guarantees about disk in‐
75 ternal buffers.
76
78 Atomicwrites is directly inspired by the following libraries (and
79 shares a minimal amount of code):
80
81 • The Trac project's utility functions, also used in Werkzeug and
82 mitsuhiko/python-atomicfile. The idea to use ctypes instead of Py‐
83 Win32 originated there.
84
85 • abarnert/fatomic. Windows support (based on PyWin32) was originally
86 taken from there.
87
88 Other alternatives to atomicwrites include:
89
90 • sashka/atomicfile. Originally I considered using that, but at the
91 time it was lacking a lot of features I needed (Windows support,
92 overwrite-parameter, overriding behavior through subclassing).
93
94 • The Boltons library collection features a class for atomic file
95 writes, which seems to have a very similar overwrite parameter. It is
96 lacking Windows support though.
97
99 Licensed under the MIT, see LICENSE.
100
102 atomicwrites.atomic_write(path, writer_cls=<class 'atomicwrites.Atom‐
103 icWriter'>, **cls_kwargs)
104 Simple atomic writes. This wraps AtomicWriter:
105
106 with atomic_write(path) as f:
107 f.write(...)
108
109 Parameters
110
111 • path -- The target path to write to.
112
113 • writer_cls -- The writer class to use. This parameter
114 is useful if you subclassed AtomicWriter to change some
115 behavior and want to use that new subclass.
116
117 Additional keyword arguments are passed to the writer class. See
118 AtomicWriter.
119
120 Errorhandling
121 All filesystem errors are subclasses of OSError.
122
123 • On UNIX systems, errors from the Python stdlib calls are thrown.
124
125 • On Windows systems, errors from Python's ctypes are thrown.
126
127 In either case, the errno attribute on the thrown exception maps to an
128 errorcode in the errno module.
129
130 Low-level API
131 atomicwrites.replace_atomic(src, dst)
132 Move src to dst. If dst exists, it will be silently overwritten.
133
134 Both paths must reside on the same filesystem for the operation
135 to be atomic.
136
137 atomicwrites.move_atomic(src, dst)
138 Move src to dst. There might a timewindow where both filesystem
139 entries exist. If dst already exists, FileExistsError will be
140 raised.
141
142 Both paths must reside on the same filesystem for the operation
143 to be atomic.
144
145 class atomicwrites.AtomicWriter(path, mode='w', overwrite=False,
146 **open_kwargs)
147 A helper class for performing atomic writes. Usage:
148
149 with AtomicWriter(path).open() as f:
150 f.write(...)
151
152 Parameters
153
154 • path -- The destination filepath. May or may not exist.
155
156 • mode -- The filemode for the temporary file. This de‐
157 faults to wb in Python 2 and w in Python 3.
158
159 • overwrite -- If set to false, an error is raised if
160 path exists. Errors are only raised after the file has
161 been written to. Either way, the operation is atomic.
162
163 If you need further control over the exact behavior, you are en‐
164 couraged to subclass.
165
166 commit(f)
167 Move the temporary file to the target location.
168
169 get_fileobject(suffix='', prefix='tmp', dir=None, **kwargs)
170 Return the temporary file to use.
171
172 open() Open the temporary file.
173
174 rollback(f)
175 Clean up all temporary resources.
176
177 sync(f)
178 responsible for clearing as many file caches as possible
179 before commit
180
182 Copyright (c) 2015-2016 Markus Unterwaditzer
183
184 Permission is hereby granted, free of charge, to any person obtaining a
185 copy of this software and associated documentation files (the "Soft‐
186 ware"), to deal in the Software without restriction, including without
187 limitation the rights to use, copy, modify, merge, publish, distribute,
188 sublicense, and/or sell copies of the Software, and to permit persons
189 to whom the Software is furnished to do so, subject to the following
190 conditions:
191
192 The above copyright notice and this permission notice shall be included
193 in all copies or substantial portions of the Software.
194
195 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
196 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MER‐
197 CHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
198 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
199 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
200 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT‐
201 WARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
202
204 Markus Unterwaditzer
205
207 2015-2021, Markus Unterwaditzer
208
209
210
211
2121.4 Jul 23, 2021 ATOMICWRITES(1)