annotate Lib/csv/csv.py @ 28646:193b8aec00ce legacy-trunk

Changes from Jonathan Riehl to allow his pgen extension (PEP 269) to work. This includes some more code that used to be part of pgen in the main parser; I'm okay with that. I'll see if the Windows build needs work next.
author Guido van Rossum <guido@python.org>
date Thu, 17 Apr 2003 14:55:42 +0000
parents cc35ed2b26a8
children c9bee11eaa8b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
28339
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
1 from _csv import Error, __version__, writer, reader, register_dialect, \
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
2 unregister_dialect, get_dialect, list_dialects, \
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
3 QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, \
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
4 __doc__
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
5
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
6 __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE",
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
7 "Error", "Dialect", "excel", "excel_tab", "reader", "writer",
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
8 "register_dialect", "get_dialect", "list_dialects",
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
9 "unregister_dialect", "__version__", "DictReader", "DictWriter" ]
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
10
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
11 class Dialect:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
12 _name = ""
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
13 _valid = False
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
14 # placeholders
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
15 delimiter = None
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
16 quotechar = None
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
17 escapechar = None
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
18 doublequote = None
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
19 skipinitialspace = None
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
20 lineterminator = None
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
21 quoting = None
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
22
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
23 def __init__(self):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
24 if self.__class__ != Dialect:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
25 self._valid = True
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
26 errors = self._validate()
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
27 if errors != []:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
28 raise Error, "Dialect did not validate: %s" % ", ".join(errors)
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
29
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
30 def _validate(self):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
31 errors = []
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
32 if not self._valid:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
33 errors.append("can't directly instantiate Dialect class")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
34
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
35 if self.delimiter is None:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
36 errors.append("delimiter character not set")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
37 elif (not isinstance(self.delimiter, str) or
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
38 len(self.delimiter) > 1):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
39 errors.append("delimiter must be one-character string")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
40
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
41 if self.quotechar is None:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
42 if self.quoting != QUOTE_NONE:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
43 errors.append("quotechar not set")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
44 elif (not isinstance(self.quotechar, str) or
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
45 len(self.quotechar) > 1):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
46 errors.append("quotechar must be one-character string")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
47
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
48 if self.lineterminator is None:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
49 errors.append("lineterminator not set")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
50 elif not isinstance(self.lineterminator, str):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
51 errors.append("lineterminator must be a string")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
52
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
53 if self.doublequote not in (True, False):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
54 errors.append("doublequote parameter must be True or False")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
55
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
56 if self.skipinitialspace not in (True, False):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
57 errors.append("skipinitialspace parameter must be True or False")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
58
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
59 if self.quoting is None:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
60 errors.append("quoting parameter not set")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
61
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
62 if self.quoting is QUOTE_NONE:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
63 if (not isinstance(self.escapechar, (unicode, str)) or
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
64 len(self.escapechar) > 1):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
65 errors.append("escapechar must be a one-character string or unicode object")
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
66
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
67 return errors
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
68
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
69 class excel(Dialect):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
70 delimiter = ','
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
71 quotechar = '"'
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
72 doublequote = True
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
73 skipinitialspace = False
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
74 lineterminator = '\r\n'
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
75 quoting = QUOTE_MINIMAL
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
76 register_dialect("excel", excel)
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
77
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
78 class excel_tab(excel):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
79 delimiter = '\t'
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
80 register_dialect("excel-tab", excel_tab)
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
81
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
82
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
83 class DictReader:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
84 def __init__(self, f, fieldnames, restkey=None, restval=None,
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
85 dialect="excel", *args):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
86 self.fieldnames = fieldnames # list of keys for the dict
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
87 self.restkey = restkey # key to catch long rows
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
88 self.restval = restval # default value for short rows
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
89 self.reader = reader(f, dialect, *args)
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
90
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
91 def __iter__(self):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
92 return self
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
93
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
94 def next(self):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
95 row = self.reader.next()
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
96 # unlike the basic reader, we prefer not to return blanks,
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
97 # because we will typically wind up with a dict full of None
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
98 # values
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
99 while row == []:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
100 row = self.reader.next()
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
101 d = dict(zip(self.fieldnames, row))
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
102 lf = len(self.fieldnames)
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
103 lr = len(row)
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
104 if lf < lr:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
105 d[self.restkey] = row[lf:]
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
106 elif lf > lr:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
107 for key in self.fieldnames[lr:]:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
108 d[key] = self.restval
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
109 return d
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
110
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
111
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
112 class DictWriter:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
113 def __init__(self, f, fieldnames, restval="", extrasaction="raise",
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
114 dialect="excel", *args):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
115 self.fieldnames = fieldnames # list of keys for the dict
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
116 self.restval = restval # for writing short dicts
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
117 if extrasaction.lower() not in ("raise", "ignore"):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
118 raise ValueError, \
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
119 ("extrasaction (%s) must be 'raise' or 'ignore'" %
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
120 extrasaction)
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
121 self.extrasaction = extrasaction
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
122 self.writer = writer(f, dialect, *args)
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
123
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
124 def _dict_to_list(self, rowdict):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
125 if self.extrasaction == "raise":
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
126 for k in rowdict.keys():
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
127 if k not in self.fieldnames:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
128 raise ValueError, "dict contains fields not in fieldnames"
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
129 return [rowdict.get(key, self.restval) for key in self.fieldnames]
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
130
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
131 def writerow(self, rowdict):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
132 return self.writer.writerow(self._dict_to_list(rowdict))
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
133
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
134 def writerows(self, rowdicts):
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
135 rows = []
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
136 for rowdict in rowdicts:
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
137 rows.append(self._dict_to_list(rowdict))
cc35ed2b26a8 new CSV file processing module - see PEP 305
Skip Montanaro <skip@pobox.com>
parents:
diff changeset
138 return self.writer.writerows(rows)