11
11
Items with a `None` type become empty XML elements.
12
12
This module works with Python 3.7+
13
13
"""
14
-
15
14
import datetime
16
15
import logging
17
16
import numbers
17
+ import os
18
18
from collections .abc import Callable , Sequence
19
19
from random import randint
20
20
from typing import Any , Dict , List , Optional , Tuple , Union
21
21
22
22
from defusedxml .minidom import parseString
23
23
24
- LOG = logging .getLogger ("dicttoxml" )
24
+ DEBUGMODE = os .getenv ("DEBUGMODE" , False ) # pragma: no cover
25
+ LOG = logging .getLogger ("dicttoxml" ) # pragma: no cover
25
26
26
27
27
28
ids : List [str ] = [] # initialize list of unique ids
@@ -100,7 +101,8 @@ def make_attrstring(attr: dict[str, Any]) -> str:
100
101
101
102
def key_is_valid_xml (key : str ) -> bool :
102
103
"""Checks that a key is a valid XML name"""
103
- LOG .info (f'Inside key_is_valid_xml(). Testing "{ str (key )} "' )
104
+ if DEBUGMODE : # pragma: no cover
105
+ LOG .info (f'Inside key_is_valid_xml(). Testing "{ str (key )} "' )
104
106
test_xml = f'<?xml version="1.0" encoding="UTF-8" ?><{ key } >foo</{ key } >'
105
107
try :
106
108
parseString (test_xml )
@@ -111,9 +113,10 @@ def key_is_valid_xml(key: str) -> bool:
111
113
112
114
def make_valid_xml_name (key : str , attr : Dict [str , Any ]) -> Tuple [str , Dict [str , Any ]]:
113
115
"""Tests an XML name and fixes it if invalid"""
114
- LOG .info (
115
- f'Inside make_valid_xml_name(). Testing key "{ str (key )} " with attr "{ str (attr )} "'
116
- )
116
+ if DEBUGMODE : # pragma: no cover
117
+ LOG .info (
118
+ f'Inside make_valid_xml_name(). Testing key "{ str (key )} " with attr "{ str (attr )} "'
119
+ )
117
120
key = escape_xml (key )
118
121
# nothing happens at escape_xml if attr is not a string, we don't
119
122
# need to pass it to the method at all.
@@ -162,10 +165,11 @@ def convert(
162
165
) -> str :
163
166
"""Routes the elements of an object to the right function to convert them
164
167
based on their data type"""
165
- LOG .info (f'Inside convert(). type(obj)="{ type (obj ).__name__ } "' )
166
- # avoid cpu consuming object serialization => extra if
167
- if LOG .getEffectiveLevel () <= logging .DEBUG :
168
- LOG .debug (f' obj="{ str (obj )} "' )
168
+ if DEBUGMODE : # pragma: no cover
169
+ LOG .info (f'Inside convert(). type(obj)="{ type (obj ).__name__ } "' )
170
+ # avoid cpu consuming object serialization => extra if
171
+ if LOG .getEffectiveLevel () <= logging .DEBUG :
172
+ LOG .debug (f' obj="{ str (obj )} "' )
169
173
170
174
item_name = item_func (parent )
171
175
# since bool is also a subtype of number.Number and int, the check for bool
@@ -227,12 +231,13 @@ def dict2xml_str(
227
231
parse dict2xml
228
232
"""
229
233
keys_str = ", " .join (str (key ) for key in item )
230
- LOG .info (
231
- f'Inside dict_item2xml_str: type(obj)="{ type (item ).__name__ } ", keys="{ keys_str } "'
232
- )
233
- # avoid cpu consuming object serialization => extra if
234
- if LOG .getEffectiveLevel () <= logging .DEBUG :
235
- LOG .debug (f' item="{ str (item )} "' )
234
+ if DEBUGMODE : # pragma: no cover
235
+ LOG .info (
236
+ f'Inside dict_item2xml_str: type(obj)="{ type (item ).__name__ } ", keys="{ keys_str } "'
237
+ )
238
+ # avoid cpu consuming object serialization => extra if
239
+ if LOG .getEffectiveLevel () <= logging .DEBUG :
240
+ LOG .debug (f' item="{ str (item )} "' )
236
241
237
242
if attr_type :
238
243
attr ["type" ] = get_xml_type (item )
@@ -292,22 +297,24 @@ def convert_dict(
292
297
) -> str :
293
298
"""Converts a dict into an XML string."""
294
299
keys_str = ", " .join (str (key ) for key in obj )
295
- LOG .info (
296
- f'Inside convert_dict(): type(obj)="{ type (obj ).__name__ } ", keys="{ keys_str } "'
297
- )
298
- # avoid cpu consuming object serialization => extra if
299
- if LOG .getEffectiveLevel () <= logging .DEBUG :
300
- LOG .debug (f' obj="{ str (obj )} "' )
300
+ if DEBUGMODE : # pragma: no cover
301
+ LOG .info (
302
+ f'Inside convert_dict(): type(obj)="{ type (obj ).__name__ } ", keys="{ keys_str } "'
303
+ )
304
+ # avoid cpu consuming object serialization => extra if
305
+ if LOG .getEffectiveLevel () <= logging .DEBUG :
306
+ LOG .debug (f' obj="{ str (obj )} "' )
301
307
302
308
output : List [str ] = []
303
309
addline = output .append
304
310
305
311
for key , val in obj .items ():
306
- LOG .info (
307
- f'Looping inside convert_dict(): key="{ str (key )} ", type(val)="{ type (val ).__name__ } "'
308
- )
309
- if LOG .getEffectiveLevel () <= logging .DEBUG :
310
- LOG .debug (f' val="{ str (val )} "' )
312
+ if DEBUGMODE : # pragma: no cover
313
+ LOG .info (
314
+ f'Looping inside convert_dict(): key="{ str (key )} ", type(val)="{ type (val ).__name__ } "'
315
+ )
316
+ if LOG .getEffectiveLevel () <= logging .DEBUG :
317
+ LOG .debug (f' val="{ str (val )} "' )
311
318
312
319
attr = {} if not ids else {"id" : f"{ get_unique_id (parent )} " }
313
320
@@ -377,10 +384,11 @@ def convert_list(
377
384
item_wrap : bool ,
378
385
) -> str :
379
386
"""Converts a list into an XML string."""
380
- LOG .info (f'Inside convert_list(): type(items)="{ type (items ).__name__ } "' )
381
- # avoid cpu consuming object serialization => extra if
382
- if LOG .getEffectiveLevel () <= logging .DEBUG :
383
- LOG .debug (f' items="{ str (items )} "' )
387
+ if DEBUGMODE : # pragma: no cover
388
+ LOG .info (f'Inside convert_list(): type(items)="{ type (items ).__name__ } "' )
389
+ # avoid cpu consuming object serialization => extra if
390
+ if LOG .getEffectiveLevel () <= logging .DEBUG :
391
+ LOG .debug (f' items="{ str (items )} "' )
384
392
385
393
output : List [str ] = []
386
394
addline = output .append
@@ -393,12 +401,13 @@ def convert_list(
393
401
this_id = get_unique_id (parent )
394
402
395
403
for i , item in enumerate (items ):
396
- LOG .info (
397
- f'Looping inside convert_list(): index="{ str (i )} ", type="{ type (item ).__name__ } "'
398
- )
399
- # avoid cpu consuming object serialization => extra if
400
- if LOG .getEffectiveLevel () <= logging .DEBUG :
401
- LOG .debug (f' item="{ str (item )} "' )
404
+ if DEBUGMODE : # pragma: no cover
405
+ LOG .info (
406
+ f'Looping inside convert_list(): index="{ str (i )} ", type="{ type (item ).__name__ } "'
407
+ )
408
+ # avoid cpu consuming object serialization => extra if
409
+ if LOG .getEffectiveLevel () <= logging .DEBUG :
410
+ LOG .debug (f' item="{ str (item )} "' )
402
411
403
412
attr = {} if not ids else {"id" : f"{ this_id } _{ i + 1 } " }
404
413
@@ -474,9 +483,10 @@ def convert_kv(
474
483
cdata : bool = False ,
475
484
) -> str :
476
485
"""Converts a number or string into an XML element"""
477
- LOG .info (
478
- f'Inside convert_kv(): key="{ str (key )} ", val="{ str (val )} ", type(val) is: "{ type (val ).__name__ } "'
479
- )
486
+ if DEBUGMODE : # pragma: no cover
487
+ LOG .info (
488
+ f'Inside convert_kv(): key="{ str (key )} ", val="{ str (val )} ", type(val) is: "{ type (val ).__name__ } "'
489
+ )
480
490
key , attr = make_valid_xml_name (key , attr )
481
491
482
492
if attr_type :
@@ -489,9 +499,10 @@ def convert_bool(
489
499
key : str , val : bool , attr_type : bool , attr : Dict [str , Any ] = {}, cdata : bool = False
490
500
) -> str :
491
501
"""Converts a boolean into an XML element"""
492
- LOG .info (
493
- f'Inside convert_bool(): key="{ str (key )} ", val="{ str (val )} ", type(val) is: "{ type (val ).__name__ } "'
494
- )
502
+ if DEBUGMODE : # pragma: no cover
503
+ LOG .info (
504
+ f'Inside convert_bool(): key="{ str (key )} ", val="{ str (val )} ", type(val) is: "{ type (val ).__name__ } "'
505
+ )
495
506
key , attr = make_valid_xml_name (key , attr )
496
507
497
508
if attr_type :
@@ -504,7 +515,6 @@ def convert_none(
504
515
key : str , attr_type : bool , attr : Dict [str , Any ] = {}, cdata : bool = False
505
516
) -> str :
506
517
"""Converts a null value into an XML element"""
507
- # LOG.info(f'Inside convert_none(): key="{str(key)}" val={type(val)}')
508
518
key , attr = make_valid_xml_name (key , attr )
509
519
510
520
if attr_type :
@@ -554,12 +564,13 @@ def dicttoxml(
554
564
{'list': {'@attrs': {'a':'b','c':'d'}, '@val': [4, 5, 6]}
555
565
which results in <list a="b" c="d"><item>4</item><item>5</item><item>6</item></list>
556
566
"""
557
- LOG .info (
558
- f'Inside dicttoxml(): type(obj) is: "{ type (obj ).__name__ } ", type(ids") is : { type (ids ).__name__ } '
559
- )
560
- # avoid cpu consuming object serialization (problem for large objects) => extra if
561
- if LOG .getEffectiveLevel () <= logging .DEBUG :
562
- LOG .debug (f' obj="{ str (obj )} "' )
567
+ if DEBUGMODE : # pragma: no cover
568
+ LOG .info (
569
+ f'Inside dicttoxml(): type(obj) is: "{ type (obj ).__name__ } ", type(ids") is : { type (ids ).__name__ } '
570
+ )
571
+ # avoid cpu consuming object serialization (problem for large objects) => extra if
572
+ if LOG .getEffectiveLevel () <= logging .DEBUG :
573
+ LOG .debug (f' obj="{ str (obj )} "' )
563
574
564
575
output = []
565
576
namespacestr = ""
0 commit comments