Skip to content

Unexpected behavior in get_readable_fileobj in Py3 #6460

Closed

Description

@taldcroft

Not sure if this is related to #3013, but the behavior in Py3 below does not make sense to me. The docstring claims one can input a File-like object, but that basically doesn't work at all as far as I can tell.

In [20]: fh = open('test5.dat', 'rb')

In [21]: type(fh.read(20))
Out[21]: bytes

In [22]: with get_readable_fileobj(fh) as fh2:
    ...:     print(type(fh2.read(20)))
    ...:     
<class 'str'>  # EXPECTED bytes

In [23]: fh = open('test5.dat', 'r')

In [24]: type(fh.read(20))
Out[24]: str

In [25]: with get_readable_fileobj(fh) as fh2:
    ...:     print(type(fh2.read(20)))
    ...:     
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-25-5b2dfcd6aacc> in <module>()
      1 with get_readable_fileobj(fh) as fh2:
----> 2     print(type(fh2.read(20)))
      3 

AttributeError: '_io.TextIOWrapper' object has no attribute 'readinto'

# WHY THE EXCEPTION?

In [27]: fh = open('test5.dat', 'r')

In [28]: with get_readable_fileobj(fh) as fh2:
    ...:     print(type(fh2.read()))
    ...:     
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-06b67839537f> in <module>()
      1 with get_readable_fileobj(fh) as fh2:
----> 2     print(type(fh2.read()))
      3 

TypeError: read() should return bytes

# WTF?

Activity

  1. pllim commented on Aug 23, 2017

    @pllim
    Member

    Did you try passing in encoding='binary' into get_readable_fileobj()?

  2. pllim commented on Feb 27, 2018

    @pllim
    Member

    Two things here...

    1. get_readable_fileobj() does return bytes if you explicitly gives it encoding='binary'. Default None makes it guess, and on my machine (and as yours above), it guessed wrong (utf-8).

    2. When in the "text" mode (as opposed to binary), the logic is basically fh2 = io.TextIOWrapper(io.BufferedReader(fh), encoding='utf-8'). You can recreate the same AttributeError just using this and then fh2.read(20).

    Not sure what we can do about these. Any idea?

  3. pllim commented on Oct 30, 2019

    @pllim
    Member

    The behavior has changed since this was first reported.

    fh.seek(0)
    with get_readable_fileobj(fh) as fh2:
        print(type(fh2.read(20)))

    now gives this exception:

    UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8a in position 10:
    invalid start byte
    

    If you use encoding='binary' specifically, it behaves as you expected:

    >>> fh.seek(0)
    >>> with get_readable_fileobj(fh, encoding='binary') as fh2:
    ...    print(type(fh2.read(20)))    
    <class 'bytes'>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions