For streams opened as reading, perhaps the most reliable way to determine its mode is to actually read from it:
def is_binary(f):
return isinstance(f.read(0), bytes)
Through it does have a caveat that it won't work if the stream was already closed (which may raise IOError
) it would reliably determine binary-ness of any custom file-like objects neither extending from appropriate io
ABCs nor providing the mode
attribute.
If only Python 3 support is required, it is also possible to determine text/binary mode of writable streams given the clear distinction between bytes and text:
def is_binary(f):
read = getattr(f, 'read', None)
if read is not None:
try:
data = read(0)
except (TypeError, ValueError):
pass # ValueError is also a superclass of io.UnsupportedOperation
else:
return isinstance(data, bytes)
try:
# alternatively, replace with empty text literal
# and swap the following True and False.
f.write(b'')
except TypeError:
return False
return True
Unless you are to frequently test if a stream is in binary mode or not (which is unnecessary since binary-ness of a stream should not change for the lifetime of the object), I suspect any performance drawbacks resulting from extensive usage of catching exceptions would be an issue (you could certainly optimize for the likelier path, though).