wiki:SocketFileAdapter

Socket file adapter for Python 2 / 3 compatiblity

Motivation

To make ftputil usable for Python 3, I decided to use io.TextIOWrapper to add text encoding/decoding capabilities to file objects returned from socket.makefile.

In Python 3, socket.makefile has arguments to encode/decode on the fly, so io.TextIOWrapper isn't needed. Not so in Python 2. My idea was to use socket.makefile to create a binary file object on Python 2 and 3 and wrap this object with io.TextIOWrapper. Unfortunately, the file object returned from socket.makefile in Python 2 can't be wrapped directly. (To use io.TextIOWrapper, the write method of the wrapped file needs to return the number of written bytes, but the file object from socket.makefile in Python 2 returns None.)

Solution

Hence I wrote an adapter to make the socket.makefile return value in Python 2 usable with io.TextIOWrapper. The adapter can be used like this:

# First create a socket file for binary I/O.
fobj = socket_.makefile("rb")  # or mode "wb"
# Adapt the interface of this object if on Python 2
if PYTHON_VERSION == 2:
    fobj = BufferedIOAdapter(fobj, is_readable=True)  # or `is_writable=True`
# If a text file (i. e. unicode I/O) is requested ...
fobj = io.TextIOWrapper(fobj, encoding=...)

Download

This is the adapter module: formatted with syntax highlighting , actual module file.

Here's an usage example in ftputil.file.FTPFile._open.

Last modified 4 years ago Last modified on Oct 5, 2014, 3:13:57 PM