• Stars
    star
    172
  • Rank 221,201 (Top 5 %)
  • Language
    Python
  • License
    MIT License
  • Created over 4 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

๐Ÿงท A safer writer ๐Ÿงท

๐Ÿงฟ safer: A safer writer ๐Ÿงฟ

Avoid partial writes or corruption!

safer wraps file streams, sockets, or a callable, and offers a drop-in replacement for regular old open().

Quick summary

A tiny example

import safer

with safer.open(filename, 'w') as fp:
    fp.write('one')
    print('two', file=fp)
    raise ValueError
    # filename was not written.

How to use

Use pip to install safer from the command line: pip install safer.

Tested on Python 3.4 - 3.11. An old Python 2.7 version is here.

See the Medium article here

The details

safer helps prevent programmer error from corrupting files, socket connections, or generalized streams by writing a whole file or nothing.

It does not prevent concurrent modification of files from other threads or processes: if you need atomic file writing, see https://pypi.org/project/atomicwrites/

It also has a useful dry_run setting to let you test your code without actually overwriting the target file.

  • safer.writer() wraps an existing writer, socket or stream and writes a whole response or nothing

  • safer.open() is a drop-in replacement for built-in open that writes a whole file or nothing

  • safer.closer() returns a stream like from safer.write() that also closes the underlying stream or callable when it closes.

  • safer.dump() is like a safer json.dump() which can be used for any serialization protocol, including Yaml and Toml, and also allows you to write to file streams or any other callable.

  • safer.printer() is safer.open() except that it yields a a function that prints to the stream.

By default, safer buffers the written data in memory in a io.StringIO or io.BytesIO.

For very large files, safer.open() has a temp_file argument which writes the data to a temporary file on disk, which is moved over using os.rename if the operation completes successfully. This functionality does not work on Windows. (In fact, it's unclear if any of this works on Windows, but that certainly won't. Windows developer solicted!)

Example: safer.writer()

safer.writer() wraps an existing stream - a writer, socket, or callback - in a temporary stream which is only copied to the target stream at close(), and only if no exception was raised.

Suppose sock = socket.socket(*args).

The old, dangerous way goes like this.

try:
    write_header(sock)
    write_body(sock)   # Exception is thrown here
    write_footer(sock)
 except Exception:
    write_error(sock)  # Oops, the header was already written

With safer you write all or nothing:

try:
    with safer.writer(sock) as s:
        write_header(s)
        write_body(s)  # Exception is thrown here
        write_footer(s)
 except Exception:
    write_error(sock)  # Nothing has been written

Example: safer.open() and json

safer.open() is a a drop-in replacement for built-in open() except that when used as a context, it leaves the original file unchanged on failure.

It's easy to write broken JSON if something within it doesn't serialize.

with open(filename, 'w') as fp:
    json.dump(data, fp)
    # If an exception is raised, the file is empty or partly written

safer prevents this:

with safer.open(filename, 'w') as fp:
    json.dump(data, fp)
    # If an exception is raised, the file is unchanged.

safer.open(filename) returns a file stream fp like open(filename) would, except that fp writes to memory stream or a temporary file in the same directory.

If fp is used as a context manager and an exception is raised, then the property fp.safer_failed on the stream is automatically set to True.

And when fp.close() is called, the cached data is stored in filename - unless fp.safer_failed is true.

Example: safer.printer()

safer.printer() is similar to safer.open() except it yields a function that prints to the open file - it's very convenient for printing text.

Like safer.open(), if an exception is raised within its context manager, the original file is left unchanged.

Before.

with open(file, 'w') as fp:
    for item in items:
        print(item, file=fp)
    # Prints lines until the first exception

With safer

with safer.printer(file) as print:
    for item in items:
        print(item)
    # Either the whole file is written, or nothing

API Documentation

More Repositories

1

swirly

Tom Swirly's Javascript libraries for Max.
Max
43
star
2

echomesh

An array of noisy, reactive little computers.
C++
37
star
3

gitz

๐Ÿ—œ Tiny useful git commands, some dangerous ๐Ÿ—œ
Python
31
star
4

tfile

๐Ÿ“ tiny C++11 file utilities ๐Ÿ“
C++
23
star
5

myers

A tiny, generic implementation of the Myers diff algorithm
Python
19
star
6

dtyper

๐Ÿ— Fix and improve `typer` ๐Ÿ—
Python
18
star
7

sproc

โ› Subprocesses for subhumanses โ›
Python
10
star
8

editor

๐Ÿ–‹ Open the default text editor ๐Ÿ–‹
Python
8
star
9

impall

๐Ÿ›Ž Test-import all modules ๐Ÿ›Ž
Python
7
star
10

wavemap

๐ŸŒŠ mmap massive audio files as numpy ๐ŸŒŠ
Python
6
star
11

git-st

Pretty git status
Shell
5
star
12

nc

๐ŸŽจ Named colors in Python ๐ŸŽจ
Python
4
star
13

swirly-leap

An interface to the Leap Motion Controller
C++
4
star
14

xmod

๐ŸŒฑ Turn any object into a module ๐ŸŒฑ
Python
4
star
15

vl8

๐Ÿ”‰ Perturbed audio ๐Ÿ”‰
Python
3
star
16

coroniad

๐Ÿ‘‘ The Coroniad - elegant, useful little programming tools to divert and entertain ๐Ÿ‘‘
3
star
17

abbrev

๐Ÿœ Expand abbreviations ๐Ÿœ
Python
3
star
18

dek

๐ŸŽด The decorator-decorator ๐ŸŽด
Python
3
star
19

runs

๐Ÿƒ Run a block of text as a subprocess ๐Ÿƒ
Python
3
star
20

git-split

Split a commit into many commits
Python
3
star
21

fil

๐Ÿบ Read/write JSON/TOMLYaml/txt/ ๐Ÿบ
Python
3
star
22

LaserBoy

A fork of James Lehman's super-excellent "LaserBoy" open source library - http://laserboy.org/.
C++
3
star
23

datacls

๐Ÿ—‚ Take the edge off `dataclass` ๐Ÿ—‚
Python
2
star
24

led

quick led!
Python
2
star
25

stroll

A simpler and more powerful os.walk
Python
2
star
26

swirly-DMXIS

Python code and lighting instrument descriptions for Enttec's DMXIS system.
Python
2
star
27

slow_gold

rec: always on
C++
2
star
28

tdir

๐Ÿ—ƒ Create, fill a temporary directory ๐Ÿ—ƒ
Python
2
star
29

tkl

BiblioPixel driver for the xled library
Python
2
star
30

cfgs

๐Ÿ‡ XDG standard config files ๐Ÿ‡
Python
2
star
31

threa

More powerful threads
Python
2
star
32

swirly-juce

Tom Swirly's free Juce code.
C++
2
star
33

radio

Utilities for Icecast streaming on Ubuntu
C
2
star
34

swirly-avr

Tom Swirly's Arduino programming
C++
2
star
35

doks

๐Ÿ“š Automatically create READMEs from your project ๐Ÿ“š
Python
2
star
36

swirler

Run things on startup.
Python
1
star
37

nederlands

Neederlandse woorden frequentien
Python
1
star
38

rec-old

๐Ÿ“ฏ Tom Ritchford's README.md ๐Ÿ“ฏ
1
star
39

grit

rationalized git workflow
Python
1
star
40

dronepledge

Modifications to "petitionscript" for our anti-drone pledge.
PHP
1
star
41

DMXIS

Python
1
star
42

cppguards

Add C++ guards to one or more files.
Python
1
star
43

the-collapse

a csound project
1
star
44

yingyang

Poisson distribution and the ying-yang grinder
Python
1
star
45

untab

Clean C++ files by removing tabs, whitespace, and replacing non-UTF-8 characters.
Python
1
star
46

ndb

Tiny repo with a little ndb code
Python
1
star
47

mop

Mobile Project
JavaScript
1
star
48

rec.github.io

๐Ÿงต My git hub pages ๐Ÿงต
Python
1
star
49

blocks

โฌœ๐ŸŸฉ๐ŸŸฆ๐ŸŸฅ Solve a block puzzle ๐ŸŸฅ๐ŸŸฆ๐ŸŸฉโฌœ
Python
1
star
50

rec

๐Ÿ“ฏ Tom Ritchford's README.md ๐Ÿ“ฏ
CSS
1
star
51

multi

๐Ÿ“š Manage my repositories ๐Ÿ“š
Python
1
star
52

recs

๐ŸŽฌ recs: the Universal Recorder ๐ŸŽฌ
Python
1
star
53

plur

๐Ÿ”ข Simple universal word pluralizer ๐Ÿ”ข
Python
1
star
54

clsprop

๐Ÿซ Like property but for classes ๐Ÿซ
Python
1
star
55

gpu_fft_py

A Python interface to the Raspberry Pi's hardware accelerated FFT functions.
C
1
star
56

the-odd-www

DHTML code for "The Odd"'s website.
1
star
57

movee

๐ŸŽฆ - Script bash and Python into asciinema movies - ๐ŸŽฆ
Python
1
star
58

wik

Tiny Python wiki
Perl
1
star
59

test

Random test code.
Python
1
star
60

baby

Analyze an Arduino project
C++
1
star
61

backer

๐Ÿ“ฆ Continuously back up files ๐Ÿ“ฆ
Python
1
star
62

hardback

๐Ÿ““ Hardcopy backups of digital data ๐Ÿ““
Python
1
star