@p7g world

Patrick Gingras


Python: The Included Batteries: uu

Recently I was browsing the CPython source for fun, and realized that there were many standard library modules that I never knew about. I figured it would be fun to talk about some of the more obscure ones, and so here we are.

In this series, we’ll take a look at the modules that I think are surprising, curious, or fun, starting with one called uu.

For those following along at home, the source for this module lives here.

uu

This module is a single Python file just 206 lines long, and has been updated as recently as December of 2019. We can see from its __all__ list that it exports an Error class and encode and decode functions. It also implements a simple command line interface for encoding and decoding.

That’s all cool and nice, but what does it actually do? Let’s find out.

The doc string at the top of the file reads:

"""Implementation of the UUencode and UUdecode functions.

encode(in_file, out_file [,name, mode], *, backtick=False)
decode(in_file [, out_file, mode, quiet])
"""

Well, from that we can figure out that it only operates on files (as opposed to Python strings), and that it has some sort of settings relating to back ticks. Seems like we’ll need to dive deeper.

uuencode

As it turns out, uuencode and uudecode are POSIX utilities for moving files between systems using only ASCII characters. Depending on your operating system, you might be able to read about it by entering man uuencode at the command line. uuencode carries over the mode of the file alongside its name and contents.

For more detail about POSIX uuencode, see here.

Trying it out

To get a better idea of how this works, let’s try it out.

First, we’ll create a file named testfile with some text in it:

$ > testfile << EOF
Hello, World!
EOF
$

Now that we have that, we can try out encoding:

$ python -m uu testfile
begin 644 testfile
.2&5L;&\L(%=O<FQD(0H

end

We can see that it prints out the word “begin”, the mode of the file we specified (644 in this case), and the name of the file. Then it prints out the encoded contents of the file, two newlines, and the word “end”. This sums up the encoding scheme at a high level, and in fact this module itself doesn’t concern itself with the specifics of encoding the binary content of the file; that logic lives in the binascii module, which we’ll save for another day.

To round things out, we can decode that result:

$ python -m uu testfile | python -m uu --decode
Hello, World!

It’s also possible to specify a destination file name, in which case uu will create a file with the given name, the mode in the payload, and the decoded contents. Interestingly, the command line interface doesn’t seem to provide a way to use the file name in the payload (normally achieved by calling uu.decode without supplying an out_file).

Conclusion

I won’t say I hope this was helpful. Rather than helpful, I hope this was mildly interesting. See you next time!