diff --git a/json2xml/dicttoxml.py b/json2xml/dicttoxml.py index 896c1ef2..41f751da 100755 --- a/json2xml/dicttoxml.py +++ b/json2xml/dicttoxml.py @@ -11,17 +11,18 @@ Items with a `None` type become empty XML elements. This module works with Python 3.7+ """ - import datetime import logging import numbers +import os from collections.abc import Callable, Sequence from random import randint from typing import Any, Dict, List, Optional, Tuple, Union from defusedxml.minidom import parseString -LOG = logging.getLogger("dicttoxml") +DEBUGMODE = os.getenv("DEBUGMODE", False) # pragma: no cover +LOG = logging.getLogger("dicttoxml") # pragma: no cover ids: List[str] = [] # initialize list of unique ids @@ -100,7 +101,8 @@ def make_attrstring(attr: dict[str, Any]) -> str: def key_is_valid_xml(key: str) -> bool: """Checks that a key is a valid XML name""" - LOG.info(f'Inside key_is_valid_xml(). Testing "{str(key)}"') + if DEBUGMODE: # pragma: no cover + LOG.info(f'Inside key_is_valid_xml(). Testing "{str(key)}"') test_xml = f'<{key}>foo' try: parseString(test_xml) @@ -111,9 +113,10 @@ def key_is_valid_xml(key: str) -> bool: def make_valid_xml_name(key: str, attr: Dict[str, Any]) -> Tuple[str, Dict[str, Any]]: """Tests an XML name and fixes it if invalid""" - LOG.info( - f'Inside make_valid_xml_name(). Testing key "{str(key)}" with attr "{str(attr)}"' - ) + if DEBUGMODE: # pragma: no cover + LOG.info( + f'Inside make_valid_xml_name(). Testing key "{str(key)}" with attr "{str(attr)}"' + ) key = escape_xml(key) # nothing happens at escape_xml if attr is not a string, we don't # need to pass it to the method at all. @@ -162,10 +165,11 @@ def convert( ) -> str: """Routes the elements of an object to the right function to convert them based on their data type""" - LOG.info(f'Inside convert(). type(obj)="{type(obj).__name__}"') - # avoid cpu consuming object serialization => extra if - if LOG.getEffectiveLevel() <= logging.DEBUG: - LOG.debug(f' obj="{str(obj)}"') + if DEBUGMODE: # pragma: no cover + LOG.info(f'Inside convert(). type(obj)="{type(obj).__name__}"') + # avoid cpu consuming object serialization => extra if + if LOG.getEffectiveLevel() <= logging.DEBUG: + LOG.debug(f' obj="{str(obj)}"') item_name = item_func(parent) # since bool is also a subtype of number.Number and int, the check for bool @@ -227,12 +231,13 @@ def dict2xml_str( parse dict2xml """ keys_str = ", ".join(str(key) for key in item) - LOG.info( - f'Inside dict_item2xml_str: type(obj)="{type(item).__name__}", keys="{keys_str}"' - ) - # avoid cpu consuming object serialization => extra if - if LOG.getEffectiveLevel() <= logging.DEBUG: - LOG.debug(f' item="{str(item)}"') + if DEBUGMODE: # pragma: no cover + LOG.info( + f'Inside dict_item2xml_str: type(obj)="{type(item).__name__}", keys="{keys_str}"' + ) + # avoid cpu consuming object serialization => extra if + if LOG.getEffectiveLevel() <= logging.DEBUG: + LOG.debug(f' item="{str(item)}"') if attr_type: attr["type"] = get_xml_type(item) @@ -292,22 +297,24 @@ def convert_dict( ) -> str: """Converts a dict into an XML string.""" keys_str = ", ".join(str(key) for key in obj) - LOG.info( - f'Inside convert_dict(): type(obj)="{type(obj).__name__}", keys="{keys_str}"' - ) - # avoid cpu consuming object serialization => extra if - if LOG.getEffectiveLevel() <= logging.DEBUG: - LOG.debug(f' obj="{str(obj)}"') + if DEBUGMODE: # pragma: no cover + LOG.info( + f'Inside convert_dict(): type(obj)="{type(obj).__name__}", keys="{keys_str}"' + ) + # avoid cpu consuming object serialization => extra if + if LOG.getEffectiveLevel() <= logging.DEBUG: + LOG.debug(f' obj="{str(obj)}"') output: List[str] = [] addline = output.append for key, val in obj.items(): - LOG.info( - f'Looping inside convert_dict(): key="{str(key)}", type(val)="{type(val).__name__}"' - ) - if LOG.getEffectiveLevel() <= logging.DEBUG: - LOG.debug(f' val="{str(val)}"') + if DEBUGMODE: # pragma: no cover + LOG.info( + f'Looping inside convert_dict(): key="{str(key)}", type(val)="{type(val).__name__}"' + ) + if LOG.getEffectiveLevel() <= logging.DEBUG: + LOG.debug(f' val="{str(val)}"') attr = {} if not ids else {"id": f"{get_unique_id(parent)}"} @@ -377,10 +384,11 @@ def convert_list( item_wrap: bool, ) -> str: """Converts a list into an XML string.""" - LOG.info(f'Inside convert_list(): type(items)="{type(items).__name__}"') - # avoid cpu consuming object serialization => extra if - if LOG.getEffectiveLevel() <= logging.DEBUG: - LOG.debug(f' items="{str(items)}"') + if DEBUGMODE: # pragma: no cover + LOG.info(f'Inside convert_list(): type(items)="{type(items).__name__}"') + # avoid cpu consuming object serialization => extra if + if LOG.getEffectiveLevel() <= logging.DEBUG: + LOG.debug(f' items="{str(items)}"') output: List[str] = [] addline = output.append @@ -393,12 +401,13 @@ def convert_list( this_id = get_unique_id(parent) for i, item in enumerate(items): - LOG.info( - f'Looping inside convert_list(): index="{str(i)}", type="{type(item).__name__}"' - ) - # avoid cpu consuming object serialization => extra if - if LOG.getEffectiveLevel() <= logging.DEBUG: - LOG.debug(f' item="{str(item)}"') + if DEBUGMODE: # pragma: no cover + LOG.info( + f'Looping inside convert_list(): index="{str(i)}", type="{type(item).__name__}"' + ) + # avoid cpu consuming object serialization => extra if + if LOG.getEffectiveLevel() <= logging.DEBUG: + LOG.debug(f' item="{str(item)}"') attr = {} if not ids else {"id": f"{this_id}_{i + 1}"} @@ -474,9 +483,10 @@ def convert_kv( cdata: bool = False, ) -> str: """Converts a number or string into an XML element""" - LOG.info( - f'Inside convert_kv(): key="{str(key)}", val="{str(val)}", type(val) is: "{type(val).__name__}"' - ) + if DEBUGMODE: # pragma: no cover + LOG.info( + f'Inside convert_kv(): key="{str(key)}", val="{str(val)}", type(val) is: "{type(val).__name__}"' + ) key, attr = make_valid_xml_name(key, attr) if attr_type: @@ -489,9 +499,10 @@ def convert_bool( key: str, val: bool, attr_type: bool, attr: Dict[str, Any] = {}, cdata: bool = False ) -> str: """Converts a boolean into an XML element""" - LOG.info( - f'Inside convert_bool(): key="{str(key)}", val="{str(val)}", type(val) is: "{type(val).__name__}"' - ) + if DEBUGMODE: # pragma: no cover + LOG.info( + f'Inside convert_bool(): key="{str(key)}", val="{str(val)}", type(val) is: "{type(val).__name__}"' + ) key, attr = make_valid_xml_name(key, attr) if attr_type: @@ -504,7 +515,6 @@ def convert_none( key: str, attr_type: bool, attr: Dict[str, Any] = {}, cdata: bool = False ) -> str: """Converts a null value into an XML element""" - # LOG.info(f'Inside convert_none(): key="{str(key)}" val={type(val)}') key, attr = make_valid_xml_name(key, attr) if attr_type: @@ -554,12 +564,13 @@ def dicttoxml( {'list': {'@attrs': {'a':'b','c':'d'}, '@val': [4, 5, 6]} which results in 456 """ - LOG.info( - f'Inside dicttoxml(): type(obj) is: "{type(obj).__name__}", type(ids") is : {type(ids).__name__}' - ) - # avoid cpu consuming object serialization (problem for large objects) => extra if - if LOG.getEffectiveLevel() <= logging.DEBUG: - LOG.debug(f' obj="{str(obj)}"') + if DEBUGMODE: # pragma: no cover + LOG.info( + f'Inside dicttoxml(): type(obj) is: "{type(obj).__name__}", type(ids") is : {type(ids).__name__}' + ) + # avoid cpu consuming object serialization (problem for large objects) => extra if + if LOG.getEffectiveLevel() <= logging.DEBUG: + LOG.debug(f' obj="{str(obj)}"') output = [] namespacestr = "" diff --git a/tests/test_json2xml.py b/tests/test_json2xml.py index 7ab03711..ada0194c 100644 --- a/tests/test_json2xml.py +++ b/tests/test_json2xml.py @@ -98,7 +98,6 @@ def test_item_wrap(self): xmldata = json2xml.Json2xml(data, pretty=False).to_xml() old_dict = xmltodict.parse(xmldata) # item must be present within my_items - print(xmldata) assert "item" in old_dict['all']['my_items'] assert "item" in old_dict['all']['my_str_items'] @@ -109,7 +108,6 @@ def test_no_item_wrap(self): xmldata = json2xml.Json2xml(data, pretty=False, item_wrap=False).to_xml() old_dict = xmltodict.parse(xmldata) # my_item must be present within my_items - print(xmldata) assert "my_item" in old_dict['all']['my_items'] assert "my_str_items" in old_dict['all'] @@ -119,7 +117,6 @@ def test_empty_array(self): ) xmldata = json2xml.Json2xml(data, pretty=False).to_xml() old_dict = xmltodict.parse(xmldata) - print(xmldata) # item empty_list be present within all assert "empty_list" in old_dict['all'] @@ -129,7 +126,6 @@ def test_attrs(self): ) xmldata = json2xml.Json2xml(data, pretty=False).to_xml() old_dict = xmltodict.parse(xmldata) - print(xmldata) # test all attrs assert "str" == old_dict['all']['my_string']['@type'] assert "int" == old_dict['all']['my_int']['@type'] @@ -181,9 +177,7 @@ def test_read_boolean_data_from_json(self): """Test correct return for boolean types.""" data = readfromjson("examples/booleanjson.json") result = json2xml.Json2xml(data).to_xml() - print(result) dict_from_xml = xmltodict.parse(result) - print(dict_from_xml) assert dict_from_xml["all"]["boolean"]["#text"] != 'True' assert dict_from_xml["all"]["boolean"]["#text"] == 'true' assert dict_from_xml["all"]["boolean_dict_list"]["item"][0]["boolean_dict"]["boolean"]["#text"] == 'true' @@ -195,9 +189,7 @@ def test_read_boolean_data_from_json2(self): """Test correct return for boolean types.""" data = readfromjson("examples/booleanjson2.json") result = json2xml.Json2xml(data).to_xml() - print(result) dict_from_xml = xmltodict.parse(result) - print(dict_from_xml) assert dict_from_xml["all"]["boolean_list"]["item"][0]["#text"] != 'True' assert dict_from_xml["all"]["boolean_list"]["item"][0]["#text"] == 'true' assert dict_from_xml["all"]["boolean_list"]["item"][1]["#text"] == 'false' @@ -212,7 +204,6 @@ def test_dict2xml_with_namespaces(self): data = {'ns1:node1': 'data in namespace 1', 'ns2:node2': 'data in namespace 2'} namespaces = {'ns1': 'http://www.google.de/ns1', 'ns2': 'http://www.google.de/ns2'} result = dicttoxml.dicttoxml(data, attr_type=False, xml_namespaces=namespaces) - print(result) assert b'' \ b'' \ b'data in namespace 1' \ @@ -222,7 +213,6 @@ def test_dict2xml_with_namespaces(self): def test_dict2xml_with_flat(self): data = {'flat_list@flat': [1, 2, 3], 'non_flat_list': [4, 5, 6]} result = dicttoxml.dicttoxml(data, attr_type=False) - print(result) assert b'' \ b'123' \ b'456' \ @@ -232,7 +222,6 @@ def test_dict2xml_with_val_and_custom_attr(self): # in order to use @attr in non-dict objects, we need to lift into a dict and combine with @val as key data = {'list1': [1, 2, 3], 'list2': {'@attrs': {'myattr1': 'myval1', 'myattr2': 'myval2'}, '@val': [4, 5, 6]}} result = dicttoxml.dicttoxml(data, attr_type=False) - print(result) assert b'' \ b'123' \ b'456' \