summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libpyexpat.tex20
-rw-r--r--Lib/test/test_pyexpat.py39
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/pyexpat.c14
4 files changed, 76 insertions, 0 deletions
diff --git a/Doc/lib/libpyexpat.tex b/Doc/lib/libpyexpat.tex
index 5b1c737..dd218c6 100644
--- a/Doc/lib/libpyexpat.tex
+++ b/Doc/lib/libpyexpat.tex
@@ -257,6 +257,26 @@ Column number at which an error occurred.
Line number at which an error occurred.
\end{memberdesc}
+The following attributes contain values relating to the current parse
+location in an \class{xmlparser} object. During a callback reporting
+a parse event they indicate the location of the first of the sequence
+of characters that generated the event. When called outside of a
+callback, the position indicated will be just past the last parse
+event (regardless of whether there was an associated callback).
+\versionadded{2.4}
+
+\begin{memberdesc}[xmlparser]{CurrentByteIndex}
+Current byte index in the parser input.
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{CurrentColumnNumber}
+Current column number in the parser input.
+\end{memberdesc}
+
+\begin{memberdesc}[xmlparser]{CurrentLineNumber}
+Current line number in the parser input.
+\end{memberdesc}
+
Here is the list of handlers that can be set. To set a handler on an
\class{xmlparser} object \var{o}, use
\code{\var{o}.\var{handlername} = \var{func}}. \var{handlername} must
diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py
index 44f9ee8..a9a5e8f 100644
--- a/Lib/test/test_pyexpat.py
+++ b/Lib/test/test_pyexpat.py
@@ -326,3 +326,42 @@ except RuntimeError, e:
print "Expected RuntimeError for element 'a'; found %r" % e.args[0]
else:
print "Expected RuntimeError for 'a'"
+
+# Test Current* members:
+class PositionTest:
+
+ def __init__(self, expected_list, parser):
+ self.parser = parser
+ self.parser.StartElementHandler = self.StartElementHandler
+ self.parser.EndElementHandler = self.EndElementHandler
+ self.expected_list = expected_list
+ self.upto = 0
+
+ def StartElementHandler(self, name, attrs):
+ self.check_pos('s')
+
+ def EndElementHandler(self, name):
+ self.check_pos('e')
+
+ def check_pos(self, event):
+ pos = (event,
+ self.parser.CurrentByteIndex,
+ self.parser.CurrentLineNumber,
+ self.parser.CurrentColumnNumber)
+ require(self.upto < len(self.expected_list),
+ 'too many parser events')
+ expected = self.expected_list[self.upto]
+ require(pos == expected,
+ 'expected position %s, got %s' % (expected, pos))
+ self.upto += 1
+
+
+parser = expat.ParserCreate()
+handler = PositionTest([('s', 0, 1, 0), ('s', 5, 2, 1), ('s', 11, 3, 2),
+ ('e', 15, 3, 6), ('e', 17, 4, 1), ('e', 22, 5, 0)],
+ parser)
+parser.Parse('''<a>
+ <b>
+ <c/>
+ </b>
+</a>''', 1)
diff --git a/Misc/NEWS b/Misc/NEWS
index cb49e0b..fd5ba68 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -54,6 +54,9 @@ Extension modules
- Added socket.socketpair().
+- Added CurrentByteIndex, CurrentColumnNumber, CurrentLineNumber
+ members to xml.parsers.expat.XMLParser object.
+
Library
-------
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index 3bee0ac..d5929b6 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -1455,6 +1455,17 @@ xmlparse_getattr(xmlparseobject *self, char *name)
return PyInt_FromLong((long)
XML_GetErrorByteIndex(self->itself));
}
+ if (name[0] == 'C') {
+ if (strcmp(name, "CurrentLineNumber") == 0)
+ return PyInt_FromLong((long)
+ XML_GetCurrentLineNumber(self->itself));
+ if (strcmp(name, "CurrentColumnNumber") == 0)
+ return PyInt_FromLong((long)
+ XML_GetCurrentColumnNumber(self->itself));
+ if (strcmp(name, "CurrentByteIndex") == 0)
+ return PyInt_FromLong((long)
+ XML_GetCurrentByteIndex(self->itself));
+ }
if (name[0] == 'b') {
if (strcmp(name, "buffer_size") == 0)
return PyInt_FromLong((long) self->buffer_size);
@@ -1503,6 +1514,9 @@ xmlparse_getattr(xmlparseobject *self, char *name)
APPEND(rc, "ErrorLineNumber");
APPEND(rc, "ErrorColumnNumber");
APPEND(rc, "ErrorByteIndex");
+ APPEND(rc, "CurrentLineNumber");
+ APPEND(rc, "CurrentColumnNumber");
+ APPEND(rc, "CurrentByteIndex");
APPEND(rc, "buffer_size");
APPEND(rc, "buffer_text");
APPEND(rc, "buffer_used");