summaryrefslogtreecommitdiffstats
path: root/Lib/xml/dom
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/xml/dom')
-rw-r--r--Lib/xml/dom/NodeFilter.py2
-rw-r--r--Lib/xml/dom/__init__.py2
-rw-r--r--Lib/xml/dom/domreg.py10
-rw-r--r--Lib/xml/dom/expatbuilder.py12
-rw-r--r--Lib/xml/dom/minicompat.py9
-rw-r--r--Lib/xml/dom/minidom.py91
-rw-r--r--Lib/xml/dom/pulldom.py17
-rw-r--r--Lib/xml/dom/xmlbuilder.py14
8 files changed, 86 insertions, 71 deletions
diff --git a/Lib/xml/dom/NodeFilter.py b/Lib/xml/dom/NodeFilter.py
index fc05245..640e0bf 100644
--- a/Lib/xml/dom/NodeFilter.py
+++ b/Lib/xml/dom/NodeFilter.py
@@ -9,7 +9,7 @@ class NodeFilter:
FILTER_REJECT = 2
FILTER_SKIP = 3
- SHOW_ALL = 0xFFFFFFFFL
+ SHOW_ALL = 0xFFFFFFFF
SHOW_ELEMENT = 0x00000001
SHOW_ATTRIBUTE = 0x00000002
SHOW_TEXT = 0x00000004
diff --git a/Lib/xml/dom/__init__.py b/Lib/xml/dom/__init__.py
index 6363d00..4401bdf 100644
--- a/Lib/xml/dom/__init__.py
+++ b/Lib/xml/dom/__init__.py
@@ -136,4 +136,4 @@ XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml"
EMPTY_NAMESPACE = None
EMPTY_PREFIX = None
-from domreg import getDOMImplementation,registerDOMImplementation
+from .domreg import getDOMImplementation, registerDOMImplementation
diff --git a/Lib/xml/dom/domreg.py b/Lib/xml/dom/domreg.py
index ec3acdf..cb35bb0 100644
--- a/Lib/xml/dom/domreg.py
+++ b/Lib/xml/dom/domreg.py
@@ -36,7 +36,7 @@ def _good_enough(dom, features):
return 0
return 1
-def getDOMImplementation(name = None, features = ()):
+def getDOMImplementation(name=None, features=()):
"""getDOMImplementation(name = None, features = ()) -> DOM implementation.
Return a suitable DOM implementation. The name is either
@@ -62,7 +62,7 @@ def getDOMImplementation(name = None, features = ()):
# User did not specify a name, try implementations in arbitrary
# order, returning the one that has the required features
- if isinstance(features, StringTypes):
+ if isinstance(features, str):
features = _parse_feature_string(features)
for creator in registered.values():
dom = creator()
@@ -72,12 +72,12 @@ def getDOMImplementation(name = None, features = ()):
for creator in well_known_implementations.keys():
try:
dom = getDOMImplementation(name = creator)
- except StandardError: # typically ImportError, or AttributeError
+ except Exception: # typically ImportError, or AttributeError
continue
if _good_enough(dom, features):
return dom
- raise ImportError,"no suitable DOM implementation found"
+ raise ImportError("no suitable DOM implementation found")
def _parse_feature_string(s):
features = []
@@ -87,7 +87,7 @@ def _parse_feature_string(s):
while i < length:
feature = parts[i]
if feature[0] in "0123456789":
- raise ValueError, "bad feature name: %r" % (feature,)
+ raise ValueError("bad feature name: %r" % (feature,))
i = i + 1
version = None
if i < length:
diff --git a/Lib/xml/dom/expatbuilder.py b/Lib/xml/dom/expatbuilder.py
index 4fba875..a98fe03 100644
--- a/Lib/xml/dom/expatbuilder.py
+++ b/Lib/xml/dom/expatbuilder.py
@@ -476,8 +476,8 @@ class FilterVisibilityController(object):
if val == FILTER_INTERRUPT:
raise ParseEscape
if val not in _ALLOWED_FILTER_RETURNS:
- raise ValueError, \
- "startContainer() returned illegal value: " + repr(val)
+ raise ValueError(
+ "startContainer() returned illegal value: " + repr(val))
return val
else:
return FILTER_ACCEPT
@@ -496,8 +496,8 @@ class FilterVisibilityController(object):
# node is handled by the caller
return FILTER_REJECT
if val not in _ALLOWED_FILTER_RETURNS:
- raise ValueError, \
- "acceptNode() returned illegal value: " + repr(val)
+ raise ValueError(
+ "acceptNode() returned illegal value: " + repr(val))
return val
else:
return FILTER_ACCEPT
@@ -918,7 +918,7 @@ def parse(file, namespaces=True):
else:
builder = ExpatBuilder()
- if isinstance(file, StringTypes):
+ if isinstance(file, str):
fp = open(file, 'rb')
try:
result = builder.parseFile(fp)
@@ -952,7 +952,7 @@ def parseFragment(file, context, namespaces=True):
else:
builder = FragmentBuilder(context)
- if isinstance(file, StringTypes):
+ if isinstance(file, str):
fp = open(file, 'rb')
try:
result = builder.parseFile(fp)
diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py
index de4cb4f..62725c6 100644
--- a/Lib/xml/dom/minicompat.py
+++ b/Lib/xml/dom/minicompat.py
@@ -40,12 +40,7 @@ __all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"]
import xml.dom
-try:
- unicode
-except NameError:
- StringTypes = type(''),
-else:
- StringTypes = type(''), type(unicode(''))
+StringTypes = (str,)
class NodeList(list):
@@ -100,7 +95,7 @@ class EmptyNodeList(tuple):
def defproperty(klass, name, doc):
- get = getattr(klass, ("_get_" + name)).im_func
+ get = getattr(klass, ("_get_" + name))
def set(self, value, name=name):
raise xml.dom.NoModificationAllowedErr(
"attempt to modify read-only attribute " + repr(name))
diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py
index 7e2898c..f23ad05 100644
--- a/Lib/xml/dom/minidom.py
+++ b/Lib/xml/dom/minidom.py
@@ -14,6 +14,8 @@ Todo:
* SAX 2 namespaces
"""
+import codecs
+import io
import xml.dom
from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE, domreg
@@ -38,26 +40,26 @@ class Node(xml.dom.Node):
prefix = EMPTY_PREFIX # non-null only for NS elements and attributes
- def __nonzero__(self):
+ def __bool__(self):
return True
- def toxml(self, encoding = None):
+ def toxml(self, encoding=None):
return self.toprettyxml("", "", encoding)
- def toprettyxml(self, indent="\t", newl="\n", encoding = None):
+ def toprettyxml(self, indent="\t", newl="\n", encoding=None):
# indent = the indentation string to prepend, per level
# newl = the newline string to append
- writer = _get_StringIO()
- if encoding is not None:
- import codecs
- # Can't use codecs.getwriter to preserve 2.0 compatibility
- writer = codecs.lookup(encoding)[3](writer)
+ use_encoding = "utf-8" if encoding is None else encoding
+ writer = codecs.getwriter(use_encoding)(io.BytesIO())
if self.nodeType == Node.DOCUMENT_NODE:
# Can pass encoding only to document, to put it into XML header
self.writexml(writer, "", indent, newl, encoding)
else:
self.writexml(writer, "", indent, newl)
- return writer.getvalue()
+ if encoding is None:
+ return writer.stream.getvalue().decode(use_encoding)
+ else:
+ return writer.stream.getvalue()
def hasChildNodes(self):
if self.childNodes:
@@ -251,7 +253,7 @@ class Node(xml.dom.Node):
def _call_user_data_handler(self, operation, src, dst):
if hasattr(self, "_user_data"):
- for key, (data, handler) in self._user_data.items():
+ for key, (data, handler) in list(self._user_data.items()):
if handler is not None:
handler.handle(operation, key, data, src, dst)
@@ -266,6 +268,14 @@ class Node(xml.dom.Node):
self.previousSibling = None
self.nextSibling = None
+ # A Node is its own context manager, to ensure that an unlink() call occurs.
+ # This is similar to how a file object works.
+ def __enter__(self):
+ return self
+
+ def __exit__(self, et, ev, tb):
+ self.unlink()
+
defproperty(Node, "firstChild", doc="First child node, or None.")
defproperty(Node, "lastChild", doc="Last child node, or None.")
defproperty(Node, "localName", doc="Namespace-local name of this node.")
@@ -355,6 +365,8 @@ class Attr(Node):
# nodeValue and value are set elsewhere
def _get_localName(self):
+ if 'localName' in self.__dict__:
+ return self.__dict__['localName']
return self.nodeName.split(":", 1)[-1]
def _get_name(self):
@@ -474,7 +486,7 @@ class NamedNodeMap(object):
def item(self, index):
try:
- return self[self._attrs.keys()[index]]
+ return self[list(self._attrs.keys())[index]]
except IndexError:
return None
@@ -490,8 +502,8 @@ class NamedNodeMap(object):
L.append(((node.namespaceURI, node.localName), node.value))
return L
- def has_key(self, key):
- if isinstance(key, StringTypes):
+ def __contains__(self, key):
+ if isinstance(key, str):
return key in self._attrs
else:
return key in self._attrsNS
@@ -510,12 +522,29 @@ class NamedNodeMap(object):
__len__ = _get_length
- __hash__ = None # Mutable type can't be correctly hashed
- def __cmp__(self, other):
+ def _cmp(self, other):
if self._attrs is getattr(other, "_attrs", None):
return 0
else:
- return cmp(id(self), id(other))
+ return (id(self) > id(other)) - (id(self) < id(other))
+
+ def __eq__(self, other):
+ return self._cmp(other) == 0
+
+ def __ge__(self, other):
+ return self._cmp(other) >= 0
+
+ def __gt__(self, other):
+ return self._cmp(other) > 0
+
+ def __le__(self, other):
+ return self._cmp(other) <= 0
+
+ def __lt__(self, other):
+ return self._cmp(other) < 0
+
+ def __ne__(self, other):
+ return self._cmp(other) != 0
def __getitem__(self, attname_or_tuple):
if isinstance(attname_or_tuple, tuple):
@@ -525,7 +554,7 @@ class NamedNodeMap(object):
# same as set
def __setitem__(self, attname, value):
- if isinstance(value, StringTypes):
+ if isinstance(value, str):
try:
node = self._attrs[attname]
except KeyError:
@@ -535,7 +564,7 @@ class NamedNodeMap(object):
node.value = value
else:
if not isinstance(value, Attr):
- raise TypeError, "value must be a string or Attr object"
+ raise TypeError("value must be a string or Attr object")
node = value
self.setNamedItem(node)
@@ -659,13 +688,15 @@ class Element(Node):
# namespaces.
def _get_localName(self):
+ if 'localName' in self.__dict__:
+ return self.__dict__['localName']
return self.tagName.split(":", 1)[-1]
def _get_tagName(self):
return self.tagName
def unlink(self):
- for attr in self._attrs.values():
+ for attr in list(self._attrs.values()):
attr.unlink()
self._attrs = None
self._attrsNS = None
@@ -798,8 +829,7 @@ class Element(Node):
writer.write(indent+"<" + self.tagName)
attrs = self._get_attributes()
- a_names = attrs.keys()
- a_names.sort()
+ a_names = sorted(attrs.keys())
for a_name in a_names:
writer.write(" %s=\"" % a_name)
@@ -1125,7 +1155,7 @@ def _get_containing_entref(node):
return None
-class Comment(Childless, CharacterData):
+class Comment(CharacterData):
nodeType = Node.COMMENT_NODE
nodeName = "#comment"
@@ -1182,7 +1212,7 @@ class ReadOnlySequentialNamedNodeMap(object):
else:
node = self.getNamedItem(name_or_tuple)
if node is None:
- raise KeyError, name_or_tuple
+ raise KeyError(name_or_tuple)
return node
def item(self, index):
@@ -1609,16 +1639,16 @@ class Document(Node, DocumentLS):
return e
def createTextNode(self, data):
- if not isinstance(data, StringTypes):
- raise TypeError, "node contents must be a string"
+ if not isinstance(data, str):
+ raise TypeError("node contents must be a string")
t = Text()
t.data = data
t.ownerDocument = self
return t
def createCDATASection(self, data):
- if not isinstance(data, StringTypes):
- raise TypeError, "node contents must be a string"
+ if not isinstance(data, str):
+ raise TypeError("node contents must be a string")
c = CDATASection()
c.data = data
c.ownerDocument = self
@@ -1901,11 +1931,6 @@ def _nssplit(qualifiedName):
return (None, fields[0])
-def _get_StringIO():
- # we can't use cStringIO since it doesn't support Unicode strings
- from StringIO import StringIO
- return StringIO()
-
def _do_pulldom_parse(func, args, kwargs):
events = func(*args, **kwargs)
toktype, rootNode = events.getEvent()
@@ -1935,7 +1960,7 @@ def parseString(string, parser=None):
def getDOMImplementation(features=None):
if features:
- if isinstance(features, StringTypes):
+ if isinstance(features, str):
features = domreg._parse_feature_string(features)
for f, v in features:
if not Document.implementation.hasFeature(f, v):
diff --git a/Lib/xml/dom/pulldom.py b/Lib/xml/dom/pulldom.py
index 18f49b5..d5ac8b2 100644
--- a/Lib/xml/dom/pulldom.py
+++ b/Lib/xml/dom/pulldom.py
@@ -2,11 +2,6 @@ import xml.sax
import xml.sax.handler
import types
-try:
- _StringTypes = [types.StringType, types.UnicodeType]
-except AttributeError:
- _StringTypes = [types.StringType]
-
START_ELEMENT = "START_ELEMENT"
END_ELEMENT = "END_ELEMENT"
COMMENT = "COMMENT"
@@ -201,7 +196,7 @@ class PullDOM(xml.sax.ContentHandler):
class ErrorHandler:
def warning(self, exception):
- print exception
+ print(exception)
def error(self, exception):
raise exception
def fatalError(self, exception):
@@ -228,7 +223,7 @@ class DOMEventStream:
return rc
raise IndexError
- def next(self):
+ def __next__(self):
rc = self.getEvent()
if rc:
return rc
@@ -330,8 +325,8 @@ default_bufsize = (2 ** 14) - 20
def parse(stream_or_string, parser=None, bufsize=None):
if bufsize is None:
bufsize = default_bufsize
- if type(stream_or_string) in _StringTypes:
- stream = open(stream_or_string)
+ if isinstance(stream_or_string, str):
+ stream = open(stream_or_string, 'rb')
else:
stream = stream_or_string
if not parser:
@@ -340,9 +335,9 @@ def parse(stream_or_string, parser=None, bufsize=None):
def parseString(string, parser=None):
try:
- from cStringIO import StringIO
+ from io import StringIO
except ImportError:
- from StringIO import StringIO
+ from io import StringIO
bufsize = len(string)
buf = StringIO(string)
diff --git a/Lib/xml/dom/xmlbuilder.py b/Lib/xml/dom/xmlbuilder.py
index dc7c5d4..d798624 100644
--- a/Lib/xml/dom/xmlbuilder.py
+++ b/Lib/xml/dom/xmlbuilder.py
@@ -190,8 +190,8 @@ class DOMBuilder:
options.errorHandler = self.errorHandler
fp = input.byteStream
if fp is None and options.systemId:
- import urllib2
- fp = urllib2.urlopen(input.systemId)
+ import urllib.request
+ fp = urllib.request.urlopen(input.systemId)
return self._parse_bytestream(fp, options)
def parseWithContext(self, input, cnode, action):
@@ -223,14 +223,14 @@ class DOMEntityResolver(object):
source.encoding = self._guess_media_encoding(source)
# determine the base URI is we can
- import posixpath, urlparse
- parts = urlparse.urlparse(systemId)
+ import posixpath, urllib.parse
+ parts = urllib.parse.urlparse(systemId)
scheme, netloc, path, params, query, fragment = parts
# XXX should we check the scheme here as well?
if path and not path.endswith("/"):
path = posixpath.dirname(path) + "/"
parts = scheme, netloc, path, params, query, fragment
- source.baseURI = urlparse.urlunparse(parts)
+ source.baseURI = urllib.parse.urlunparse(parts)
return source
@@ -242,8 +242,8 @@ class DOMEntityResolver(object):
return self._opener
def _create_opener(self):
- import urllib2
- return urllib2.build_opener()
+ import urllib.request
+ return urllib.request.build_opener()
def _guess_media_encoding(self, source):
info = source.byteStream.info()