Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to type-annotate object returned by csv.writer?

Tags:

python

mypy

I want to apply type annotation to the returned object of csv.writer in order to comply with a larger codebase. Unfortunately I can not figure out the fitting return type.

>>> import csv
>>> writer = csv.writer(open('outfile.csv', 'w'))
>>> type(writer)
<class '_csv.writer'>

If I try to use this classname:

>>> import _csv
>>> writer: _csv.writer = csv.writer(open('outfile.csv', 'w'))

I get the following mypy error:

Invalid type "_csv.writer"

Does someone know which type to use in this case. Of course I could use typing.Any but this nullify the sense of a type annotation.

like image 908
MrLeeh Avatar asked Jul 10 '18 11:07

MrLeeh


People also ask

What is the return type of CSV reader?

Example 1: Read CSV files with csv. reader() is used to read the file, which returns an iterable reader object.

Which function is used to create a writer object in CSV?

writer() function is used to create a writer object. The writer. writerow() function is then used to write single rows to the CSV file.

How do I write a csv file in a list?

Steps for writing a CSV file First, open the CSV file for writing ( w mode) by using the open() function. Second, create a CSV writer object by calling the writer() function of the csv module. Third, write data to CSV file by calling the writerow() or writerows() method of the CSV writer object.


2 Answers

Often when things are acting weird it's a sign typeshed doesn't exactly map to runtime. If you look at _csv in typeshed you will see the type is named _writer. So you should can the annotation to _csv._writer.

like image 52
ethanhs Avatar answered Oct 29 '22 00:10

ethanhs


Short answer is there is no way to directly access the type. Reading the C source of the _csv module will show that the types of reader and writer are not exposed. Even in Pypy where the _csv module is implemented in Python, doesn't expose the types.

Therefore, if you need to use it, you will need to use a work-around, by instantiating a temporary instance of the writer and getting it's type.

import csv
# We'll need a temporary file-like object, so use a tempfile
from tempfile import TemporaryFile

with TemporaryFile() as t:
    CSVReader = type(csv.reader(t))
    CSVWriter = type(csv.writer(t))

w: CSVWriter = csv.writer('path/to/data.csv')

If you want keep this logic separate, I would suggest creating the types in a separate module

from csv_types import CSVReader, CSVWriter

The other solution (which also involves writing your own module of types), is to follow the example of the typing module in it's definition of types for io and re.

like image 39
Edward Minnix Avatar answered Oct 28 '22 23:10

Edward Minnix