Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bug or feature: open and io.open are not interchangeable

I always thought open and io.open were interchangeable.
Apparently not, if I believe this snippet:

import ctypes, io

class POINT(ctypes.Structure):
    _fields_ = [("x", ctypes.c_int),("y", ctypes.c_int)]
# THIS WORKS
with open("mypoints.bin", "wb") as f: 
    for i in range(10):
        p = POINT(i,10-i)
        print p.x, p.y
        f.write(p)
# THIS FAILS 
with io.open("mypoints.bin", "wb") as f:
    for i in range(10):
        p = POINT(i,10-i)
        print p.x, p.y
        f.write(p)

0 10
Traceback (most recent call last):
  File "D:\test.py", line 10, in <module>
    f.write(p)
  File "c:\Python26\lib\io.py", line 1070, in write
    self._write_buf.extend(b)
TypeError: 'POINT' object is not iterable

Note: I tested in Python 2.6.6

like image 558
Alain Avatar asked Feb 04 '11 10:02

Alain


1 Answers

Yes, it's a "bug", io.open in Python 2.6 is slightly broken. It was supposed to be work like 3.x's open to ease transition, but it doesn't work correctly in some cases. For example, it doesn't support objects with the buffer interface like in your case. This is fixed in Python 2.7 where the builtin open can be used like the open in 3.x, and io.open is just an alias to it.

If you need binary mode, use open, it behaves the same in 2.x and 3.x, with the only difference being that in 2.x it accepts for writing objects that it shouldn't (such as unicode objects). If you need text mode, use codecs.open or io.open with encoding argument. Both are available in 3.x.

But note that open and io.open were meant to not be interchangeable, because io is Python 3's io module, and in Python 3 open is very different from the open in Python 2.6 or less.

http://docs.python.org/library/io.html

like image 113
Rosh Oxymoron Avatar answered Oct 02 '22 14:10

Rosh Oxymoron