<commit_before># @purpose converts an XML file into a python dict, back and forth
# @author http://code.activestate.com/recipes/573463
#         slightly adapted to follow PEP8 conventions
# based on http://alxr.usatlas.bnl.gov/lxr/source/atlas/Tools/PyUtils/python/xmldict.py
# @author "<NAME> <<EMAIL>>"
#         modified to handle attributes, namespaces..

__doc__ = """\
functions to convert an XML file into a python dict, back and forth
"""
__author__ = "<NAME> <<EMAIL>>"

from StringIO import StringIO

# hack: LCGCMT had the py-2.5 xml.etree module hidden by mistake.
#       this is to import it, by hook or by crook
def import_etree():
    import xml
    # first try the usual way
    try:
        import xml.etree
        return xml.etree
    except ImportError:
        pass
    # do it by hook or by crook...
    import sys, os, imp
    xml_site_package = os.path.join(os.path.dirname(os.__file__), 'xml')
    m = imp.find_module('etree', [xml_site_package])

    etree = imp.load_module('xml.etree', *m)
    setattr(xml, 'etree', etree)
    return etree

etree = import_etree()
from xml.etree import ElementTree

## module data ----------------------------------------------------------------
__all__ = [
    'xml2dict',
    'dict2xml',
    ]

_BASE_NSMAP = {
    'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
}

## module implementation ------------------------------------------------------
class XmlDictObject(dict):
    _path = ()
    _childorder = {} # relative to _path; only useful if defined at the same level at which _path is defined/overridden
    _multi_nodes = set()

    def __init__(self, initdict=None, nsmap=None, extra_nsmap=None):
        # NOTE: setting attributes in __init__ will require special handling, see XmlDictObject
        if initdict is None:
            initdict = {}
        dict.__init__(self, initdict)

        if nsmap is None:
            nsmap = self._nsmap = _BASE_NSMAP.copy()
        nsmap.update(extra_nsmap or {})
        self._nsmap = nsmap

        nsmap_r = {}
        # build reverse map
        for prefix, uri in nsmap.iteritems():
            if uri in nsmap_r and not prefix: # default prefix should not override anything already in the rmap
                continue
            nsmap_r[uri] = prefix
        self._nsmap_r = nsmap_r

        self.__initialized = True


    def __getattr__(self, item):
        it = self
        for p in self._path:
            it = it[p]
        if item in it:
            return it[item]
        else:
            raise AttributeError("no such node (%s/%s) in: %r (self=%s)" % ('/'.join(self._path), item, it, self))


    def __setattr__(self, item, value):
        if not self.__dict__.has_key('_XmlDictObject__initialized'):
            # this test allows attributes to be set in the __init__ method
            return super(XmlDictObject, self).__setattr__(item, value)<commit_msg>fix exception causing infinite recursion<commit_after># @purpose converts an XML file into a python dict, back and forth
# @author http://code.activestate.com/recipes/573463
#         slightly adapted to follow PEP8 conventions
# based on http://alxr.usatlas.bnl.gov/lxr/source/atlas/Tools/PyUtils/python/xmldict.py
# @author "<NAME> <<EMAIL>>"
#         modified to handle attributes, namespaces..

__doc__ = """\
functions to convert an XML file into a python dict, back and forth
"""
__author__ = "<NAME> <<EMAIL>>"

from StringIO import StringIO

# hack: LCGCMT had the py-2.5 xml.etree module hidden by mistake.
#       this is to import it, by hook or by crook
def import_etree():
    import xml
    # first try the usual way
    try:
        import xml.etree
        return xml.etree
    except ImportError:
        pass
    # do it by hook or by crook...
    import sys, os, imp
    xml_site_package = os.path.join(os.path.dirname(os.__file__), 'xml')
    m = imp.find_module('etree', [xml_site_package])

    etree = imp.load_module('xml.etree', *m)
    setattr(xml, 'etree', etree)
    return etree

etree = import_etree()
from xml.etree import ElementTree

## module data ----------------------------------------------------------------
__all__ = [
    'xml2dict',
    'dict2xml',
    ]

_BASE_NSMAP = {
    'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
}

## module implementation ------------------------------------------------------
class XmlDictObject(dict):
    _path = ()
    _childorder = {} # relative to _path; only useful if defined at the same level at which _path is defined/overridden
    _multi_nodes = set()

    def __init__(self, initdict=None, nsmap=None, extra_nsmap=None):
        # NOTE: setting attributes in __init__ will require special handling, see XmlDictObject
        if initdict is None:
            initdict = {}
        dict.__init__(self, initdict)

        if nsmap is None:
            nsmap = self._nsmap = _BASE_NSMAP.copy()
        nsmap.update(extra_nsmap or {})
        self._nsmap = nsmap

        nsmap_r = {}
        # build reverse map
        for prefix, uri in nsmap.iteritems():
            if uri in nsmap_r and not prefix: # default prefix should not override anything already in the rmap
                continue
            nsmap_r[uri] = prefix
        self._nsmap_r = nsmap_r

        self.__initialized = True


    def __getattr__(self, item):
        it = self
        for p in self._path:
            it = it[p]
        if item in it:
            return it[item]
        else:
            raise AttributeError("no such node (%s/%s) in: %r (self=%s)" % ('/'.join(self._path),
                                                                            item,
                                                                            it,
                                                                            super(XmlDictObject, self).__str__()))


    def __setattr__(self, item, value):
        if not self.__dict__.has_key('_XmlDictObject__initialized'):
            # this test allows attributes to be set in the __init__ method
            return super(XmlDictObject, self).__setattr__(item, value)
{'fraction_non_alphanumeric': 0.13357460108570487, 'fraction_numerical': 0.0052640236881065965, 'mean_word_length': 1.9818538499264344, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 26}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6910295', 'n_tokens_mistral': 1779, 'n_tokens_neox': 1752, 'n_words': 548}