summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorent Xicluna <florent.xicluna@gmail.com>2012-02-11 10:28:16 (GMT)
committerFlorent Xicluna <florent.xicluna@gmail.com>2012-02-11 10:28:16 (GMT)
commitf4bdf4e478adc3f7c0ec54e60bb3359f51058722 (patch)
tree90798a7497fa0f406fe6885b7b8c9950a890790b
parent44fb613816f2e0e9fc4388ef80603fa9ae35de4f (diff)
downloadcpython-f4bdf4e478adc3f7c0ec54e60bb3359f51058722.zip
cpython-f4bdf4e478adc3f7c0ec54e60bb3359f51058722.tar.gz
cpython-f4bdf4e478adc3f7c0ec54e60bb3359f51058722.tar.bz2
Issue #13988: move the python bootstrap code to cElementTree.py, and remove obsolete code for Python 2.4 and 2.5.
-rw-r--r--Lib/xml/etree/cElementTree.py150
-rw-r--r--Modules/_elementtree.c234
2 files changed, 152 insertions, 232 deletions
diff --git a/Lib/xml/etree/cElementTree.py b/Lib/xml/etree/cElementTree.py
index a6f127a..aaef59e 100644
--- a/Lib/xml/etree/cElementTree.py
+++ b/Lib/xml/etree/cElementTree.py
@@ -1,3 +1,153 @@
# Wrapper module for _elementtree
+from xml.etree.ElementTree import (ElementTree, dump, iselement, QName,
+ fromstringlist,
+ tostring, tostringlist, VERSION)
+# These ones are not in ElementTree.__all__
+from xml.etree.ElementTree import ElementPath, register_namespace
+
+# Import the C accelerators:
+# Element, SubElement, TreeBuilder, XMLParser, ParseError
from _elementtree import *
+
+
+class ElementTree(ElementTree):
+
+ def parse(self, source, parser=None):
+ close_source = False
+ if not hasattr(source, 'read'):
+ source = open(source, 'rb')
+ close_source = True
+ try:
+ if parser is not None:
+ while True:
+ data = source.read(65536)
+ if not data:
+ break
+ parser.feed(data)
+ self._root = parser.close()
+ else:
+ parser = XMLParser()
+ self._root = parser._parse(source)
+ return self._root
+ finally:
+ if close_source:
+ source.close()
+
+
+class iterparse:
+ root = None
+
+ def __init__(self, file, events=None):
+ self._close_file = False
+ if not hasattr(file, 'read'):
+ file = open(file, 'rb')
+ self._close_file = True
+ self._file = file
+ self._events = []
+ self._index = 0
+ self._error = None
+ self.root = self._root = None
+ b = TreeBuilder()
+ self._parser = XMLParser(b)
+ self._parser._setevents(self._events, events)
+
+ def __next__(self):
+ while True:
+ try:
+ item = self._events[self._index]
+ self._index += 1
+ return item
+ except IndexError:
+ pass
+ if self._error:
+ e = self._error
+ self._error = None
+ raise e
+ if self._parser is None:
+ self.root = self._root
+ if self._close_file:
+ self._file.close()
+ raise StopIteration
+ # load event buffer
+ del self._events[:]
+ self._index = 0
+ data = self._file.read(16384)
+ if data:
+ try:
+ self._parser.feed(data)
+ except SyntaxError as exc:
+ self._error = exc
+ else:
+ self._root = self._parser.close()
+ self._parser = None
+
+ def __iter__(self):
+ return self
+
+
+# =============================================================================
+#
+# Everything below this line can be removed
+# after cElementTree is folded behind ElementTree.
+#
+# =============================================================================
+
+from xml.etree.ElementTree import Comment as _Comment, PI as _PI
+
+
+def parse(source, parser=None):
+ tree = ElementTree()
+ tree.parse(source, parser)
+ return tree
+
+
+def XML(text, parser=None):
+ if not parser:
+ parser = XMLParser()
+ parser = XMLParser()
+ parser.feed(text)
+ return parser.close()
+
+
+def XMLID(text, parser=None):
+ tree = XML(text, parser=parser)
+ ids = {}
+ for elem in tree.iter():
+ id = elem.get('id')
+ if id:
+ ids[id] = elem
+ return tree, ids
+
+
+class CommentProxy:
+
+ def __call__(self, text=None):
+ element = Element(_Comment)
+ element.text = text
+ return element
+
+ def __eq__(self, other):
+ return _Comment == other
+
+
+class PIProxy:
+
+ def __call__(self, target, text=None):
+ element = Element(_PI)
+ element.text = target
+ if text:
+ element.text = element.text + ' ' + text
+ return element
+
+ def __eq__(self, other):
+ return _PI == other
+
+
+Comment = CommentProxy()
+PI = ProcessingInstruction = PIProxy()
+del CommentProxy, PIProxy
+
+# Aliases
+fromstring = XML
+XMLTreeBuilder = XMLParser
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 884e50d..af7661e 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -94,25 +94,6 @@ do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0)
#define LOCAL(type) static type
#endif
-/* compatibility macros */
-#if (PY_VERSION_HEX < 0x02060000)
-#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
-#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-#endif
-
-#if (PY_VERSION_HEX < 0x02050000)
-typedef int Py_ssize_t;
-#define lenfunc inquiry
-#endif
-
-#if (PY_VERSION_HEX < 0x02040000)
-#define PyDict_CheckExact PyDict_Check
-
-#if !defined(Py_RETURN_NONE)
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-#endif
-
/* macros used to store 'join' flags in string object pointers. note
that all use of text and tail as object pointers must be wrapped in
JOIN_OBJ. see comments in the ElementObject definition for more
@@ -123,7 +104,6 @@ typedef int Py_ssize_t;
/* glue functions (see the init function for details) */
static PyObject* elementtree_parseerror_obj;
-static PyObject* elementtree_copyelement_obj;
static PyObject* elementtree_deepcopy_obj;
static PyObject* elementtree_iter_obj;
static PyObject* elementtree_itertext_obj;
@@ -1128,31 +1108,6 @@ element_makeelement(PyObject* self, PyObject* args, PyObject* kw)
}
static PyObject*
-element_reduce(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":__reduce__"))
- return NULL;
-
- /* Hack alert: This method is used to work around a __copy__
- problem on certain 2.3 and 2.4 versions. To save time and
- simplify the code, we create the copy in here, and use a dummy
- copyelement helper to trick the copy module into doing the
- right thing. */
-
- if (!elementtree_copyelement_obj) {
- PyErr_SetString(
- PyExc_RuntimeError,
- "copyelement helper not found"
- );
- return NULL;
- }
-
- return Py_BuildValue(
- "O(N)", elementtree_copyelement_obj, element_copy(self, args)
- );
-}
-
-static PyObject*
element_remove(ElementObject* self, PyObject* args)
{
int i;
@@ -1260,13 +1215,8 @@ element_subscr(PyObject* self_, PyObject* item)
{
ElementObject* self = (ElementObject*) self_;
-#if (PY_VERSION_HEX < 0x02050000)
- if (PyInt_Check(item) || PyLong_Check(item)) {
- long i = PyInt_AsLong(item);
-#else
if (PyIndex_Check(item)) {
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
-#endif
if (i == -1 && PyErr_Occurred()) {
return NULL;
@@ -1317,13 +1267,8 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
{
ElementObject* self = (ElementObject*) self_;
-#if (PY_VERSION_HEX < 0x02050000)
- if (PyInt_Check(item) || PyLong_Check(item)) {
- long i = PyInt_AsLong(item);
-#else
if (PyIndex_Check(item)) {
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
-#endif
if (i == -1 && PyErr_Occurred()) {
return -1;
@@ -1364,13 +1309,8 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
if (step != 1 && newlen != slicelen)
{
PyErr_Format(PyExc_ValueError,
-#if (PY_VERSION_HEX < 0x02050000)
- "attempt to assign sequence of size %d "
- "to extended slice of size %d",
-#else
"attempt to assign sequence of size %zd "
"to extended slice of size %zd",
-#endif
newlen, slicelen
);
return -1;
@@ -1470,18 +1410,6 @@ static PyMethodDef element_methods[] = {
{"__copy__", (PyCFunction) element_copy, METH_VARARGS},
{"__deepcopy__", (PyCFunction) element_deepcopy, METH_VARARGS},
- /* Some 2.3 and 2.4 versions do not handle the __copy__ method on
- C objects correctly, so we have to fake it using a __reduce__-
- based hack (see the element_reduce implementation above for
- details). */
-
- /* The behaviour has been changed in 2.3.5 and 2.4.1, so we're
- using a runtime test to figure out if we need to fake things
- or now (see the init code below). The following entry is
- enabled only if the hack is needed. */
-
- {"!__reduce__", (PyCFunction) element_reduce, METH_VARARGS},
-
{NULL, NULL}
};
@@ -2878,7 +2806,6 @@ static PyMethodDef _functions[] = {
{"TreeBuilder", (PyCFunction) treebuilder, METH_VARARGS},
#if defined(USE_EXPAT)
{"XMLParser", (PyCFunction) xmlparser, METH_VARARGS|METH_KEYWORDS},
- {"XMLTreeBuilder", (PyCFunction) xmlparser, METH_VARARGS|METH_KEYWORDS},
#endif
{NULL, NULL}
};
@@ -2933,54 +2860,8 @@ PyInit__elementtree(void)
bootstrap = (
- "from copy import copy, deepcopy\n"
-
- "try:\n"
- " from xml.etree import ElementTree\n"
- "except ImportError:\n"
- " import ElementTree\n"
- "ET = ElementTree\n"
- "del ElementTree\n"
-
- "import _elementtree as cElementTree\n"
-
- "try:\n" /* check if copy works as is */
- " copy(cElementTree.Element('x'))\n"
- "except:\n"
- " def copyelement(elem):\n"
- " return elem\n"
-
- "class CommentProxy:\n"
- " def __call__(self, text=None):\n"
- " element = cElementTree.Element(ET.Comment)\n"
- " element.text = text\n"
- " return element\n"
- " def __eq__(self, other):\n"
- " return ET.Comment == other\n"
- "cElementTree.Comment = CommentProxy()\n"
-
- "class ElementTree(ET.ElementTree):\n" /* public */
- " def parse(self, source, parser=None):\n"
- " close_source = False\n"
- " if not hasattr(source, 'read'):\n"
- " source = open(source, 'rb')\n"
- " close_source = True\n"
- " try:\n"
- " if parser is not None:\n"
- " while 1:\n"
- " data = source.read(65536)\n"
- " if not data:\n"
- " break\n"
- " parser.feed(data)\n"
- " self._root = parser.close()\n"
- " else:\n"
- " parser = cElementTree.XMLParser()\n"
- " self._root = parser._parse(source)\n"
- " return self._root\n"
- " finally:\n"
- " if close_source:\n"
- " source.close()\n"
- "cElementTree.ElementTree = ElementTree\n"
+ "from copy import deepcopy\n"
+ "from xml.etree import ElementPath\n"
"def iter(node, tag=None):\n" /* helper */
" if tag == '*':\n"
@@ -3000,123 +2881,12 @@ PyInit__elementtree(void)
" if e.tail:\n"
" yield e.tail\n"
- "def parse(source, parser=None):\n" /* public */
- " tree = ElementTree()\n"
- " tree.parse(source, parser)\n"
- " return tree\n"
- "cElementTree.parse = parse\n"
-
- "class iterparse:\n"
- " root = None\n"
- " def __init__(self, file, events=None):\n"
- " self._close_file = False\n"
- " if not hasattr(file, 'read'):\n"
- " file = open(file, 'rb')\n"
- " self._close_file = True\n"
- " self._file = file\n"
- " self._events = []\n"
- " self._index = 0\n"
- " self._error = None\n"
- " self.root = self._root = None\n"
- " b = cElementTree.TreeBuilder()\n"
- " self._parser = cElementTree.XMLParser(b)\n"
- " self._parser._setevents(self._events, events)\n"
- " def __next__(self):\n"
- " while 1:\n"
- " try:\n"
- " item = self._events[self._index]\n"
- " self._index += 1\n"
- " return item\n"
- " except IndexError:\n"
- " pass\n"
- " if self._error:\n"
- " e = self._error\n"
- " self._error = None\n"
- " raise e\n"
- " if self._parser is None:\n"
- " self.root = self._root\n"
- " if self._close_file:\n"
- " self._file.close()\n"
- " raise StopIteration\n"
- " # load event buffer\n"
- " del self._events[:]\n"
- " self._index = 0\n"
- " data = self._file.read(16384)\n"
- " if data:\n"
- " try:\n"
- " self._parser.feed(data)\n"
- " except SyntaxError as exc:\n"
- " self._error = exc\n"
- " else:\n"
- " self._root = self._parser.close()\n"
- " self._parser = None\n"
- " def __iter__(self):\n"
- " return self\n"
- "cElementTree.iterparse = iterparse\n"
-
- "class PIProxy:\n"
- " def __call__(self, target, text=None):\n"
- " element = cElementTree.Element(ET.PI)\n"
- " element.text = target\n"
- " if text:\n"
- " element.text = element.text + ' ' + text\n"
- " return element\n"
- " def __eq__(self, other):\n"
- " return ET.PI == other\n"
- "cElementTree.PI = cElementTree.ProcessingInstruction = PIProxy()\n"
-
- "def XML(text):\n" /* public */
- " parser = cElementTree.XMLParser()\n"
- " parser.feed(text)\n"
- " return parser.close()\n"
- "cElementTree.XML = cElementTree.fromstring = XML\n"
-
- "def XMLID(text):\n" /* public */
- " tree = XML(text)\n"
- " ids = {}\n"
- " for elem in tree.iter():\n"
- " id = elem.get('id')\n"
- " if id:\n"
- " ids[id] = elem\n"
- " return tree, ids\n"
- "cElementTree.XMLID = XMLID\n"
-
- "try:\n"
- " register_namespace = ET.register_namespace\n"
- "except AttributeError:\n"
- " def register_namespace(prefix, uri):\n"
- " ET._namespace_map[uri] = prefix\n"
- "cElementTree.register_namespace = register_namespace\n"
-
- "cElementTree.dump = ET.dump\n"
- "cElementTree.ElementPath = ElementPath = ET.ElementPath\n"
- "cElementTree.iselement = ET.iselement\n"
- "cElementTree.QName = ET.QName\n"
- "cElementTree.tostring = ET.tostring\n"
- "cElementTree.fromstringlist = ET.fromstringlist\n"
- "cElementTree.tostringlist = ET.tostringlist\n"
- "cElementTree.VERSION = '" VERSION "'\n"
- "cElementTree.__version__ = '" VERSION "'\n"
-
);
if (!PyRun_String(bootstrap, Py_file_input, g, NULL))
return NULL;
elementpath_obj = PyDict_GetItemString(g, "ElementPath");
-
- elementtree_copyelement_obj = PyDict_GetItemString(g, "copyelement");
- if (elementtree_copyelement_obj) {
- /* reduce hack needed; enable reduce method */
- PyMethodDef* mp;
- for (mp = element_methods; mp->ml_name; mp++)
- if (mp->ml_meth == (PyCFunction) element_reduce) {
- mp->ml_name = "__reduce__";
- break;
- }
- } else
- PyErr_Clear();
-
elementtree_deepcopy_obj = PyDict_GetItemString(g, "deepcopy");
elementtree_iter_obj = PyDict_GetItemString(g, "iter");
elementtree_itertext_obj = PyDict_GetItemString(g, "itertext");