summaryrefslogtreecommitdiff
path: root/coverage/xmlreport.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2018-11-10 14:11:47 -0500
committerNed Batchelder <ned@nedbatchelder.com>2018-11-11 16:45:33 -0500
commitc376209f35331b358e59c79ed3537a2ed920d677 (patch)
tree5dddd7715de562ffa851be89738af3f4e9644b3c /coverage/xmlreport.py
parent19c093580d9ad80fd45dd6ea333c24c059c891bf (diff)
downloadpython-coveragepy-git-c376209f35331b358e59c79ed3537a2ed920d677.tar.gz
Canonicalize the XML output
https://bugs.python.org/issue34160 added retaining the user's attribute order to the XML output, which removed the sorting that used to happen. This broke our XML tests, which compare against saved gold files. This adds in a rough-and-ready canonicalization to avoid the problem. Maybe the core devs will eventually support a sort_attributes option, and I can get rid of this.
Diffstat (limited to 'coverage/xmlreport.py')
-rw-r--r--coverage/xmlreport.py29
1 files changed, 24 insertions, 5 deletions
diff --git a/coverage/xmlreport.py b/coverage/xmlreport.py
index 5148b54a..6c07337a 100644
--- a/coverage/xmlreport.py
+++ b/coverage/xmlreport.py
@@ -1,3 +1,4 @@
+# coding: utf-8
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
@@ -5,6 +6,7 @@
import os
import os.path
+import re
import sys
import time
import xml.dom.minidom
@@ -124,11 +126,8 @@ class XmlReporter(Reporter):
xcoverage.setAttribute("branch-rate", "0")
xcoverage.setAttribute("complexity", "0")
- # Use the DOM to write the output file.
- out = self.xml_out.toprettyxml()
- if env.PY2:
- out = out.encode("utf8")
- outfile.write(out)
+ # Write the output file.
+ outfile.write(serialize_xml(self.xml_out))
# Return the total percentage.
denom = lnum_tot + bnum_tot
@@ -219,3 +218,23 @@ class XmlReporter(Reporter):
package[2] += class_lines
package[3] += class_br_hits
package[4] += class_branches
+
+
+def serialize_xml(dom):
+ """Serialize a minidom node to XML."""
+ out = dom.toprettyxml()
+ if env.PY2:
+ out = out.encode("utf8")
+ # In Python 3.8, minidom lost the sorting of attributes: https://bugs.python.org/issue34160
+ # For the limited kinds of XML we produce, this re-sorts them.
+ if env.PYVERSION >= (3, 8):
+ rx_attr = r' [\w-]+="[^"]*"'
+ rx_attrs = r'(' + rx_attr + ')+'
+ fixed_lines = []
+ for line in out.splitlines(True):
+ hollow_line = re.sub(rx_attrs, u"☺", line)
+ attrs = sorted(re.findall(rx_attr, line))
+ new_line = hollow_line.replace(u"☺", "".join(attrs))
+ fixed_lines.append(new_line)
+ out = "".join(fixed_lines)
+ return out