Skip to content

"csv.writer.write" does not work for objects expecting something other than "str" in their "write" method #3997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
deveshks opened this issue May 15, 2020 · 3 comments

Comments

@deveshks
Copy link

deveshks commented May 15, 2020

This was originally found when upgrading pip to mypy 0.770 in pypa/pip#8235

There was a change made to _csv.pyi in #3581 which hardcodes the input type of _Writer.write to str

class _Writer(Protocol):
def write(self, s: str) -> Any: ...

If I understand correctly, as per the csv.writer docs , csvfile can be any object with a write() method, which means that things like io.BytesIO whose write accepts bytes-like object will fail typechecking

A minimal reproducer for this is as follows, and the type checking was done against mypy 0.770
and python 3.8.2

import csv
import io

buffer = io.BytesIO()
wrt = csv.writer(buffer)

And the output is

$ mypy --version
mypy 0.770

$ python --version
Python 3.8.2

$ mypy scratch.py 
scratch.py:5: error: Argument 1 to "writer" has incompatible type "BytesIO"; expected "_Writer"
scratch.py:5: note: Following member(s) of "BytesIO" have conflicts:
scratch.py:5: note:     Expected:
scratch.py:5: note:         def write(self, s: str) -> Any
scratch.py:5: note:     Got:
scratch.py:5: note:         def write(self, Union[bytes, bytearray]) -> int
Found 1 error in 1 file (checked 1 source file)

Also note that this worked in mypy 0.760

$ mypy --version
mypy 0.760

$ mypy scratch.py 
Success: no issues found in 1 source file
@deveshks deveshks changed the title "csv.writer.write" does not work for objects expecting something other than str in their write method "csv.writer.write" does not work for objects expecting something other than "str" in their "write" method May 15, 2020
@srittau
Copy link
Collaborator

srittau commented May 15, 2020

@deveshks You will notice that your example will fail as soon as you try to actually use the writer you just created:

import csv
import io

buffer = io.BytesIO()
wrt = csv.writer(buffer)
wrt.writerow([])  # TypeError

While using io.StringIO() works. I have used the csv module only casually though, so I might be misunderstanding how it's supposed to work.

@JelleZijlstra
Copy link
Member

Indeed the C code for csv always calls write() with a str argument: https://github.com/python/cpython/blob/6b6092f533f0e4787b8564c4fad6ec6d1018af0d/Modules/_csv.c#L1244

@deveshks
Copy link
Author

So given the facts that the mypy type checking not working is due to the code example which doesn't work as well, I will go ahead and close this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants