1ATOMICWRITES(1)                  atomicwrites                  ATOMICWRITES(1)
2
3
4

NAME

6       atomicwrites - atomicwrites Documentation Documentation Status
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       See API documentation for more low-level interfaces.
19
20       Features   that  distinguish  it  from  other  similar  libraries  (see
21       Alternatives and Credit):
22
23       • Race-free assertion that the target file doesn't yet exist. This  can
24         be controlled with the overwrite parameter.
25
26       • Windows support, although not well-tested. The MSDN resources are not
27         very explicit about which operations are atomic. I'm  basing  my  as‐
28         sumptions  off  a comment by Doug Cook, who appears to be a Microsoft
29         employee:
30            Question: Is MoveFileEx atomic if the existing and new  files  are
31            both on the same drive?
32
33            The  simple answer is "usually, but in some cases it will silently
34            fall-back to a non-atomic method, so don't count on it".
35
36            The implementation of MoveFileEx looks something like this: [...]
37
38            The problem is if the rename fails, you might end up with a  Copy‐
39            File, which is definitely not atomic.
40
41            If  you  really need atomic-or-nothing, you can try calling NtSet‐
42            InformationFile, which is unsupported but is much more  likely  to
43            be atomic.
44
45       • Simple high-level API that wraps a very flexible class-based API.
46
47       • Consistent error handling across platforms.
48

HOW IT WORKS

50       It  uses a temporary file in the same directory as the given path. This
51       ensures that the temporary file resides on the same filesystem.
52
53       The temporary file will then be atomically moved to  the  target  loca‐
54       tion: On POSIX, it will use rename if files should be overwritten, oth‐
55       erwise a combination of link and unlink. On Windows, it uses MoveFileEx
56       through stdlib's ctypes with the appropriate flags.
57
58       Note  that  with  link  and unlink, there's a timewindow where the file
59       might be available under two entries in the filesystem: The name of the
60       temporary file, and the name of the target file.
61
62       Also  note that the permissions of the target file may change this way.
63       In some situations a chmod can be issued without any concurrency  prob‐
64       lems, but since that is not always the case, this library doesn't do it
65       by itself.
66
67   fsync
68       On POSIX, fsync is invoked on the temporary file after  it  is  written
69       (to flush file content and metadata), and on the parent directory after
70       the file is moved (to flush filename).
71
72       fsync does not take care of disks' internal buffers,  but  there  don't
73       seem  to  be  any  standard POSIX APIs for that. On OS X, fcntl is used
74       with F_FULLFSYNC instead of fsync for that reason.
75
76       On Windows, _commit is used, but there are no guarantees about disk in‐
77       ternal buffers.
78

ALTERNATIVES AND CREDIT

80       Atomicwrites  is  directly  inspired  by  the  following libraries (and
81       shares a minimal amount of code):
82
83       • The Trac project's utility  functions,  also  used  in  Werkzeug  and
84         mitsuhiko/python-atomicfile.  The  idea  to use ctypes instead of Py‐
85         Win32 originated there.
86
87abarnert/fatomic. Windows support (based on PyWin32)  was  originally
88         taken from there.
89
90       Other alternatives to atomicwrites include:
91
92sashka/atomicfile.  Originally  I  considered  using that, but at the
93         time it was lacking a lot of  features  I  needed  (Windows  support,
94         overwrite-parameter, overriding behavior through subclassing).
95
96       • The  Boltons  library  collection  features  a  class for atomic file
97         writes, which seems to have a very similar overwrite parameter. It is
98         lacking Windows support though.
99

LICENSE

101       Licensed under the MIT, see LICENSE.
102

API

104       atomicwrites.atomic_write(path,  writer_cls=<class  'atomicwrites.Atom‐
105       icWriter'>, **cls_kwargs)
106              Simple atomic writes. This wraps AtomicWriter:
107
108                 with atomic_write(path) as f:
109                     f.write(...)
110
111              Parameters
112
113path -- The target path to write to.
114
115writer_cls -- The writer class to use.  This  parameter
116                       is useful if you subclassed AtomicWriter to change some
117                       behavior and want to use that new subclass.
118
119              Additional keyword arguments are passed to the writer class. See
120              AtomicWriter.
121
122   Errorhandling
123       All filesystem errors are subclasses of OSError.
124
125       • On UNIX systems, errors from the Python stdlib calls are thrown.
126
127       • On Windows systems, errors from Python's ctypes are thrown.
128
129       In  either case, the errno attribute on the thrown exception maps to an
130       errorcode in the errno module.
131
132   Low-level API
133       atomicwrites.replace_atomic(src, dst)
134              Move src to dst. If dst exists, it will be silently overwritten.
135
136              Both paths must reside on the same filesystem for the  operation
137              to be atomic.
138
139       atomicwrites.move_atomic(src, dst)
140              Move  src to dst. There might a timewindow where both filesystem
141              entries exist. If dst already exists,  FileExistsError  will  be
142              raised.
143
144              Both  paths must reside on the same filesystem for the operation
145              to be atomic.
146
147       class   atomicwrites.AtomicWriter(path,   mode='w',    overwrite=False,
148       **open_kwargs)
149              A helper class for performing atomic writes. Usage:
150
151                 with AtomicWriter(path).open() as f:
152                     f.write(...)
153
154              Parameters
155
156path -- The destination filepath. May or may not exist.
157
158mode  --  The filemode for the temporary file. This de‐
159                       faults to wb in Python 2 and w in Python 3.
160
161overwrite -- If set to false, an  error  is  raised  if
162                       path exists.  Errors are only raised after the file has
163                       been written to.  Either way, the operation is atomic.
164
165open_kwargs -- Keyword-arguments to pass to the  under‐
166                       lying open() call. This can be used to set the encoding
167                       when opening files in text-mode.
168
169              If you need further control over the exact behavior, you are en‐
170              couraged to subclass.
171
172              commit(f)
173                     Move the temporary file to the target location.
174
175              get_fileobject(suffix='', prefix='tmp', dir=None, **kwargs)
176                     Return the temporary file to use.
177
178              open() Open the temporary file.
179
180              rollback(f)
181                     Clean up all temporary resources.
182
183              sync(f)
184                     responsible  for clearing as many file caches as possible
185                     before commit
186

LICENSE

188       Copyright (c) 2015-2016 Markus Unterwaditzer
189
190       Permission is hereby granted, free of charge, to any person obtaining a
191       copy  of  this  software and associated documentation files (the "Soft‐
192       ware"), to deal in the Software without restriction, including  without
193       limitation the rights to use, copy, modify, merge, publish, distribute,
194       sublicense, and/or sell copies of the Software, and to  permit  persons
195       to  whom  the  Software is furnished to do so, subject to the following
196       conditions:
197
198       The above copyright notice and this permission notice shall be included
199       in all copies or substantial portions of the Software.
200
201       THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
202       OR IMPLIED, INCLUDING  BUT  NOT  LIMITED  TO  THE  WARRANTIES  OF  MER‐
203       CHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
204       NO EVENT SHALL THE AUTHORS OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY
205       CLAIM,  DAMAGES  OR  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
206       TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFT‐
207       WARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
208

AUTHOR

210       Markus Unterwaditzer
211
213       2015-2023, Markus Unterwaditzer
214
215
216
217
2181.4                              Jan 20, 2023                  ATOMICWRITES(1)
Impressum