Skip to content

Commit 4e23a93

Browse files
authored
Merge pull request #403 from mpsonntag/kwargsSave
Allow additional keywords in 'odml.save' LGTM
2 parents 24d7552 + bf60ef7 commit 4e23a93

File tree

4 files changed

+93
-16
lines changed

4 files changed

+93
-16
lines changed

odml/fileio.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,23 @@ def load(filename, backend="xml", show_warnings=True):
2525
return reader.from_file(filename)
2626

2727

28-
def save(obj, filename, backend="xml"):
28+
def save(obj, filename, backend="xml", **kwargs):
2929
"""
3030
Save an open odML document to file of a specified format.
3131
:param obj: odML document do be saved.
3232
:param filename: Filename and path where the odML document
3333
should be saved.
3434
:param backend: Format in which the odML document is to be saved.
3535
The default format is XML.
36+
:param kwargs: Writer backend keyword arguments e.g. for adding specific
37+
stylesheets for xml documents or specifying an RDF format.
38+
Refer to the documentation of the available parsers to check
39+
which arguments are supported.
3640
"""
3741
writer = ODMLWriter(backend)
3842
if "." not in filename.split(os.pathsep)[-1]:
3943
filename = filename + ".%s" % backend
40-
return writer.write_file(obj, filename)
44+
return writer.write_file(obj, filename, **kwargs)
4145

4246

4347
def display(obj, backend="xml"):

odml/tools/odmlparser.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def __init__(self, parser='XML'):
4646

4747
self.parser = parser
4848

49-
def write_file(self, odml_document, filename):
49+
def write_file(self, odml_document, filename, **kwargs):
5050
"""
5151
Writes an odml.Document to a file using the format
5252
defined in the ODMLWriter.parser property. Supported formats are
@@ -55,6 +55,8 @@ def write_file(self, odml_document, filename):
5555
5656
:param odml_document: odml.Document.
5757
:param filename: path and filename of the output file.
58+
:param kwargs: Writer backend keyword arguments. Refer to the documentation
59+
of the available parsers to check which arguments are supported.
5860
"""
5961

6062
# Write document only if it does not contain validation errors.
@@ -74,30 +76,44 @@ def write_file(self, odml_document, filename):
7476
msg += " Run the Documents 'validate' method to access them.\n%s" % report
7577
warnings.warn(msg)
7678

77-
with open(filename, 'w') as file:
78-
# Add XML header to support odML stylesheets.
79-
if self.parser == 'XML':
80-
file.write(xmlparser.XMLWriter.header)
81-
82-
file.write(self.to_string(odml_document))
79+
# Allow kwargs when writing XML documents to support individual style sheets
80+
if self.parser == 'XML':
81+
local_style = False
82+
custom_template = None
83+
84+
if "local_style" in kwargs and isinstance(kwargs["local_style"], bool):
85+
local_style = kwargs["local_style"]
86+
if "custom_template" in kwargs and isinstance(kwargs["custom_template"], str):
87+
custom_template = kwargs["custom_template"]
88+
xmlparser.XMLWriter(odml_document).write_file(filename, local_style=local_style,
89+
custom_template=custom_template)
90+
else:
91+
with open(filename, 'w') as file:
92+
file.write(self.to_string(odml_document, **kwargs))
8393

84-
def to_string(self, odml_document):
94+
def to_string(self, odml_document, **kwargs):
8595
"""
8696
Parses an odml.Document to a string in the file format
8797
defined in the ODMLWriter.parser property. Supported formats are
88-
JSON, XML, YAML and RDF.
98+
JSON, YAML and RDF.
8999
90100
:param odml_document: odml.Document.
101+
:param kwargs: Writer backend keyword arguments e.g. for adding specific
102+
stylesheets for xml documents or specifying an RDF format.
103+
Refer to the documentation of the available parsers to check
104+
which arguments are supported.
105+
91106
:return: string containing the content of the odml.Document in the
92107
specified format.
93108
"""
94109
string_doc = ''
95110

96-
if self.parser == 'XML':
97-
string_doc = unicode(xmlparser.XMLWriter(odml_document))
98-
elif self.parser == "RDF":
99-
# Use XML as default output format for now.
100-
string_doc = RDFWriter(odml_document).get_rdf_str("xml")
111+
if self.parser == "RDF":
112+
rdf_format = "xml"
113+
if "rdf_format" in kwargs and isinstance(kwargs["rdf_format"], str):
114+
rdf_format = kwargs["rdf_format"]
115+
116+
string_doc = RDFWriter(odml_document).get_rdf_str(rdf_format)
101117
else:
102118
self.parsed_doc = DictWriter().to_dict(odml_document)
103119

test/test_fileio.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ def test_load_save(self):
2727
odml.save(doc, file_name)
2828
os.remove(file_name)
2929

30+
def test_save_kwargs(self):
31+
doc = odml.load(self.file)
32+
file_name = "%s_copy" % self.file
33+
34+
# Test unsupported kwarg does not raise an exception
35+
odml.save(doc, file_name, unsupported_kwarg="I do not matter")
36+
os.remove(file_name)
37+
3038
def test_display(self):
3139
doc = odml.load(self.file)
3240
odml.display(doc)

test/test_parser_odml.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,39 @@ def test_xml_file(self):
6868

6969
self.assertEqual(xml_doc, self.odml_doc)
7070

71+
def test_xml_file_kwargs(self):
72+
# Check unsupported kwargs
73+
self.xml_writer.write_file(self.odml_doc, self.xml_file,
74+
invalid_a=False, invalid_b=None, invalid_c="naughty")
75+
xml_doc = self.xml_reader.from_file(self.xml_file)
76+
77+
self.assertEqual(xml_doc, self.odml_doc)
78+
79+
# Check invalid local_style
80+
self.xml_writer.write_file(self.odml_doc, self.xml_file, local_style="this is not good")
81+
xml_doc = self.xml_reader.from_file(self.xml_file)
82+
83+
self.assertEqual(xml_doc, self.odml_doc)
84+
85+
# Check valid local_style
86+
self.xml_writer.write_file(self.odml_doc, self.xml_file, local_style=True)
87+
xml_doc = self.xml_reader.from_file(self.xml_file)
88+
89+
self.assertEqual(xml_doc, self.odml_doc)
90+
91+
# Check invalid custom template
92+
self.xml_writer.write_file(self.odml_doc, self.xml_file, custom_template=True)
93+
xml_doc = self.xml_reader.from_file(self.xml_file)
94+
95+
self.assertEqual(xml_doc, self.odml_doc)
96+
97+
# Check custom template
98+
custom = "<xsl:template></xsl:template>"
99+
self.xml_writer.write_file(self.odml_doc, self.xml_file, custom_template=custom)
100+
xml_doc = self.xml_reader.from_file(self.xml_file)
101+
102+
self.assertEqual(xml_doc, self.odml_doc)
103+
71104
def test_yaml_file(self):
72105
self.yaml_writer.write_file(self.odml_doc, self.yaml_file)
73106
yaml_doc = self.yaml_reader.from_file(self.yaml_file)
@@ -143,6 +176,22 @@ def test_rdf_file(self):
143176
self.assertIn(doc.sections[2].properties[1].name, rdf_sec3.properties)
144177
self.assertIn(doc.sections[2].properties[1].name, rdf_sec3.properties)
145178

179+
def test_rdf_file_kwargs(self):
180+
181+
# Check unsupported kwarg
182+
self.rdf_writer.write_file(self.odml_doc, self.rdf_file,
183+
invalid_a=False, invalid_b=None, invalid_c="naughty")
184+
self.rdf_reader.from_file(self.rdf_file, "xml")
185+
186+
# Check unsupported backend
187+
with self.assertRaises(ValueError):
188+
self.rdf_writer.write_file(self.odml_doc, self.rdf_file, rdf_format="i do not exist")
189+
190+
# Check supported backend different from xml
191+
rdf_format = "turtle"
192+
self.rdf_writer.write_file(self.odml_doc, self.rdf_file, rdf_format=rdf_format)
193+
self.rdf_reader.from_file(self.rdf_file, rdf_format)
194+
146195
def test_xml_string(self):
147196
# Read from string
148197
author = "HPL"

0 commit comments

Comments
 (0)