Opened 6 years ago

Closed 6 years ago

#25576 closed New feature (fixed)

HttpResponse can't be wrapped by io.TextIOWrapper; add required IOBase methods

Reported by: Jon Dufresne Owned by: nobody
Component: HTTP handling Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

In Python3, the stdlib CSV writer [1] is expected to write to a text file, not a binary file. Observe writing to a bytes buffer:

import io
import csv

b = io.BytesIO()
w = csv.writer(b)
w.writerow(['a', 'b', 'c'])
Traceback (most recent call last):
  File "test.py", line 8, in <module>
    w.writerow(['a', 'b', 'c'])
TypeError: 'str' does not support the buffer interface

To handle this, one should use the stdlib's io.TextIOWrapper [2]:

import io
import csv

b = io.BytesIO()
wrapper = io.TextIOWrapper(b, 'utf-8', newline='')
w = csv.writer(wrapper)
w.writerow(['a', 'b', 'c'])
wrapper.flush()
print(b.getvalue())
b'a,b,c\r\n'

As Django's HttpResponse uses a binary file-like interface, I'd expect the same to work. That is, wrap the response in a io.TextIOWrapper and write the CSV document to the wrapper. However, this fails:

import io
import csv
from django.http.response import HttpResponse

r = HttpResponse()
wrapper = io.TextIOWrapper(r, 'utf-8', newline='')
w = csv.writer(wrapper)
w.writerow(['a', 'b', 'c'])
wrapper.flush()
print(r)
Traceback (most recent call last):
  File "/home/jon/test.py", line 8, in <module>
    wrapper = io.TextIOWrapper(r, 'utf-8')
AttributeError: 'HttpResponse' object has no attribute 'readable'

As HttpResponse is a binary file-like interface, I'm suggesting the necessary methods/members be added so that it can be wrapped by io.TextIOWrapper. These methods/members are documented in io.BaseIO() [3]. From initial testing, only readable() and seekable() are required for my use case.

This will make it easier to integrate text-only file interfaces to the binary nature of the response.

[1] https://docs.python.org/3/library/csv.html#csv.writer
[2] https://docs.python.org/3/library/io.html#io.TextIOWrapper
[3] https://docs.python.org/3/library/io.html#io.IOBase

Change History (4)

comment:1 Changed 6 years ago by Claude Paroz

Triage Stage: UnreviewedAccepted
Type: BugNew feature

+1 (in the same spirit as #18523).

comment:2 Changed 6 years ago by Jon Dufresne

Has patch: set

comment:3 Changed 6 years ago by Claude Paroz

Triage Stage: AcceptedReady for checkin

comment:4 Changed 6 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: newclosed

In 05248a10:

Fixed #25576 -- Added IOBase methods required by TextIOWrapper to HttpResponse.

Note: See TracTickets for help on using tickets.
Back to Top