Skip to content
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

gh-76728: Coerce DictReader and DictWriter fieldnames argument to a list #32225

Merged
merged 15 commits into from
Aug 25, 2022
8 changes: 6 additions & 2 deletions Doc/library/csv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ The :mod:`csv` module defines the following classes:
information in each row to a :class:`dict` whose keys are given by the
optional *fieldnames* parameter.

The *fieldnames* parameter is a :term:`sequence`. If *fieldnames* is
The *fieldnames* parameter is a :term:`sequence`. If the argument passed
to *fieldnames* is not a :term:`sequence` then a :exc:`TypeError` is
raised. If *fieldnames* is
dignissimus marked this conversation as resolved.
Show resolved Hide resolved
omitted, the values in the first row of file *f* will be used as the
fieldnames. Regardless of how the fieldnames are determined, the
dictionary preserves their original ordering.
Expand Down Expand Up @@ -195,7 +197,9 @@ The :mod:`csv` module defines the following classes:
onto output rows. The *fieldnames* parameter is a :mod:`sequence
<collections.abc>` of keys that identify the order in which values in the
dictionary passed to the :meth:`writerow` method are written to file
*f*. The optional *restval* parameter specifies the value to be
*f*. If the argument passed to *fieldnames* is not a
:mod:`sequence <collections.abc>`, a :exc:`TypeError` is raised. The optional
*restval* parameter specifies the value to be
dignissimus marked this conversation as resolved.
Show resolved Hide resolved
written if the dictionary is missing a key in *fieldnames*. If the
dictionary passed to the :meth:`writerow` method contains a key not found in
*fieldnames*, the optional *extrasaction* parameter indicates what action to
Expand Down
5 changes: 5 additions & 0 deletions Lib/csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, \
__doc__
from _csv import Dialect as _Dialect
from _collections_abc import Sequence

from io import StringIO

Expand Down Expand Up @@ -80,6 +81,8 @@ class unix_dialect(Dialect):
class DictReader:
def __init__(self, f, fieldnames=None, restkey=None, restval=None,
dialect="excel", *args, **kwds):
if not isinstance(fieldnames, Sequence):
raise TypeError("fieldnames must be a sequence")
dignissimus marked this conversation as resolved.
Show resolved Hide resolved
self._fieldnames = fieldnames # list of keys for the dict
self.restkey = restkey # key to catch long rows
self.restval = restval # default value for short rows
Expand Down Expand Up @@ -130,6 +133,8 @@ def __next__(self):
class DictWriter:
def __init__(self, f, fieldnames, restval="", extrasaction="raise",
dialect="excel", *args, **kwds):
if not isinstance(fieldnames, Sequence):
raise TypeError("fieldnames must be a sequence")
dignissimus marked this conversation as resolved.
Show resolved Hide resolved
self.fieldnames = fieldnames # list of keys for the dict
self.restval = restval # for writing short dicts
if extrasaction.lower() not in ("raise", "ignore"):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The constructors for csv.DictWriter and csv.DictReader raise TypeError when
the fieldnames argument is not a sequence.
dignissimus marked this conversation as resolved.
Show resolved Hide resolved