8000 Merge pull request #5176 from Blues-star/csv · RustPython/RustPython@4c8cd67 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4c8cd67

Browse files
authored
Merge pull request #5176 from Blues-star/csv
Update csv.py and test_csv.py from CPython v3.12
2 parents d0c827e + 54247df commit 4c8cd67

File tree

3 files changed

+2395
-80
lines changed

3 files changed

+2395
-80
lines changed

Lib/csv.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@
44
"""
55

66
import re
7-
from _csv import Error, writer, reader, \
7+
import types
8+
from _csv import Error, __version__, writer, reader, register_dialect, \
9+
unregister_dialect, get_dialect, list_dialects, \
10+
field_size_limit, \
811
QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, \
12+
QUOTE_STRINGS, QUOTE_NOTNULL, \
913
__doc__
14+
from _csv import Dialect as _Dialect
1015

11-
from collections import OrderedDict
1216
from io import StringIO
1317

1418
__all__ = ["QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE",
19+
"QUOTE_STRINGS", "QUOTE_NOTNULL",
1520
"Error", "Dialect", "__doc__", "excel", "excel_tab",
1621
"field_size_limit", "reader", "writer",
17-
"Sniffer",
22+
"register_dialect", "get_dialect", "list_dialects", "Sniffer",
1823
"unregister_dialect", "__version__", "DictReader", "DictWriter",
1924
"unix_dialect"]
2025

@@ -57,10 +62,12 @@ class excel(Dialect):
5762
skipinitialspace = False
5863
lineterminator = '\r\n'
5964
quoting = QUOTE_MINIMAL
65+
register_dialect("excel", excel)
6066

6167
class excel_tab(excel):
6268
"""Describe the usual properties of Excel-generated TAB-delimited files."""
6369
delimiter = '\t'
70+
register_dialect("excel-tab", excel_tab)
6471

6572
class unix_dialect(Dialect):
6673
"""Describe the usual properties of Unix-generated CSV files."""
@@ -70,11 +77,14 @@ class unix_dialect(Dialect):
7077
skipinitialspace = False
7178
lineterminator = '\n'
7279
quoting = QUOTE_ALL
80+
register_dialect("unix", unix_dialect)
7381

7482

7583
class DictReader:
7684
def __init__(self, f, fieldnames=None, restkey=None, restval=None,
7785
dialect="excel", *args, **kwds):
86+
if fieldnames is not None and iter(fieldnames) is fieldnames:
87+
fieldnames = list(fieldnames)
7888
self._fieldnames = fieldnames # list of keys for the dict
7989
self.restkey = restkey # key to catch long rows
8090
self.restval = restval # default value for short rows
@@ -111,7 +121,7 @@ def __next__(self):
111121
# values
112122
while row == []:
113123
row = next(self.reader)
114-
d = OrderedDict(zip(self.fieldnames, row))
124+
d = dict(zip(self.fieldnames, row))
115125
lf = len(self.fieldnames)
116126
lr = len(row)
117127
if lf < lr:
@@ -121,21 +131,26 @@ def __next__(self):
121131
d[key] = self.restval
122132
return d
123133

134+
__class_getitem__ = classmethod(types.GenericAlias)
135+
124136

125137
class DictWriter:
126138
def __init__(self, f, fieldnames, restval="", extrasaction="raise",
127139
dialect="excel", *args, **kwds):
140+
if fieldnames is not None and iter(fieldnames) is fieldnames:
141+
fieldnames = list(fieldnames)
128142
self.fieldnames = fieldnames # list of keys for the dict
129143
self.restval = restval # for writing short dicts
130-
if extrasaction.lower() not in ("raise", "ignore"):
144+
extrasaction = extrasaction.lower()
145+
if extrasaction not in ("raise", "ignore"):
131146
raise ValueError("extrasaction (%s) must be 'raise' or 'ignore'"
132147
% extrasaction)
133148
self.extrasaction = extrasaction
134149
self.writer = writer(f, dialect, *args, **kwds)
135150

136151
def writeheader(self):
137152
header = dict(zip(self.fieldnames, self.fieldnames))
138-
self.writerow(header)
153+
return self.writerow(header)
139154

140155
def _dict_to_list(self, rowdict):
141156
if self.extrasaction == "raise":
@@ -151,11 +166,8 @@ def writerow(self, rowdict):
151166
def writerows(self, rowdicts):
152167
return self.writer.writerows(map(self._dict_to_list, rowdicts))
153168

154-
# Guard Sniffer's type checking against builds that exclude complex()
155-
try:
156-
complex
157-
except NameError:
158-
complex = float
169+
__class_getitem__ = classmethod(types.GenericAlias)
170+
159171

160172
class Sniffer:
161173
'''
@@ -404,14 +416,10 @@ def has_header(self, sample):
404416
continue # skip rows that have irregular number of columns
405417

406418
for col in list(columnTypes.keys()):
407-
408-
for thisType in [int, float, complex]:
409-
try:
410-
thisType(row[col])
411-
break
412-
except (ValueError, OverflowError):
413-
pass
414-
else:
419+
thisType = complex
420+
try:
421+
thisType(row[col])
422+
except (ValueError, OverflowError):
415423
# fallback to length of string
416424
thisType = len(row[col])
417425

@@ -427,7 +435,7 @@ def has_header(self, sample):
427435
# on whether it's a header
428436
hasHeader = 0
429437
for col, colType in columnTypes.items():
430-
if type(colType) == type(0): # it's a length
438+
if isinstance(colType, int): # it's a length
431439
if len(header[col]) != colType:
432440
hasHeader += 1
433441
else:

0 commit comments

Comments
 (0)
0