<commit_before>#
# Copyright (c) 2008 rPath, Inc.
#
# This program is distributed under the terms of the MIT License as found 
# in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/mit-license.php.
#
# This program is distributed in the hope that it will be useful, but
# without any waranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the MIT License for full details.

from lxml import etree
import types
from StringIO import StringIO

DocumentInvalid = etree.DocumentInvalid

class UnknownXType(Exception):

    """
    Exception raised when a class prototype specifies a type which is not
    understood.
    """

class UnmatchedIdRef(Exception):

    """
    Exception raised when idref's cannot be matched with an id during
    XML generation.
    """

    def __str__(self):
        return ("Unmatched idref values during XML creation for id(s): %s"
                    % ",".join(str(x) for x in self.idList))

    def __init__(self, idList):
        self.idList = idList

class XType(object):

    def _isComplex(self):
        for key, val in self.pythonType.__dict__.iteritems():
            if (type(val) != types.FunctionType and 
                 type(val) != types.MethodType and key[0] != '_'
                 and key != 'text'):
                return True

        return False

    def __init__(self, pythonType, forceList = False):
        self.pythonType = pythonType
        self.forceList = forceList

class XUnionType(XType):

    def __init__(self, d):
        self.d = {}
        for key, val in d.iteritems():
            self.d[key] = XTypeFromXObjectType(val)
            self.d[key].forceList = True

def XTypeFromXObjectType(xObjectType):

    if xObjectType == str or xObjectType == object:
        # Basic object's are static, making instantiating one pretty worthless.
        return XType(XObj)
    elif xObjectType == int:
        return XType(XObjInt)
    elif xObjectType == float:
        return XType(XObjFloat)
    elif type(xObjectType) == list:
        assert(len(xObjectType) == 1)
        return XType(XTypeFromXObjectType(xObjectType[0]).pythonType,
                     forceList = True)

    return XType(xObjectType)

class XObj(object):

    """
    Example class for all elements represented in XML. Subclasses of XObject
    can be used to specify how attributes and elements of the element are
    represented in python. For example, parsing the XML:

        <element intAttr="10" strAttr="hello">
           <subelement>Value</subelement>
        </element>

    using this class:

        class Element(xobj.XObj):

            intAttr = int                       # force an int
            subelement = [ str ]                # force a list

    (which is done with doc = xobj.parse("---xml string---",
                                    typeMap = { 'element' : Element } )
    will result in the object tree:

        doc.element.intAttr = 10
        doc.element.strAttr = 'hello'
        doc.element.subelement.text = [ 'Value' ]

    """

    def __repr__(self):
        if self:
            return str.__repr__(self)<commit_msg>return XObj to subclassing from str.<commit_after>#
# Copyright (c) 2008 rPath, Inc.
#
# This program is distributed under the terms of the MIT License as found 
# in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/mit-license.php.
#
# This program is distributed in the hope that it will be useful, but
# without any waranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the MIT License for full details.

from lxml import etree
import types
from StringIO import StringIO

DocumentInvalid = etree.DocumentInvalid

class UnknownXType(Exception):

    """
    Exception raised when a class prototype specifies a type which is not
    understood.
    """

class UnmatchedIdRef(Exception):

    """
    Exception raised when idref's cannot be matched with an id during
    XML generation.
    """

    def __str__(self):
        return ("Unmatched idref values during XML creation for id(s): %s"
                    % ",".join(str(x) for x in self.idList))

    def __init__(self, idList):
        self.idList = idList

class XType(object):

    def _isComplex(self):
        for key, val in self.pythonType.__dict__.iteritems():
            if (type(val) != types.FunctionType and 
                 type(val) != types.MethodType and key[0] != '_'
                 and key != 'text'):
                return True

        return False

    def __init__(self, pythonType, forceList = False):
        self.pythonType = pythonType
        self.forceList = forceList

class XUnionType(XType):

    def __init__(self, d):
        self.d = {}
        for key, val in d.iteritems():
            self.d[key] = XTypeFromXObjectType(val)
            self.d[key].forceList = True

def XTypeFromXObjectType(xObjectType):

    if xObjectType == str or xObjectType == object:
        # Basic object's are static, making instantiating one pretty worthless.
        return XType(XObj)
    elif xObjectType == int:
        return XType(XObjInt)
    elif xObjectType == float:
        return XType(XObjFloat)
    elif type(xObjectType) == list:
        assert(len(xObjectType) == 1)
        return XType(XTypeFromXObjectType(xObjectType[0]).pythonType,
                     forceList = True)

    return XType(xObjectType)

class XObj(str):

    """
    Example class for all elements represented in XML. Subclasses of XObject
    can be used to specify how attributes and elements of the element are
    represented in python. For example, parsing the XML:

        <element intAttr="10" strAttr="hello">
           <subelement>Value</subelement>
        </element>

    using this class:

        class Element(xobj.XObj):

            intAttr = int                       # force an int
            subelement = [ str ]                # force a list

    (which is done with doc = xobj.parse("---xml string---",
                                    typeMap = { 'element' : Element } )
    will result in the object tree:

        doc.element.intAttr = 10
        doc.element.strAttr = 'hello'
        doc.element.subelement.text = [ 'Value' ]

    """

    def __repr__(self):
        if self:
            return str.__repr__(self)
{'fraction_non_alphanumeric': 0.0889475318224154, 'fraction_numerical': 0.0034150884818379386, 'mean_word_length': 2.326277749096541, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3255114', 'n_tokens_mistral': 1827, 'n_tokens_neox': 1744, 'n_words': 618}