Skip to content

Commit 1cf4740

Browse files
author
andrewmcnamara
committed
Add counting of source iterator lines to the reader object - handy for
user error messages (otherwise difficult to do without instrumenting the source). git-svn-id: http://svn.python.org/projects/python/trunk@38282 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent f87e550 commit 1cf4740

3 files changed

Lines changed: 21 additions & 1 deletion

File tree

Lib/test/test_csv.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def test_read_quoting(self):
242242
self._read_test(['1,",3,",5'], [['1', '"', '3', '"', '5']],
243243
quoting=csv.QUOTE_NONE, escapechar='\\')
244244
# will this fail where locale uses comma for decimals?
245-
self._read_test([',3,"5",7.3'], [['', 3, '5', 7.3]],
245+
self._read_test([',3,"5",7.3, 9'], [['', 3, '5', 7.3, 9]],
246246
quoting=csv.QUOTE_NONNUMERIC)
247247
self.assertRaises(ValueError, self._read_test,
248248
['abc,3'], [[]],
@@ -267,6 +267,18 @@ def test_read_bigfield(self):
267267
finally:
268268
csv.field_size_limit(limit)
269269

270+
def test_read_linenum(self):
271+
r = csv.reader(['line,1', 'line,2', 'line,3'])
272+
self.assertEqual(r.line_num, 0)
273+
r.next()
274+
self.assertEqual(r.line_num, 1)
275+
r.next()
276+
self.assertEqual(r.line_num, 2)
277+
r.next()
278+
self.assertEqual(r.line_num, 3)
279+
self.assertRaises(StopIteration, r.next)
280+
self.assertEqual(r.line_num, 3)
281+
270282
class TestDialectRegistry(unittest.TestCase):
271283
def test_registry_badargs(self):
272284
self.assertRaises(TypeError, csv.list_dialects, None)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ Library
6666
+ A new module method csv.field_size_limit() has been added that sets
6767
the parser field size limit (returning the former limit). The initial
6868
limit is 128kB.
69+
+ A line_num attribute has been added to the reader object, which tracks
70+
the number of lines read from the source iterator. This is not
71+
the same as the number of records returned, as records can span
72+
multiple lines.
6973
+ reader and writer objects were not being registered with the cyclic-GC.
7074
This has been fixed.
7175

Modules/_csv.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ typedef struct {
9898
int field_len; /* length of current field */
9999
int had_parse_error; /* did we have a parse error? */
100100
int numeric_field; /* treat field as numeric */
101+
unsigned long line_num; /* Source-file line number */
101102
} ReaderObj;
102103

103104
staticforward PyTypeObject Reader_Type;
@@ -734,6 +735,7 @@ parse_process_char(ReaderObj *self, char c)
734735

735736
static struct PyMemberDef Reader_memberlist[] = {
736737
{ "dialect", T_OBJECT, R_OFF(dialect), RO },
738+
{ "line_num", T_ULONG, R_OFF(line_num), RO },
737739
{ NULL }
738740
};
739741

@@ -753,6 +755,7 @@ Reader_iternext(ReaderObj *self)
753755
"newline inside string");
754756
return NULL;
755757
}
758+
++self->line_num;
756759

757760
if (self->had_parse_error)
758761
if (parse_reset(self) < 0) {
@@ -924,6 +927,7 @@ csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
924927
self->input_iter = NULL;
925928
self->field = NULL;
926929
self->field_size = 0;
930+
self->line_num = 0;
927931

928932
if (parse_reset(self) < 0) {
929933
Py_DECREF(self);

0 commit comments

Comments
 (0)