Add counting of source iterator lines to the reader object - handy for

user error messages (otherwise difficult to do without instrumenting
the source).
This commit is contained in:
Andrew McNamara 2005-01-12 11:17:16 +00:00
parent 0f0599ddc1
commit 7f2053eff3
3 changed files with 21 additions and 1 deletions

View File

@ -242,7 +242,7 @@ class Test_Csv(unittest.TestCase):
self._read_test(['1,",3,",5'], [['1', '"', '3', '"', '5']], self._read_test(['1,",3,",5'], [['1', '"', '3', '"', '5']],
quoting=csv.QUOTE_NONE, escapechar='\\') quoting=csv.QUOTE_NONE, escapechar='\\')
# will this fail where locale uses comma for decimals? # will this fail where locale uses comma for decimals?
self._read_test([',3,"5",7.3'], [['', 3, '5', 7.3]], self._read_test([',3,"5",7.3, 9'], [['', 3, '5', 7.3, 9]],
quoting=csv.QUOTE_NONNUMERIC) quoting=csv.QUOTE_NONNUMERIC)
self.assertRaises(ValueError, self._read_test, self.assertRaises(ValueError, self._read_test,
['abc,3'], [[]], ['abc,3'], [[]],
@ -267,6 +267,18 @@ class Test_Csv(unittest.TestCase):
finally: finally:
csv.field_size_limit(limit) csv.field_size_limit(limit)
def test_read_linenum(self):
r = csv.reader(['line,1', 'line,2', 'line,3'])
self.assertEqual(r.line_num, 0)
r.next()
self.assertEqual(r.line_num, 1)
r.next()
self.assertEqual(r.line_num, 2)
r.next()
self.assertEqual(r.line_num, 3)
self.assertRaises(StopIteration, r.next)
self.assertEqual(r.line_num, 3)
class TestDialectRegistry(unittest.TestCase): class TestDialectRegistry(unittest.TestCase):
def test_registry_badargs(self): def test_registry_badargs(self):
self.assertRaises(TypeError, csv.list_dialects, None) self.assertRaises(TypeError, csv.list_dialects, None)

View File

@ -66,6 +66,10 @@ Library
+ A new module method csv.field_size_limit() has been added that sets + A new module method csv.field_size_limit() has been added that sets
the parser field size limit (returning the former limit). The initial the parser field size limit (returning the former limit). The initial
limit is 128kB. limit is 128kB.
+ A line_num attribute has been added to the reader object, which tracks
the number of lines read from the source iterator. This is not
the same as the number of records returned, as records can span
multiple lines.
+ reader and writer objects were not being registered with the cyclic-GC. + reader and writer objects were not being registered with the cyclic-GC.
This has been fixed. This has been fixed.

View File

@ -98,6 +98,7 @@ typedef struct {
int field_len; /* length of current field */ int field_len; /* length of current field */
int had_parse_error; /* did we have a parse error? */ int had_parse_error; /* did we have a parse error? */
int numeric_field; /* treat field as numeric */ int numeric_field; /* treat field as numeric */
unsigned long line_num; /* Source-file line number */
} ReaderObj; } ReaderObj;
staticforward PyTypeObject Reader_Type; staticforward PyTypeObject Reader_Type;
@ -734,6 +735,7 @@ parse_process_char(ReaderObj *self, char c)
static struct PyMemberDef Reader_memberlist[] = { static struct PyMemberDef Reader_memberlist[] = {
{ "dialect", T_OBJECT, R_OFF(dialect), RO }, { "dialect", T_OBJECT, R_OFF(dialect), RO },
{ "line_num", T_ULONG, R_OFF(line_num), RO },
{ NULL } { NULL }
}; };
@ -753,6 +755,7 @@ Reader_iternext(ReaderObj *self)
"newline inside string"); "newline inside string");
return NULL; return NULL;
} }
++self->line_num;
if (self->had_parse_error) if (self->had_parse_error)
if (parse_reset(self) < 0) { if (parse_reset(self) < 0) {
@ -924,6 +927,7 @@ csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
self->input_iter = NULL; self->input_iter = NULL;
self->field = NULL; self->field = NULL;
self->field_size = 0; self->field_size = 0;
self->line_num = 0;
if (parse_reset(self) < 0) { if (parse_reset(self) < 0) {
Py_DECREF(self); Py_DECREF(self);