Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-xmltodict for 
openSUSE:Factory checked in at 2022-06-20 15:37:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-xmltodict (Old)
 and      /work/SRC/openSUSE:Factory/.python-xmltodict.new.1548 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-xmltodict"

Mon Jun 20 15:37:03 2022 rev:7 rq:983728 version:0.13.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-xmltodict/python-xmltodict.changes        
2022-02-23 16:25:44.431507307 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-xmltodict.new.1548/python-xmltodict.changes  
    2022-06-20 15:37:25.214872203 +0200
@@ -1,0 +2,17 @@
+Sun Jun 19 17:47:26 UTC 2022 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 0.13.0:
+  * Add install info to readme for openSUSE. (#205)
+  * Support defaultdict for namespace mapping (#211)
+  * parse(generator) is now possible (#212)
+  * Processing comments on parsing from xml to dict (connected to #109) (#221)
+  * Add expand_iter kw to unparse to expand iterables (#213)
+  * Fixed some typos
+  * Add support for python3.8
+  * Drop Jython/Python 2 and add Python 3.9/3.10.
+  * Drop OrderedDict in Python >= 3.7
+  * Do not use len() to determine if a sequence is empty
+  * Add more namespace attribute tests
+  * Fix encoding issue in setup.py
+
+-------------------------------------------------------------------

Old:
----
  xmltodict-0.12.0.tar.gz

New:
----
  xmltodict-0.13.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-xmltodict.spec ++++++
--- /var/tmp/diff_new_pack.BD12JL/_old  2022-06-20 15:37:25.714872934 +0200
+++ /var/tmp/diff_new_pack.BD12JL/_new  2022-06-20 15:37:25.718872939 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-xmltodict
-Version:        0.12.0
+Version:        0.13.0
 Release:        0
 Summary:        Module to make XML working resemble JSON
 License:        MIT

++++++ xmltodict-0.12.0.tar.gz -> xmltodict-0.13.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmltodict-0.12.0/PKG-INFO 
new/xmltodict-0.13.0/PKG-INFO
--- old/xmltodict-0.12.0/PKG-INFO       2019-02-11 08:00:08.000000000 +0100
+++ new/xmltodict-0.13.0/PKG-INFO       2022-05-08 08:59:52.086786000 +0200
@@ -1,232 +1,278 @@
 Metadata-Version: 2.1
 Name: xmltodict
-Version: 0.12.0
+Version: 0.13.0
 Summary: Makes working with XML feel like you are working with JSON
 Home-page: https://github.com/martinblech/xmltodict
 Author: Martin Blech
 Author-email: martinbl...@gmail.com
 License: MIT
-Description: # xmltodict
-        
-        `xmltodict` is a Python module that makes working with XML feel like 
you are working with [JSON](http://docs.python.org/library/json.html), as in 
this 
["spec"](http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html):
-        
-        [![Build 
Status](https://secure.travis-ci.org/martinblech/xmltodict.svg)](http://travis-ci.org/martinblech/xmltodict)
-        
-        ```python
-        >>> print(json.dumps(xmltodict.parse("""
-        ...  <mydocument has="an attribute">
-        ...    <and>
-        ...      <many>elements</many>
-        ...      <many>more elements</many>
-        ...    </and>
-        ...    <plus a="complex">
-        ...      element as well
-        ...    </plus>
-        ...  </mydocument>
-        ...  """), indent=4))
-        {
-            "mydocument": {
-                "@has": "an attribute", 
-                "and": {
-                    "many": [
-                        "elements", 
-                        "more elements"
-                    ]
-                }, 
-                "plus": {
-                    "@a": "complex", 
-                    "#text": "element as well"
-                }
-            }
-        }
-        ```
-        
-        ## Namespace support
-        
-        By default, `xmltodict` does no XML namespace processing (it just 
treats namespace declarations as regular node attributes), but passing 
`process_namespaces=True` will make it expand namespaces for you:
-        
-        ```python
-        >>> xml = """
-        ... <root xmlns="http://defaultns.com/";
-        ...       xmlns:a="http://a.com/";
-        ...       xmlns:b="http://b.com/";>
-        ...   <x>1</x>
-        ...   <a:y>2</a:y>
-        ...   <b:z>3</b:z>
-        ... </root>
-        ... """
-        >>> xmltodict.parse(xml, process_namespaces=True) == {
-        ...     'http://defaultns.com/:root': {
-        ...         'http://defaultns.com/:x': '1',
-        ...         'http://a.com/:y': '2',
-        ...         'http://b.com/:z': '3',
-        ...     }
-        ... }
-        True
-        ```
-        
-        It also lets you collapse certain namespaces to shorthand prefixes, or 
skip them altogether:
-        
-        ```python
-        >>> namespaces = {
-        ...     'http://defaultns.com/': None, # skip this namespace
-        ...     'http://a.com/': 'ns_a', # collapse "http://a.com/"; -> "ns_a"
-        ... }
-        >>> xmltodict.parse(xml, process_namespaces=True, 
namespaces=namespaces) == {
-        ...     'root': {
-        ...         'x': '1',
-        ...         'ns_a:y': '2',
-        ...         'http://b.com/:z': '3',
-        ...     },
-        ... }
-        True
-        ```
-        
-        ## Streaming mode
-        
-        `xmltodict` is very fast 
([Expat](http://docs.python.org/library/pyexpat.html)-based) and has a 
streaming mode with a small memory footprint, suitable for big XML dumps like 
[Discogs](http://discogs.com/data/) or [Wikipedia](http://dumps.wikimedia.org/):
-        
-        ```python
-        >>> def handle_artist(_, artist):
-        ...     print(artist['name'])
-        ...     return True
-        >>> 
-        >>> xmltodict.parse(GzipFile('discogs_artists.xml.gz'),
-        ...     item_depth=2, item_callback=handle_artist)
-        A Perfect Circle
-        Fant??mas
-        King Crimson
-        Chris Potter
-        ...
-        ```
-        
-        It can also be used from the command line to pipe objects to a script 
like this:
-        
-        ```python
-        import sys, marshal
-        while True:
-            _, article = marshal.load(sys.stdin)
-            print(article['title'])
-        ```
-        
-        ```sh
-        $ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | myscript.py
-        AccessibleComputing
-        Anarchism
-        AfghanistanHistory
-        AfghanistanGeography
-        AfghanistanPeople
-        AfghanistanCommunications
-        Autism
-        ...
-        ```
-        
-        Or just cache the dicts so you don't have to parse that big XML file 
again. You do this only once:
-        
-        ```sh
-        $ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | gzip > 
enwiki.dicts.gz
-        ```
-        
-        And you reuse the dicts with every script that needs them:
-        
-        ```sh
-        $ gunzip enwiki.dicts.gz | script1.py
-        $ gunzip enwiki.dicts.gz | script2.py
-        ...
-        ```
-        
-        ## Roundtripping
-        
-        You can also convert in the other direction, using the `unparse()` 
method:
-        
-        ```python
-        >>> mydict = {
-        ...     'response': {
-        ...             'status': 'good',
-        ...             'last_updated': '2014-02-16T23:10:12Z',
-        ...     }
-        ... }
-        >>> print(unparse(mydict, pretty=True))
-        <?xml version="1.0" encoding="utf-8"?>
-        <response>
-               <status>good</status>
-               <last_updated>2014-02-16T23:10:12Z</last_updated>
-        </response>
-        ```
-        
-        Text values for nodes can be specified with the `cdata_key` key in the 
python dict, while node properties can be specified with the `attr_prefix` 
prefixed to the key name in the python dict. The default value for 
`attr_prefix` is `@` and the default value for `cdata_key` is `#text`.
-        
-        ```python
-        >>> import xmltodict
-        >>> 
-        >>> mydict = {
-        ...     'text': {
-        ...         '@color':'red',
-        ...         '@stroke':'2',
-        ...         '#text':'This is a test'
-        ...     }
-        ... }
-        >>> print(xmltodict.unparse(mydict, pretty=True))
-        <?xml version="1.0" encoding="utf-8"?>
-        <text stroke="2" color="red">This is a test</text>
-        ```
-        
-        ## Ok, how do I get it?
-        
-        ### Using pypi
-        
-        You just need to
-        
-        ```sh
-        $ pip install xmltodict
-        ```
-        
-        ### RPM-based distro (Fedora, RHEL, ???)
-        
-        There is an [official Fedora package for 
xmltodict](https://apps.fedoraproject.org/packages/python-xmltodict).
-        
-        ```sh
-        $ sudo yum install python-xmltodict
-        ```
-        
-        ### Arch Linux
-        
-        There is an [official Arch Linux package for 
xmltodict](https://www.archlinux.org/packages/community/any/python-xmltodict/).
-        
-        ```sh
-        $ sudo pacman -S python-xmltodict
-        ```
-        
-        ### Debian-based distro (Debian, Ubuntu, ???)
-        
-        There is an [official Debian package for 
xmltodict](https://tracker.debian.org/pkg/python-xmltodict).
-        
-        ```sh
-        $ sudo apt install python-xmltodict
-        ```
-        
-        ### FreeBSD
-        
-        There is an [official FreeBSD port for 
xmltodict](https://svnweb.freebsd.org/ports/head/devel/py-xmltodict/).
-        
-        ```sh
-        $ pkg install py36-xmltodict
-        ```
-        
 Platform: all
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: Implementation :: Jython
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Text Processing :: Markup :: XML
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
+Requires-Python: >=3.4
 Description-Content-Type: text/markdown
+License-File: LICENSE
+
+# xmltodict
+
+`xmltodict` is a Python module that makes working with XML feel like you are 
working with [JSON](http://docs.python.org/library/json.html), as in this 
["spec"](http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html):
+
+[![Build 
Status](https://travis-ci.com/martinblech/xmltodict.svg?branch=master)](https://travis-ci.com/martinblech/xmltodict)
+
+```python
+>>> print(json.dumps(xmltodict.parse("""
+...  <mydocument has="an attribute">
+...    <and>
+...      <many>elements</many>
+...      <many>more elements</many>
+...    </and>
+...    <plus a="complex">
+...      element as well
+...    </plus>
+...  </mydocument>
+...  """), indent=4))
+{
+    "mydocument": {
+        "@has": "an attribute", 
+        "and": {
+            "many": [
+                "elements", 
+                "more elements"
+            ]
+        }, 
+        "plus": {
+            "@a": "complex", 
+            "#text": "element as well"
+        }
+    }
+}
+```
+
+## Namespace support
+
+By default, `xmltodict` does no XML namespace processing (it just treats 
namespace declarations as regular node attributes), but passing 
`process_namespaces=True` will make it expand namespaces for you:
+
+```python
+>>> xml = """
+... <root xmlns="http://defaultns.com/";
+...       xmlns:a="http://a.com/";
+...       xmlns:b="http://b.com/";>
+...   <x>1</x>
+...   <a:y>2</a:y>
+...   <b:z>3</b:z>
+... </root>
+... """
+>>> xmltodict.parse(xml, process_namespaces=True) == {
+...     'http://defaultns.com/:root': {
+...         'http://defaultns.com/:x': '1',
+...         'http://a.com/:y': '2',
+...         'http://b.com/:z': '3',
+...     }
+... }
+True
+```
+
+It also lets you collapse certain namespaces to shorthand prefixes, or skip 
them altogether:
+
+```python
+>>> namespaces = {
+...     'http://defaultns.com/': None, # skip this namespace
+...     'http://a.com/': 'ns_a', # collapse "http://a.com/"; -> "ns_a"
+... }
+>>> xmltodict.parse(xml, process_namespaces=True, namespaces=namespaces) == {
+...     'root': {
+...         'x': '1',
+...         'ns_a:y': '2',
+...         'http://b.com/:z': '3',
+...     },
+... }
+True
+```
+
+## Streaming mode
+
+`xmltodict` is very fast 
([Expat](http://docs.python.org/library/pyexpat.html)-based) and has a 
streaming mode with a small memory footprint, suitable for big XML dumps like 
[Discogs](http://discogs.com/data/) or [Wikipedia](http://dumps.wikimedia.org/):
+
+```python
+>>> def handle_artist(_, artist):
+...     print(artist['name'])
+...     return True
+>>> 
+>>> xmltodict.parse(GzipFile('discogs_artists.xml.gz'),
+...     item_depth=2, item_callback=handle_artist)
+A Perfect Circle
+Fant??mas
+King Crimson
+Chris Potter
+...
+```
+
+It can also be used from the command line to pipe objects to a script like 
this:
+
+```python
+import sys, marshal
+while True:
+    _, article = marshal.load(sys.stdin)
+    print(article['title'])
+```
+
+```sh
+$ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | myscript.py
+AccessibleComputing
+Anarchism
+AfghanistanHistory
+AfghanistanGeography
+AfghanistanPeople
+AfghanistanCommunications
+Autism
+...
+```
+
+Or just cache the dicts so you don't have to parse that big XML file again. 
You do this only once:
+
+```sh
+$ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | gzip > 
enwiki.dicts.gz
+```
+
+And you reuse the dicts with every script that needs them:
+
+```sh
+$ gunzip enwiki.dicts.gz | script1.py
+$ gunzip enwiki.dicts.gz | script2.py
+...
+```
+
+## Roundtripping
+
+You can also convert in the other direction, using the `unparse()` method:
+
+```python
+>>> mydict = {
+...     'response': {
+...             'status': 'good',
+...             'last_updated': '2014-02-16T23:10:12Z',
+...     }
+... }
+>>> print(unparse(mydict, pretty=True))
+<?xml version="1.0" encoding="utf-8"?>
+<response>
+       <status>good</status>
+       <last_updated>2014-02-16T23:10:12Z</last_updated>
+</response>
+```
+
+Text values for nodes can be specified with the `cdata_key` key in the python 
dict, while node properties can be specified with the `attr_prefix` prefixed to 
the key name in the python dict. The default value for `attr_prefix` is `@` and 
the default value for `cdata_key` is `#text`.
+
+```python
+>>> import xmltodict
+>>> 
+>>> mydict = {
+...     'text': {
+...         '@color':'red',
+...         '@stroke':'2',
+...         '#text':'This is a test'
+...     }
+... }
+>>> print(xmltodict.unparse(mydict, pretty=True))
+<?xml version="1.0" encoding="utf-8"?>
+<text stroke="2" color="red">This is a test</text>
+```
+
+Lists that are specified under a key in a dictionary use the key as a tag for 
each item. But if a list does have a parent key, for example if a list exists 
inside another list, it does not have a tag to use and the items are converted 
to a string as shown in the example below.  To give tags to nested lists, use 
the `expand_iter` keyword argument to provide a tag as demonstrated below. Note 
that using `expand_iter` will break roundtripping.
+
+```python
+>>> mydict = {
+...     "line": {
+...         "points": [
+...             [1, 5],
+...             [2, 6],
+...         ]
+...     }
+... }
+>>> print(xmltodict.unparse(mydict, pretty=True))
+<?xml version="1.0" encoding="utf-8"?>
+<line>
+        <points>[1, 5]</points>
+        <points>[2, 6]</points>
+</line>
+>>> print(xmltodict.unparse(mydict, pretty=True, expand_iter="coord"))
+<?xml version="1.0" encoding="utf-8"?>
+<line>
+        <points>
+                <coord>1</coord>
+                <coord>5</coord>
+        </points>
+        <points>
+                <coord>2</coord>
+                <coord>6</coord>
+        </points>
+</line>
+```
+
+## Ok, how do I get it?
+
+### Using pypi
+
+You just need to
+
+```sh
+$ pip install xmltodict
+```
+
+### RPM-based distro (Fedora, RHEL, ???)
+
+There is an [official Fedora package for 
xmltodict](https://apps.fedoraproject.org/packages/python-xmltodict).
+
+```sh
+$ sudo yum install python-xmltodict
+```
+
+### Arch Linux
+
+There is an [official Arch Linux package for 
xmltodict](https://www.archlinux.org/packages/community/any/python-xmltodict/).
+
+```sh
+$ sudo pacman -S python-xmltodict
+```
+
+### Debian-based distro (Debian, Ubuntu, ???)
+
+There is an [official Debian package for 
xmltodict](https://tracker.debian.org/pkg/python-xmltodict).
+
+```sh
+$ sudo apt install python-xmltodict
+```
+
+### FreeBSD
+
+There is an [official FreeBSD port for 
xmltodict](https://svnweb.freebsd.org/ports/head/devel/py-xmltodict/).
+
+```sh
+$ pkg install py36-xmltodict
+```
+
+### openSUSE/SLE (SLE 15, Leap 15, Tumbleweed)
+
+There is an [official openSUSE package for 
xmltodict](https://software.opensuse.org/package/python-xmltodict).
+
+```sh
+# Python2
+$ zypper in python2-xmltodict
+
+# Python3
+$ zypper in python3-xmltodict
+```
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmltodict-0.12.0/README.md 
new/xmltodict-0.13.0/README.md
--- old/xmltodict-0.12.0/README.md      2019-02-11 07:36:33.000000000 +0100
+++ new/xmltodict-0.13.0/README.md      2019-12-08 10:15:13.000000000 +0100
@@ -2,7 +2,7 @@
 
 `xmltodict` is a Python module that makes working with XML feel like you are 
working with [JSON](http://docs.python.org/library/json.html), as in this 
["spec"](http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html):
 
-[![Build 
Status](https://secure.travis-ci.org/martinblech/xmltodict.svg)](http://travis-ci.org/martinblech/xmltodict)
+[![Build 
Status](https://travis-ci.com/martinblech/xmltodict.svg?branch=master)](https://travis-ci.com/martinblech/xmltodict)
 
 ```python
 >>> print(json.dumps(xmltodict.parse("""
@@ -163,6 +163,37 @@
 <text stroke="2" color="red">This is a test</text>
 ```
 
+Lists that are specified under a key in a dictionary use the key as a tag for 
each item. But if a list does have a parent key, for example if a list exists 
inside another list, it does not have a tag to use and the items are converted 
to a string as shown in the example below.  To give tags to nested lists, use 
the `expand_iter` keyword argument to provide a tag as demonstrated below. Note 
that using `expand_iter` will break roundtripping.
+
+```python
+>>> mydict = {
+...     "line": {
+...         "points": [
+...             [1, 5],
+...             [2, 6],
+...         ]
+...     }
+... }
+>>> print(xmltodict.unparse(mydict, pretty=True))
+<?xml version="1.0" encoding="utf-8"?>
+<line>
+        <points>[1, 5]</points>
+        <points>[2, 6]</points>
+</line>
+>>> print(xmltodict.unparse(mydict, pretty=True, expand_iter="coord"))
+<?xml version="1.0" encoding="utf-8"?>
+<line>
+        <points>
+                <coord>1</coord>
+                <coord>5</coord>
+        </points>
+        <points>
+                <coord>2</coord>
+                <coord>6</coord>
+        </points>
+</line>
+```
+
 ## Ok, how do I get it?
 
 ### Using pypi
@@ -204,3 +235,15 @@
 ```sh
 $ pkg install py36-xmltodict
 ```
+
+### openSUSE/SLE (SLE 15, Leap 15, Tumbleweed)
+
+There is an [official openSUSE package for 
xmltodict](https://software.opensuse.org/package/python-xmltodict).
+
+```sh
+# Python2
+$ zypper in python2-xmltodict
+
+# Python3
+$ zypper in python3-xmltodict
+```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmltodict-0.12.0/setup.py 
new/xmltodict-0.13.0/setup.py
--- old/xmltodict-0.12.0/setup.py       2019-02-11 07:36:33.000000000 +0100
+++ new/xmltodict-0.13.0/setup.py       2022-05-08 08:49:17.000000000 +0200
@@ -8,8 +8,8 @@
 
 import xmltodict
 
-with open('README.md') as f:
-    long_description = f.read()
+with open('README.md', 'rb') as f:
+    long_description = f.read().decode('utf-8')
 
 
 setup(name='xmltodict',
@@ -22,23 +22,23 @@
       url='https://github.com/martinblech/xmltodict',
       license=xmltodict.__license__,
       platforms=['all'],
-      python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
+      python_requires='>=3.4',
       classifiers=[
           'Intended Audience :: Developers',
           'License :: OSI Approved :: MIT License',
           'Operating System :: OS Independent',
           'Programming Language :: Python',
-          'Programming Language :: Python :: 2',
-          'Programming Language :: Python :: 2.7',
           'Programming Language :: Python :: 3',
           'Programming Language :: Python :: 3.4',
           'Programming Language :: Python :: 3.5',
           'Programming Language :: Python :: 3.6',
           'Programming Language :: Python :: 3.7',
-          'Programming Language :: Python :: Implementation :: Jython',
+          'Programming Language :: Python :: 3.8',
+          'Programming Language :: Python :: 3.9',
+          'Programming Language :: Python :: 3.10',
           'Programming Language :: Python :: Implementation :: PyPy',
           'Topic :: Text Processing :: Markup :: XML',
       ],
       py_modules=['xmltodict'],
-      tests_require=['nose>=1.0', 'coverage'],
+      tests_require=['nose2', 'coverage'],
       )
Binary files 
old/xmltodict-0.12.0/tests/__pycache__/test_dicttoxml.cpython-310.pyc and 
new/xmltodict-0.13.0/tests/__pycache__/test_dicttoxml.cpython-310.pyc differ
Binary files 
old/xmltodict-0.12.0/tests/__pycache__/test_dicttoxml.cpython-37.pyc and 
new/xmltodict-0.13.0/tests/__pycache__/test_dicttoxml.cpython-37.pyc differ
Binary files 
old/xmltodict-0.12.0/tests/__pycache__/test_dicttoxml.cpython-39.pyc and 
new/xmltodict-0.13.0/tests/__pycache__/test_dicttoxml.cpython-39.pyc differ
Binary files 
old/xmltodict-0.12.0/tests/__pycache__/test_xmltodict.cpython-310.pyc and 
new/xmltodict-0.13.0/tests/__pycache__/test_xmltodict.cpython-310.pyc differ
Binary files 
old/xmltodict-0.12.0/tests/__pycache__/test_xmltodict.cpython-37.pyc and 
new/xmltodict-0.13.0/tests/__pycache__/test_xmltodict.cpython-37.pyc differ
Binary files 
old/xmltodict-0.12.0/tests/__pycache__/test_xmltodict.cpython-39.pyc and 
new/xmltodict-0.13.0/tests/__pycache__/test_xmltodict.cpython-39.pyc differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmltodict-0.12.0/tests/test_dicttoxml.py 
new/xmltodict-0.13.0/tests/test_dicttoxml.py
--- old/xmltodict-0.12.0/tests/test_dicttoxml.py        2019-02-11 
07:36:33.000000000 +0100
+++ new/xmltodict-0.13.0/tests/test_dicttoxml.py        2019-12-08 
10:15:13.000000000 +0100
@@ -46,6 +46,14 @@
         self.assertEqual(obj, parse(unparse(obj)))
         self.assertEqual(unparse(obj), unparse(parse(unparse(obj))))
 
+    def test_list_expand_iter(self):
+        obj = {'a': {'b': [['1', '2'], ['3',]]}}
+        #self.assertEqual(obj, parse(unparse(obj, expand_iter="item")))
+        exp_xml = dedent('''\
+        <?xml version="1.0" encoding="utf-8"?>
+        <a><b><item>1</item><item>2</item></b><b><item>3</item></b></a>''')
+        self.assertEqual(exp_xml, unparse(obj, expand_iter="item"))
+
     def test_generator(self):
         obj = {'a': {'b': ['1', '2', '3']}}
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmltodict-0.12.0/tests/test_xmltodict.py 
new/xmltodict-0.13.0/tests/test_xmltodict.py
--- old/xmltodict-0.12.0/tests/test_xmltodict.py        2019-02-11 
07:36:33.000000000 +0100
+++ new/xmltodict-0.13.0/tests/test_xmltodict.py        2022-05-08 
08:49:17.000000000 +0200
@@ -1,4 +1,5 @@
 from xmltodict import parse, ParsingInterrupted
+import collections
 import unittest
 
 try:
@@ -119,6 +120,17 @@
                           parse, '<a>x</a>',
                           item_depth=1, item_callback=cb)
 
+    def test_streaming_generator(self):
+        def cb(path, item):
+            cb.count += 1
+            self.assertEqual(path, [('a', {'x': 'y'}), ('b', None)])
+            self.assertEqual(item, str(cb.count))
+            return True
+        cb.count = 0
+        parse((n for n in '<a x="y"><b>1</b><b>2</b><b>3</b></a>'),
+              item_depth=2, item_callback=cb)
+        self.assertEqual(cb.count, 3)
+
     def test_postprocessor(self):
         def postprocessor(path, key, value):
             try:
@@ -171,7 +183,8 @@
         xml = """
         <root xmlns="http://defaultns.com/";
               xmlns:a="http://a.com/";
-              xmlns:b="http://b.com/";>
+              xmlns:b="http://b.com/";
+              version="1.00">
           <x a:attr="val">1</x>
           <a:y>2</a:y>
           <b:z>3</b:z>
@@ -179,12 +192,13 @@
         """
         d = {
             'http://defaultns.com/:root': {
+                '@version': '1.00',
+                '@xmlns': {
+                    '': 'http://defaultns.com/',
+                    'a': 'http://a.com/',
+                    'b': 'http://b.com/',
+                },
                 'http://defaultns.com/:x': {
-                    '@xmlns': {
-                        '': 'http://defaultns.com/',
-                        'a': 'http://a.com/',
-                        'b': 'http://b.com/',
-                    },
                     '@http://a.com/:attr': 'val',
                     '#text': '1',
                 },
@@ -199,7 +213,8 @@
         xml = """
         <root xmlns="http://defaultns.com/";
               xmlns:a="http://a.com/";
-              xmlns:b="http://b.com/";>
+              xmlns:b="http://b.com/";
+              version="1.00">
           <x a:attr="val">1</x>
           <a:y>2</a:y>
           <b:z>3</b:z>
@@ -211,12 +226,13 @@
         }
         d = {
             'root': {
+                '@version': '1.00',
+                '@xmlns': {
+                    '': 'http://defaultns.com/',
+                    'a': 'http://a.com/',
+                    'b': 'http://b.com/',
+                },
                 'x': {
-                    '@xmlns': {
-                        '': 'http://defaultns.com/',
-                        'a': 'http://a.com/',
-                        'b': 'http://b.com/',
-                    },
                     '@ns_a:attr': 'val',
                     '#text': '1',
                 },
@@ -227,11 +243,43 @@
         res = parse(xml, process_namespaces=True, namespaces=namespaces)
         self.assertEqual(res, d)
 
+    def test_namespace_collapse_all(self):
+        xml = """
+        <root xmlns="http://defaultns.com/";
+              xmlns:a="http://a.com/";
+              xmlns:b="http://b.com/";
+              version="1.00">
+          <x a:attr="val">1</x>
+          <a:y>2</a:y>
+          <b:z>3</b:z>
+        </root>
+        """
+        namespaces = collections.defaultdict(lambda: None)
+        d = {
+            'root': {
+                '@version': '1.00',
+                '@xmlns': {
+                    '': 'http://defaultns.com/',
+                    'a': 'http://a.com/',
+                    'b': 'http://b.com/',
+                },
+                'x': {
+                    '@attr': 'val',
+                    '#text': '1',
+                },
+                'y': '2',
+                'z': '3',
+            },
+        }
+        res = parse(xml, process_namespaces=True, namespaces=namespaces)
+        self.assertEqual(res, d)
+
     def test_namespace_ignore(self):
         xml = """
         <root xmlns="http://defaultns.com/";
               xmlns:a="http://a.com/";
-              xmlns:b="http://b.com/";>
+              xmlns:b="http://b.com/";
+              version="1.00">
           <x>1</x>
           <a:y>2</a:y>
           <b:z>3</b:z>
@@ -242,6 +290,7 @@
                 '@xmlns': 'http://defaultns.com/',
                 '@xmlns:a': 'http://a.com/',
                 '@xmlns:b': 'http://b.com/',
+                '@version': '1.00',
                 'x': '1',
                 'a:y': '2',
                 'b:z': '3',
@@ -380,3 +429,31 @@
         else:
             self.assertTrue(False)
         expat.ParserCreate = ParserCreate
+
+    def test_comments(self):
+        xml = """
+        <a>
+          <b>
+            <!-- b comment -->
+            <c>
+                <!-- c comment -->
+                1
+            </c>
+            <d>2</d>
+          </b>
+        </a>
+        """
+        expectedResult = {
+            'a': {
+                'b': {
+                    '#comment': 'b comment',
+                    'c': {
+
+                        '#comment': 'c comment',
+                        '#text': '1',
+                    },
+                    'd': '2',
+                },
+            }
+        }
+        self.assertEqual(parse(xml, process_comments=True), expectedResult)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmltodict-0.12.0/xmltodict.egg-info/PKG-INFO 
new/xmltodict-0.13.0/xmltodict.egg-info/PKG-INFO
--- old/xmltodict-0.12.0/xmltodict.egg-info/PKG-INFO    2019-02-11 
08:00:08.000000000 +0100
+++ new/xmltodict-0.13.0/xmltodict.egg-info/PKG-INFO    2022-05-08 
08:59:51.000000000 +0200
@@ -1,232 +1,278 @@
 Metadata-Version: 2.1
 Name: xmltodict
-Version: 0.12.0
+Version: 0.13.0
 Summary: Makes working with XML feel like you are working with JSON
 Home-page: https://github.com/martinblech/xmltodict
 Author: Martin Blech
 Author-email: martinbl...@gmail.com
 License: MIT
-Description: # xmltodict
-        
-        `xmltodict` is a Python module that makes working with XML feel like 
you are working with [JSON](http://docs.python.org/library/json.html), as in 
this 
["spec"](http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html):
-        
-        [![Build 
Status](https://secure.travis-ci.org/martinblech/xmltodict.svg)](http://travis-ci.org/martinblech/xmltodict)
-        
-        ```python
-        >>> print(json.dumps(xmltodict.parse("""
-        ...  <mydocument has="an attribute">
-        ...    <and>
-        ...      <many>elements</many>
-        ...      <many>more elements</many>
-        ...    </and>
-        ...    <plus a="complex">
-        ...      element as well
-        ...    </plus>
-        ...  </mydocument>
-        ...  """), indent=4))
-        {
-            "mydocument": {
-                "@has": "an attribute", 
-                "and": {
-                    "many": [
-                        "elements", 
-                        "more elements"
-                    ]
-                }, 
-                "plus": {
-                    "@a": "complex", 
-                    "#text": "element as well"
-                }
-            }
-        }
-        ```
-        
-        ## Namespace support
-        
-        By default, `xmltodict` does no XML namespace processing (it just 
treats namespace declarations as regular node attributes), but passing 
`process_namespaces=True` will make it expand namespaces for you:
-        
-        ```python
-        >>> xml = """
-        ... <root xmlns="http://defaultns.com/";
-        ...       xmlns:a="http://a.com/";
-        ...       xmlns:b="http://b.com/";>
-        ...   <x>1</x>
-        ...   <a:y>2</a:y>
-        ...   <b:z>3</b:z>
-        ... </root>
-        ... """
-        >>> xmltodict.parse(xml, process_namespaces=True) == {
-        ...     'http://defaultns.com/:root': {
-        ...         'http://defaultns.com/:x': '1',
-        ...         'http://a.com/:y': '2',
-        ...         'http://b.com/:z': '3',
-        ...     }
-        ... }
-        True
-        ```
-        
-        It also lets you collapse certain namespaces to shorthand prefixes, or 
skip them altogether:
-        
-        ```python
-        >>> namespaces = {
-        ...     'http://defaultns.com/': None, # skip this namespace
-        ...     'http://a.com/': 'ns_a', # collapse "http://a.com/"; -> "ns_a"
-        ... }
-        >>> xmltodict.parse(xml, process_namespaces=True, 
namespaces=namespaces) == {
-        ...     'root': {
-        ...         'x': '1',
-        ...         'ns_a:y': '2',
-        ...         'http://b.com/:z': '3',
-        ...     },
-        ... }
-        True
-        ```
-        
-        ## Streaming mode
-        
-        `xmltodict` is very fast 
([Expat](http://docs.python.org/library/pyexpat.html)-based) and has a 
streaming mode with a small memory footprint, suitable for big XML dumps like 
[Discogs](http://discogs.com/data/) or [Wikipedia](http://dumps.wikimedia.org/):
-        
-        ```python
-        >>> def handle_artist(_, artist):
-        ...     print(artist['name'])
-        ...     return True
-        >>> 
-        >>> xmltodict.parse(GzipFile('discogs_artists.xml.gz'),
-        ...     item_depth=2, item_callback=handle_artist)
-        A Perfect Circle
-        Fant??mas
-        King Crimson
-        Chris Potter
-        ...
-        ```
-        
-        It can also be used from the command line to pipe objects to a script 
like this:
-        
-        ```python
-        import sys, marshal
-        while True:
-            _, article = marshal.load(sys.stdin)
-            print(article['title'])
-        ```
-        
-        ```sh
-        $ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | myscript.py
-        AccessibleComputing
-        Anarchism
-        AfghanistanHistory
-        AfghanistanGeography
-        AfghanistanPeople
-        AfghanistanCommunications
-        Autism
-        ...
-        ```
-        
-        Or just cache the dicts so you don't have to parse that big XML file 
again. You do this only once:
-        
-        ```sh
-        $ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | gzip > 
enwiki.dicts.gz
-        ```
-        
-        And you reuse the dicts with every script that needs them:
-        
-        ```sh
-        $ gunzip enwiki.dicts.gz | script1.py
-        $ gunzip enwiki.dicts.gz | script2.py
-        ...
-        ```
-        
-        ## Roundtripping
-        
-        You can also convert in the other direction, using the `unparse()` 
method:
-        
-        ```python
-        >>> mydict = {
-        ...     'response': {
-        ...             'status': 'good',
-        ...             'last_updated': '2014-02-16T23:10:12Z',
-        ...     }
-        ... }
-        >>> print(unparse(mydict, pretty=True))
-        <?xml version="1.0" encoding="utf-8"?>
-        <response>
-               <status>good</status>
-               <last_updated>2014-02-16T23:10:12Z</last_updated>
-        </response>
-        ```
-        
-        Text values for nodes can be specified with the `cdata_key` key in the 
python dict, while node properties can be specified with the `attr_prefix` 
prefixed to the key name in the python dict. The default value for 
`attr_prefix` is `@` and the default value for `cdata_key` is `#text`.
-        
-        ```python
-        >>> import xmltodict
-        >>> 
-        >>> mydict = {
-        ...     'text': {
-        ...         '@color':'red',
-        ...         '@stroke':'2',
-        ...         '#text':'This is a test'
-        ...     }
-        ... }
-        >>> print(xmltodict.unparse(mydict, pretty=True))
-        <?xml version="1.0" encoding="utf-8"?>
-        <text stroke="2" color="red">This is a test</text>
-        ```
-        
-        ## Ok, how do I get it?
-        
-        ### Using pypi
-        
-        You just need to
-        
-        ```sh
-        $ pip install xmltodict
-        ```
-        
-        ### RPM-based distro (Fedora, RHEL, ???)
-        
-        There is an [official Fedora package for 
xmltodict](https://apps.fedoraproject.org/packages/python-xmltodict).
-        
-        ```sh
-        $ sudo yum install python-xmltodict
-        ```
-        
-        ### Arch Linux
-        
-        There is an [official Arch Linux package for 
xmltodict](https://www.archlinux.org/packages/community/any/python-xmltodict/).
-        
-        ```sh
-        $ sudo pacman -S python-xmltodict
-        ```
-        
-        ### Debian-based distro (Debian, Ubuntu, ???)
-        
-        There is an [official Debian package for 
xmltodict](https://tracker.debian.org/pkg/python-xmltodict).
-        
-        ```sh
-        $ sudo apt install python-xmltodict
-        ```
-        
-        ### FreeBSD
-        
-        There is an [official FreeBSD port for 
xmltodict](https://svnweb.freebsd.org/ports/head/devel/py-xmltodict/).
-        
-        ```sh
-        $ pkg install py36-xmltodict
-        ```
-        
 Platform: all
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: Implementation :: Jython
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Text Processing :: Markup :: XML
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
+Requires-Python: >=3.4
 Description-Content-Type: text/markdown
+License-File: LICENSE
+
+# xmltodict
+
+`xmltodict` is a Python module that makes working with XML feel like you are 
working with [JSON](http://docs.python.org/library/json.html), as in this 
["spec"](http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html):
+
+[![Build 
Status](https://travis-ci.com/martinblech/xmltodict.svg?branch=master)](https://travis-ci.com/martinblech/xmltodict)
+
+```python
+>>> print(json.dumps(xmltodict.parse("""
+...  <mydocument has="an attribute">
+...    <and>
+...      <many>elements</many>
+...      <many>more elements</many>
+...    </and>
+...    <plus a="complex">
+...      element as well
+...    </plus>
+...  </mydocument>
+...  """), indent=4))
+{
+    "mydocument": {
+        "@has": "an attribute", 
+        "and": {
+            "many": [
+                "elements", 
+                "more elements"
+            ]
+        }, 
+        "plus": {
+            "@a": "complex", 
+            "#text": "element as well"
+        }
+    }
+}
+```
+
+## Namespace support
+
+By default, `xmltodict` does no XML namespace processing (it just treats 
namespace declarations as regular node attributes), but passing 
`process_namespaces=True` will make it expand namespaces for you:
+
+```python
+>>> xml = """
+... <root xmlns="http://defaultns.com/";
+...       xmlns:a="http://a.com/";
+...       xmlns:b="http://b.com/";>
+...   <x>1</x>
+...   <a:y>2</a:y>
+...   <b:z>3</b:z>
+... </root>
+... """
+>>> xmltodict.parse(xml, process_namespaces=True) == {
+...     'http://defaultns.com/:root': {
+...         'http://defaultns.com/:x': '1',
+...         'http://a.com/:y': '2',
+...         'http://b.com/:z': '3',
+...     }
+... }
+True
+```
+
+It also lets you collapse certain namespaces to shorthand prefixes, or skip 
them altogether:
+
+```python
+>>> namespaces = {
+...     'http://defaultns.com/': None, # skip this namespace
+...     'http://a.com/': 'ns_a', # collapse "http://a.com/"; -> "ns_a"
+... }
+>>> xmltodict.parse(xml, process_namespaces=True, namespaces=namespaces) == {
+...     'root': {
+...         'x': '1',
+...         'ns_a:y': '2',
+...         'http://b.com/:z': '3',
+...     },
+... }
+True
+```
+
+## Streaming mode
+
+`xmltodict` is very fast 
([Expat](http://docs.python.org/library/pyexpat.html)-based) and has a 
streaming mode with a small memory footprint, suitable for big XML dumps like 
[Discogs](http://discogs.com/data/) or [Wikipedia](http://dumps.wikimedia.org/):
+
+```python
+>>> def handle_artist(_, artist):
+...     print(artist['name'])
+...     return True
+>>> 
+>>> xmltodict.parse(GzipFile('discogs_artists.xml.gz'),
+...     item_depth=2, item_callback=handle_artist)
+A Perfect Circle
+Fant??mas
+King Crimson
+Chris Potter
+...
+```
+
+It can also be used from the command line to pipe objects to a script like 
this:
+
+```python
+import sys, marshal
+while True:
+    _, article = marshal.load(sys.stdin)
+    print(article['title'])
+```
+
+```sh
+$ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | myscript.py
+AccessibleComputing
+Anarchism
+AfghanistanHistory
+AfghanistanGeography
+AfghanistanPeople
+AfghanistanCommunications
+Autism
+...
+```
+
+Or just cache the dicts so you don't have to parse that big XML file again. 
You do this only once:
+
+```sh
+$ bunzip2 enwiki-pages-articles.xml.bz2 | xmltodict.py 2 | gzip > 
enwiki.dicts.gz
+```
+
+And you reuse the dicts with every script that needs them:
+
+```sh
+$ gunzip enwiki.dicts.gz | script1.py
+$ gunzip enwiki.dicts.gz | script2.py
+...
+```
+
+## Roundtripping
+
+You can also convert in the other direction, using the `unparse()` method:
+
+```python
+>>> mydict = {
+...     'response': {
+...             'status': 'good',
+...             'last_updated': '2014-02-16T23:10:12Z',
+...     }
+... }
+>>> print(unparse(mydict, pretty=True))
+<?xml version="1.0" encoding="utf-8"?>
+<response>
+       <status>good</status>
+       <last_updated>2014-02-16T23:10:12Z</last_updated>
+</response>
+```
+
+Text values for nodes can be specified with the `cdata_key` key in the python 
dict, while node properties can be specified with the `attr_prefix` prefixed to 
the key name in the python dict. The default value for `attr_prefix` is `@` and 
the default value for `cdata_key` is `#text`.
+
+```python
+>>> import xmltodict
+>>> 
+>>> mydict = {
+...     'text': {
+...         '@color':'red',
+...         '@stroke':'2',
+...         '#text':'This is a test'
+...     }
+... }
+>>> print(xmltodict.unparse(mydict, pretty=True))
+<?xml version="1.0" encoding="utf-8"?>
+<text stroke="2" color="red">This is a test</text>
+```
+
+Lists that are specified under a key in a dictionary use the key as a tag for 
each item. But if a list does have a parent key, for example if a list exists 
inside another list, it does not have a tag to use and the items are converted 
to a string as shown in the example below.  To give tags to nested lists, use 
the `expand_iter` keyword argument to provide a tag as demonstrated below. Note 
that using `expand_iter` will break roundtripping.
+
+```python
+>>> mydict = {
+...     "line": {
+...         "points": [
+...             [1, 5],
+...             [2, 6],
+...         ]
+...     }
+... }
+>>> print(xmltodict.unparse(mydict, pretty=True))
+<?xml version="1.0" encoding="utf-8"?>
+<line>
+        <points>[1, 5]</points>
+        <points>[2, 6]</points>
+</line>
+>>> print(xmltodict.unparse(mydict, pretty=True, expand_iter="coord"))
+<?xml version="1.0" encoding="utf-8"?>
+<line>
+        <points>
+                <coord>1</coord>
+                <coord>5</coord>
+        </points>
+        <points>
+                <coord>2</coord>
+                <coord>6</coord>
+        </points>
+</line>
+```
+
+## Ok, how do I get it?
+
+### Using pypi
+
+You just need to
+
+```sh
+$ pip install xmltodict
+```
+
+### RPM-based distro (Fedora, RHEL, ???)
+
+There is an [official Fedora package for 
xmltodict](https://apps.fedoraproject.org/packages/python-xmltodict).
+
+```sh
+$ sudo yum install python-xmltodict
+```
+
+### Arch Linux
+
+There is an [official Arch Linux package for 
xmltodict](https://www.archlinux.org/packages/community/any/python-xmltodict/).
+
+```sh
+$ sudo pacman -S python-xmltodict
+```
+
+### Debian-based distro (Debian, Ubuntu, ???)
+
+There is an [official Debian package for 
xmltodict](https://tracker.debian.org/pkg/python-xmltodict).
+
+```sh
+$ sudo apt install python-xmltodict
+```
+
+### FreeBSD
+
+There is an [official FreeBSD port for 
xmltodict](https://svnweb.freebsd.org/ports/head/devel/py-xmltodict/).
+
+```sh
+$ pkg install py36-xmltodict
+```
+
+### openSUSE/SLE (SLE 15, Leap 15, Tumbleweed)
+
+There is an [official openSUSE package for 
xmltodict](https://software.opensuse.org/package/python-xmltodict).
+
+```sh
+# Python2
+$ zypper in python2-xmltodict
+
+# Python3
+$ zypper in python3-xmltodict
+```
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmltodict-0.12.0/xmltodict.egg-info/SOURCES.txt 
new/xmltodict-0.13.0/xmltodict.egg-info/SOURCES.txt
--- old/xmltodict-0.12.0/xmltodict.egg-info/SOURCES.txt 2019-02-11 
08:00:08.000000000 +0100
+++ new/xmltodict-0.13.0/xmltodict.egg-info/SOURCES.txt 2022-05-08 
08:59:52.000000000 +0200
@@ -7,6 +7,12 @@
 xmltodict.py
 tests/test_dicttoxml.py
 tests/test_xmltodict.py
+tests/__pycache__/test_dicttoxml.cpython-310.pyc
+tests/__pycache__/test_dicttoxml.cpython-37.pyc
+tests/__pycache__/test_dicttoxml.cpython-39.pyc
+tests/__pycache__/test_xmltodict.cpython-310.pyc
+tests/__pycache__/test_xmltodict.cpython-37.pyc
+tests/__pycache__/test_xmltodict.cpython-39.pyc
 xmltodict.egg-info/PKG-INFO
 xmltodict.egg-info/SOURCES.txt
 xmltodict.egg-info/dependency_links.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/xmltodict-0.12.0/xmltodict.py 
new/xmltodict-0.13.0/xmltodict.py
--- old/xmltodict-0.12.0/xmltodict.py   2019-02-11 07:57:59.000000000 +0100
+++ new/xmltodict-0.13.0/xmltodict.py   2022-05-08 08:49:17.000000000 +0200
@@ -15,7 +15,12 @@
     except ImportError:
         from io import StringIO
 
-from collections import OrderedDict
+_dict = dict
+import platform
+if tuple(map(int, platform.python_version_tuple()[:2])) < (3, 7):
+    from collections import OrderedDict as _dict
+
+from inspect import isgenerator
 
 try:  # pragma no cover
     _basestring = basestring
@@ -27,7 +32,7 @@
     _unicode = str
 
 __author__ = 'Martin Blech'
-__version__ = '0.12.0'
+__version__ = '0.13.0'
 __license__ = 'MIT'
 
 
@@ -45,11 +50,12 @@
                  force_cdata=False,
                  cdata_separator='',
                  postprocessor=None,
-                 dict_constructor=OrderedDict,
+                 dict_constructor=_dict,
                  strip_whitespace=True,
                  namespace_separator=':',
                  namespaces=None,
-                 force_list=None):
+                 force_list=None,
+                 comment_key='#comment'):
         self.path = []
         self.stack = []
         self.data = []
@@ -66,17 +72,21 @@
         self.strip_whitespace = strip_whitespace
         self.namespace_separator = namespace_separator
         self.namespaces = namespaces
-        self.namespace_declarations = OrderedDict()
+        self.namespace_declarations = dict_constructor()
         self.force_list = force_list
+        self.comment_key = comment_key
 
     def _build_name(self, full_name):
-        if not self.namespaces:
+        if self.namespaces is None:
             return full_name
         i = full_name.rfind(self.namespace_separator)
         if i == -1:
             return full_name
         namespace, name = full_name[:i], full_name[i+1:]
-        short_namespace = self.namespaces.get(namespace, namespace)
+        try:
+            short_namespace = self.namespaces[namespace]
+        except KeyError:
+            short_namespace = namespace
         if not short_namespace:
             return name
         else:
@@ -95,7 +105,7 @@
         attrs = self._attrs_to_dict(attrs)
         if attrs and self.namespace_declarations:
             attrs['xmlns'] = self.namespace_declarations
-            self.namespace_declarations = OrderedDict()
+            self.namespace_declarations = self.dict_constructor()
         self.path.append((name, attrs or None))
         if len(self.path) > self.item_depth:
             self.stack.append((self.item, self.data))
@@ -126,7 +136,7 @@
             should_continue = self.item_callback(self.path, item)
             if not should_continue:
                 raise ParsingInterrupted()
-        if len(self.stack):
+        if self.stack:
             data = (None if not self.data
                     else self.cdata_separator.join(self.data))
             item = self.item
@@ -152,6 +162,11 @@
         else:
             self.data.append(data)
 
+    def comments(self, data):
+        if self.strip_whitespace:
+            data = data.strip()
+        self.item = self.push_data(self.item, self.comment_key, data)
+
     def push_data(self, item, key, data):
         if self.postprocessor is not None:
             result = self.postprocessor(self.path, key, data)
@@ -185,10 +200,10 @@
 
 
 def parse(xml_input, encoding=None, expat=expat, process_namespaces=False,
-          namespace_separator=':', disable_entities=True, **kwargs):
+          namespace_separator=':', disable_entities=True, 
process_comments=False, **kwargs):
     """Parse the given XML input and convert it into a dictionary.
 
-    `xml_input` can either be a `string` or a file-like object.
+    `xml_input` can either be a `string`, a file-like object, or a generator 
of strings.
 
     If `xml_attribs` is `True`, element attributes are put in the dictionary
     among regular child elements, using `@` as a prefix to avoid collisions. If
@@ -243,21 +258,21 @@
         ...         return key, value
         >>> xmltodict.parse('<a><b>1</b><b>2</b><b>x</b></a>',
         ...                 postprocessor=postprocessor)
-        OrderedDict([(u'a', OrderedDict([(u'b:int', [1, 2]), (u'b', u'x')]))])
+        {'a': {'b:int': [1, 2], 'b': 'x'}}
 
     You can pass an alternate version of `expat` (such as `defusedexpat`) by
     using the `expat` parameter. E.g:
 
         >>> import defusedexpat
         >>> xmltodict.parse('<a>hello</a>', expat=defusedexpat.pyexpat)
-        OrderedDict([(u'a', u'hello')])
+        {'a': 'hello'}
 
     You can use the force_list argument to force lists to be created even
     when there is only a single child of a given level of hierarchy. The
     force_list argument is a tuple of keys. If the key for a given level
     of hierarchy is in the force_list argument, that level of hierarchy
     will have a list as a child (even if there is only one sub-element).
-    The index_keys operation takes precendence over this. This is applied
+    The index_keys operation takes precedence over this. This is applied
     after any user-supplied postprocessor has already run.
 
         For example, given this input:
@@ -287,6 +302,36 @@
         `force_list` can also be a callable that receives `path`, `key` and
         `value`. This is helpful in cases where the logic that decides whether
         a list should be forced is more complex.
+
+
+        If `process_comment` is `True` then comment will be added with 
comment_key
+        (default=`'#comment'`) to then tag which contains comment
+
+            For example, given this input:
+            <a>
+              <b>
+                <!-- b comment -->
+                <c>
+                    <!-- c comment -->
+                    1
+                </c>
+                <d>2</d>
+              </b>
+            </a>
+
+            If called with process_comment=True, it will produce
+            this dictionary:
+            'a': {
+                'b': {
+                    '#comment': 'b comment',
+                    'c': {
+
+                        '#comment': 'c comment',
+                        '#text': '1',
+                    },
+                    'd': '2',
+                },
+            }
     """
     handler = _DictSAXHandler(namespace_separator=namespace_separator,
                               **kwargs)
@@ -309,6 +354,8 @@
     parser.StartElementHandler = handler.startElement
     parser.EndElementHandler = handler.endElement
     parser.CharacterDataHandler = handler.characters
+    if process_comments:
+        parser.CommentHandler = handler.comments
     parser.buffer_text = True
     if disable_entities:
         try:
@@ -323,6 +370,10 @@
             parser.ExternalEntityRefHandler = lambda *x: 1
     if hasattr(xml_input, 'read'):
         parser.ParseFile(xml_input)
+    elif isgenerator(xml_input):
+        for chunk in xml_input:
+            parser.Parse(chunk,False)
+        parser.Parse(b'',True)
     else:
         parser.Parse(xml_input, True)
     return handler.item
@@ -353,7 +404,8 @@
           indent='\t',
           namespace_separator=':',
           namespaces=None,
-          full_document=True):
+          full_document=True,
+          expand_iter=None):
     key = _process_namespace(key, namespaces, namespace_separator, attr_prefix)
     if preprocessor is not None:
         result = preprocessor(key, value)
@@ -368,18 +420,21 @@
         if full_document and depth == 0 and index > 0:
             raise ValueError('document with multiple roots')
         if v is None:
-            v = OrderedDict()
+            v = _dict()
         elif isinstance(v, bool):
             if v:
                 v = _unicode('true')
             else:
                 v = _unicode('false')
         elif not isinstance(v, dict):
-            v = _unicode(v)
+            if expand_iter and hasattr(v, '__iter__') and not isinstance(v, 
_basestring):
+                v = _dict(((expand_iter, v),))
+            else:
+                v = _unicode(v)
         if isinstance(v, _basestring):
-            v = OrderedDict(((cdata_key, v),))
+            v = _dict(((cdata_key, v),))
         cdata = None
-        attrs = OrderedDict()
+        attrs = _dict()
         children = []
         for ik, iv in v.items():
             if ik == cdata_key:
@@ -407,7 +462,8 @@
             _emit(child_key, child_value, content_handler,
                   attr_prefix, cdata_key, depth+1, preprocessor,
                   pretty, newl, indent, namespaces=namespaces,
-                  namespace_separator=namespace_separator)
+                  namespace_separator=namespace_separator,
+                  expand_iter=expand_iter)
         if cdata is not None:
             content_handler.characters(cdata)
         if pretty and children:

Reply via email to