Skip to content

Commit 1a28783

Browse files
authored
Some fixes for XMLTransformer and Pipeline (#585)
1 parent 1b8e814 commit 1a28783

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

src/codemodder/codemods/xml_transformer.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from xml.sax import SAXParseException, handler
44
from xml.sax.handler import LexicalHandler
55
from xml.sax.saxutils import XMLGenerator
6-
from xml.sax.xmlreader import Locator
6+
from xml.sax.xmlreader import AttributesImpl, Locator
77

88
from defusedxml.sax import make_parser
99

@@ -107,9 +107,9 @@ def __init__(
107107
super().__init__(out, encoding, short_empty_elements, results)
108108

109109
def startElement(self, name, attrs):
110-
new_attrs = attrs
110+
new_attrs: AttributesImpl = attrs
111111
if self.event_match_result() and name in self.name_attributes_map:
112-
new_attrs = self.name_attributes_map[name]
112+
new_attrs = AttributesImpl(attrs._attrs | self.name_attributes_map[name])
113113
self.add_change(self._my_locator.getLineNumber())
114114
super().startElement(name, new_attrs)
115115

@@ -150,19 +150,18 @@ def apply(
150150
return None
151151

152152
diff = ""
153-
with open(file_context.file_path, "r") as original:
154-
# don't calculate diff if no changes were reported
155-
# TODO there's a failure potential here for very large files
156-
diff = (
157-
create_diff(
153+
# don't calculate diff if no changes were reported
154+
if changes:
155+
with open(file_context.file_path, "r") as original:
156+
# TODO there's a failure potential here for very large files
157+
diff = create_diff(
158158
original.readlines(),
159159
output_file.readlines(),
160160
)
161-
if changes
162-
else ""
163-
)
164161

165-
if not context.dry_run:
162+
# don't write anything if no changes were issued
163+
# avoids simply formatting the file
164+
if changes and not context.dry_run:
166165
with open(file_context.file_path, "w+b") as original:
167166
# mmap can't map empty files, write something first
168167
original.write(b"a")

tests/test_xml_transformer.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,22 @@ def test_change_single_attr(self):
7575
name_attr_map = {"element": {"attr": "true"}}
7676
self.run_and_assert(name_attr_map, input_code, expected_output)
7777

78-
def test_change_multiple_attr(self):
78+
def test_add_new_attribute(self):
7979
input_code = """\
8080
<?xml version="1.0" encoding="utf-8"?>
81-
<element first="1" second="2"></element>"""
81+
<element></element>"""
82+
expected_output = """\
83+
<?xml version="1.0" encoding="utf-8"?>
84+
<element attr="true"></element>"""
85+
name_attr_map = {"element": {"attr": "true"}}
86+
self.run_and_assert(name_attr_map, input_code, expected_output)
87+
88+
def test_change_multiple_attr_and_preserve_existing(self):
89+
input_code = """\
90+
<?xml version="1.0" encoding="utf-8"?>
91+
<element first="1" second="2" three="three"></element>"""
8292
expected_output = """\
8393
<?xml version="1.0" encoding="utf-8"?>
84-
<element first="one" second="two"></element>"""
94+
<element first="one" second="two" three="three"></element>"""
8595
name_attr_map = {"element": {"first": "one", "second": "two"}}
8696
self.run_and_assert(name_attr_map, input_code, expected_output)

0 commit comments

Comments
 (0)