Description
Following the discussion from #1140 with @effigies , the Opener does not guarantee the file mode (or err) when a file handler is provided instead of a filename. E.g.:
fd = open('file', 'r')
with Opener(fd, 'w') as bigO:
bigO.write('hello') # trying to write in read mode
fd = open('file', 'r')
with Opener(fd, 'rb') as bigO:
assert bigO.read(5) == b'hello' # 'hello' != b'hello'
For read/write, it seems to me that it is no-brainer- just check for the correct chars in the .mode
and err when it is different. This change in the contract may require a DeprecationWarning.
Now for text/binary mode, let me know if that's too hacky: When opening in text mode on Py3, the file object has an attribute 'buffer' which is the same as opening the file in binary mode. So something like this would guarantee to always be binary (when requested + for the default mode):
class Opener(object):
def __init__(self, fileish, *args, **kwargs):
mode = kwargs['mode'] # all that kwargs processing
if self._is_fileobj(fileish):
# binary mode is requested, but fileish mode is text
if 'b' in mode and 'b' not in fileish.mode:
self.fobj = fileish.buffer
else:
self.fobj = fileish
...
fd = open('file', 'r')
with Opener(fd, 'rb') as bigO:
assert bigO.read(5) == 'hello' # b'hello' == b'hello'
however, if fd is binary mode and Opener requests text mode, probably a TextIOWrapper needs to be used to convert between modes.