Issue 1581357: missing enter + getattr forwarding (original) (raw)

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 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)
  1. 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...