8000 gh-67230: add quoting rules to csv module by smontanaro · Pull Request #29469 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-67230: add quoting rules to csv module #29469

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

Merged
merged 20 commits into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
bpo-23041: update proposed changes to csv module.
  • Loading branch information
smontanaro committed Nov 8, 2021
commit 7e92373cbba32aea398196b5287ce77193463707
12 changes: 12 additions & 0 deletions Doc/library/csv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,18 @@ The :mod:`csv` module defines the following constants:

Instructs :class:`reader` to perform no special processing of quote characters.

.. data:: QUOTE_NOTNULL

Instructs :class:`writer` objects to quote all fields which are not
``None``. If a field value is ``None`` an empty (unquoted) string
is written.

.. data:: QUOTE_STRINGS

Instructs :class:`writer` quotes are always placed around fields
which are strings. Note that ``None`` will be written as a
bar (unquoted) empty string.

The :mod:`csv` module defines the following exception:


Expand Down
2 changes: 2 additions & 0 deletions Lib/csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
unregister_dialect, get_dialect, list_dialects, \
field_size_limit, \
QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, \
QUOTE_STRINGS, QUOTE_NOTNULL, \
__doc__
from _csv import Dialect as _Dialect

from io import StringIO

__all__ = ["QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE",
"QUOTE_STRINGS", "QUOTE_NOTNULL",
"Error", "Dialect", "__doc__", "excel", "excel_tab",
"field_size_limit", "reader", "writer",
"register_dialect", "get_dialect", "list_dialects", "Sniffer",
Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ def test_write_quoting(self):
quoting = csv.QUOTE_ALL)
self._write_test(['a\nb',1], '"a\nb","1"',
quoting = csv.QUOTE_ALL)
self._write_test(['a',None,1], '"a",,1',
quoting = csv.QUOTE_STRINGS)
self._write_test(['a',None,1], '"a",,"1"',
quoting = csv.QUOTE_NOTNULL)

def test_write_escape(self):
self._write_test(['a',1,'p,q'], 'a,1,"p,q"',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add QUOTE_STRINGS and QUOTE_NOTNULL to the suite of csv module quoting
styles.
16 changes: 15 additions & 1 deletion Modules/_csv.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ typedef enum {
} ParserState;

typedef enum {
QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE,
QUOTE_STRINGS, QUOTE_NOTNULL
} QuoteStyle;

typedef struct {
Expand All @@ -87,6 +88,8 @@ static const StyleDesc quote_styles[] = {
{ QUOTE_ALL, "QUOTE_ALL" },
{ QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
{ QUOTE_NONE, "QUOTE_NONE" },
{ QUOTE_STRINGS, "QUOTE_STRINGS" },
{ QUOTE_NOTNULL, "QUOTE_NOTNULL" },
{ 0 }
};

Expand Down Expand Up @@ -1259,6 +1262,12 @@ csv_writerow(WriterObj *self, PyObject *seq)
case QUOTE_ALL:
quoted = 1;
break;
case QUOTE_STRINGS:
quoted = PyUnicode_Check(field);
break;
case QUOTE_NOTNULL:
quoted = field != Py_None;
break;
default:
quoted = 0;
break;
Expand Down Expand Up @@ -1610,6 +1619,11 @@ PyDoc_STRVAR(csv_module_doc,
" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
" fields which do not parse as integers or floating point\n"
" numbers.\n"
" csv.QUOTE_STRINGS means that quotes are always placed around\n"
" fields which are strings. Note that the Python value None\n"
" is not a string.\n"
" csv.QUOTE_NOTNULL means that quotes are only placed around fields\n"
" that are not the Python value None.\n"
" csv.QUOTE_NONE means that quotes are never placed around fields.\n"
" * escapechar - specifies a one-character string used to escape\n"
" the delimiter when quoting is set to QUOTE_NONE.\n"
Expand Down
0