Hello. I encountered some unexpected behavior on "with"
statement.
First, please run attached "a.py" file.
# traditional way
<open file 'a.txt', mode 'wb' at 0x009373C8> shift_jis
<type 'instance'> True
# with statement
<open file 'a.txt', mode 'wb' at 0x009373C8> None <type
'file'> False
Traceback (most recent call last):
File "R:\a.py", line 15, in <module>
test(io)
File "R:\a.py", line 8, in test
io.write(u"ã‚ã„ã†ãˆãŠ")
UnicodeEncodeError: 'ascii' codec can't encode
characters in position 0-4: ordin
al not in range(128)
"traditional way" runs as expected, but "with
statement" crashes. This happens because....
1. codecs.open returns codecs.StreamReaderWriter
2. codecs.StreamReaderWriter defines __getattr__
like this.
def __getattr__(self, name,
getattr=getattr):
""" Inherit all other methods from the
underlying stream.
"""
return getattr(self.stream, name)
3. But codecs.StreamReaderWriter doesn't have its
__enter__ definition, so
srw = StreamReaderWriter(stream, ...
srw.__enter__() # actually calls stream.__enter__
which returns stream not srw
via __getattr__
And more worse, with statement doesn't complain
StreamReaderWriter (currently) doesn't support
context manager.
Is this intended behavior? If not, only this problem
can be solved by attached "a.patch". I greped library
files, I found many __getattr__ without __enter__...
|