Пример #1
0
def olddata_to_newdata(data, extra, paranoia):
    """Given raw data, the extra= tag, and paranoia setting,
    recreate the object that was passed to newdata_to_olddata."""
    (module, klass) = extra.split()
    o = obj_from_name(klass, module, paranoia)

    #if isinstance(o,ComplexType) and \
    #      type(data) in [StringType,UnicodeType]:
    #   # yuck ... have to strip () from complex data before
    #   # passing to __init__ (ran into this also in one of the
    #   # parsers ... maybe the () shouldn't be in the XML at all?)
    #   if data[0] == '(' and data[-1] == ')':
    #       data = data[1:-1]

    if isinstance_any(o,(IntType,FloatType,ComplexType,LongType)) and \
                      type(data) in [StringType,UnicodeType]:
        data = aton(data)

    o = setCoreData(o, data)
    return o
Пример #2
0
def olddata_to_newdata(data,extra,paranoia):
    """Given raw data, the extra= tag, and paranoia setting,
    recreate the object that was passed to newdata_to_olddata."""
    (module,klass) = extra.split()
    o = obj_from_name(klass,module,paranoia)

    #if isinstance(o,ComplexType) and \
    #	   type(data) in [StringType,UnicodeType]:
    #	# yuck ... have to strip () from complex data before
    #	# passing to __init__ (ran into this also in one of the
    #	# parsers ... maybe the () shouldn't be in the XML at all?)
    #	if data[0] == '(' and data[-1] == ')':
    #		data = data[1:-1]

    if isinstance_any(o,(IntType,FloatType,ComplexType,LongType)) and \
                      type(data) in [StringType,UnicodeType]:
        data = aton(data)

    o = setCoreData(o,data)
    return o
Пример #3
0
def _tag_completer(start_tag, orig_thing, close_tag, level, deepcopy):
    tag_body = []

    (mtag, thing, in_body, mextra) = try_mutate(orig_thing, None,
                                                getInBody(type(orig_thing)),
                                                None)

    if type(thing) is NoneType:
        start_tag += "%s />\n" % (_family_type('none', 'None', None, None))
        close_tag = ''
    # looks like bool cannot be used as a base class, so if thing
    # is a bool it will always be BooleanType, and either True or False
    elif py_version >= '2.3' and type(thing) is BooleanType:
        if thing is True:
            typestr = 'True'
        else:  # must be False
            typestr = 'False'

        if in_body:
            start_tag +='%s>%s' % \
                      (_family_type('uniq',typestr,mtag,mextra),
                       '')
            close_tag = close_tag.lstrip()
        else:
            start_tag +='%s value="%s" />\n' % \
                      (_family_type('uniq',typestr,mtag,mextra),
                       '')
            close_tag = ''
    # ClassType will get caught by isInstanceLike(), which is not
    # what we want (also check for new-style class objects)
    elif isinstance(thing, ClassType) or isNewStyleClass(thing):
        module = thing.__module__
        if module:
            extra = 'module="%s" class="%s"' % (module, thing.__name__)
        else:
            extra = 'class="%s"' % _klass(thing.__name__)
        start_tag +='%s %s/>\n' % \
                     (_family_type('lang','class',mtag,mextra),extra)

        close_tag = ''
    # have to check for instance-like next since ints, etc., can be
    # instance-like in Python 2.2+. if it's really an object, we don't
    # want to fall through to the regular int,float,etc. code, since
    # that would skip the special handling in pickle_instance().
    elif isInstanceLike(thing):
        module = _module(thing)
        if module:
            extra = 'module="%s" class="%s"' % (module, _klass(thing))
        else:
            extra = 'class="%s"' % _klass(thing)
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('obj','PyObject',mtag,mextra),
                                 orig_thing, deepcopy, extra)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            pickle_instance(thing, tag_body, level + 1, deepcopy)
        else:
            close_tag = ''
    elif isinstance_any(thing, (IntType, LongType, FloatType, ComplexType)):
        #thing_str = repr(thing)
        thing_str = ntoa(thing)

        if in_body:
            # we don't call safe_content() here since numerics won't
            # contain special XML chars.
            # the unpickler can either call unsafe_content() or not,
            # it won't matter
            start_tag +='%s>%s' % \
                      (_family_type('atom','numeric',mtag,mextra),
                       thing_str)
            close_tag = close_tag.lstrip()
        else:
            start_tag +='%s value="%s" />\n' % \
                      (_family_type('atom','numeric',mtag,mextra),thing_str)
            close_tag = ''
    elif isinstance_any(thing, (StringType, UnicodeType)):
        if in_body:
            start_tag +='%s>%s' % \
                      (_family_type('atom','string',mtag,mextra),
                       safe_content(thing))
            close_tag = close_tag.lstrip()
        else:
            start_tag +='%s value="%s" />\n' % \
                      (_family_type('atom','string',mtag,mextra),
                       safe_string(thing))
            close_tag = ''
    # General notes:
    #   1. When we make references, set type to referenced object
    #      type -- we don't need type when unpickling, but it may be useful
    #      to someone reading the XML file
    #   2. For containers, we have to stick the container into visited{}
    #      before pickling subitems, in case it contains self-references
    #      (we CANNOT just move the visited{} update to the top of this
    #      function, since that would screw up every _family_type() call)
    elif type(thing) is TupleType:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('seq','tuple',mtag,mextra),
                                 orig_thing,deepcopy)
        if do_copy:
            for item in thing:
                tag_body.append(_item_tag(item, level + 1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) is ListType:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('seq','list',mtag,mextra),
                                 orig_thing,deepcopy)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            for item in thing:
                tag_body.append(_item_tag(item, level + 1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) in [DictType]:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('map','dict',mtag,mextra),
                                 orig_thing,deepcopy)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            for key, val in thing.items():
                tag_body.append(_entry_tag(key, val, level + 1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) in [FunctionType, BuiltinFunctionType]:
        info = get_function_info(thing)
        # use module/class tags -- not perfect semantically, but better
        # that creating new attr names
        start_tag +='%s module="%s" class="%s"/>\n' % \
                     (_family_type('lang','function',mtag,mextra),
                      info[0],info[1])
        close_tag = ''
    else:
        # try using pickled value as the XML value tag.
        # rationale:  it won't be (easily) editable, but at least
        # you'll get valid XML even if your classes happen to
        # contain a few "foreign" types, and you don't feel like
        # writing a helper object (see gnosis.xml.pickle.ext for
        # how to do that)
        try:
            # we can't lookup the helper by type, since rawpickle can pickle
            # any pickleable class, so lookup by tag (unmutator) instead
            # (mutator & unmutator are always the same object)

            # always put rawpickles in the element body
            mutator = get_unmutator('rawpickle', None)
            thing = safe_content(mutator.mutate(thing).obj)
            start_tag += '%s>%s' % (_family_type('atom', None, 'rawpickle',
                                                 None), thing)
            close_tag = close_tag.lstrip()
        except:
            raise XMLPicklingError, "non-handled type %s" % type(thing)

    # need to keep a ref to the object for two reasons -
    #  1. we can ref it later instead of copying it into the XML stream
    #  2. need to keep temporary objects around so their ids don't get reused

    # if DEEPCOPY, we can skip this -- reusing ids is not an issue if we
    # never look at them
    if not deepcopy:
        visited[id(orig_thing)] = orig_thing

    return start_tag + ''.join(tag_body) + close_tag
Пример #4
0
def _tag_completer(start_tag, orig_thing, close_tag, level, deepcopy):
    tag_body = []

    (mtag,thing,in_body,mextra) = try_mutate(orig_thing,None,
                                             getInBody(type(orig_thing)), None)

    if type(thing) is NoneType:
        start_tag = start_tag + "%s />\n" % (_family_type('none','None',None,None))
        close_tag = ''
    # bool cannot be used as a base class (see sanity check above) so if thing
    # is a bool it will always be BooleanType, and either True or False
    elif Have_BoolClass and type(thing) is BooleanType:
        if thing is True:
            typestr = 'True'
        else: # must be False
            typestr = 'False'

        if in_body:
            start_tag = start_tag + '%s>%s' % \
                      (_family_type('uniq',typestr,mtag,mextra),
                       '')
            close_tag = close_tag.lstrip()
        else:
            start_tag = start_tag + '%s value="%s" />\n' % \
                      (_family_type('uniq',typestr,mtag,mextra),
                       '')
            close_tag = ''
    # ClassType will get caught by isInstanceLike(), which is not
    # what we want. There are two cases here - the first catches
    # old-style classes, the second catches new-style classes.
    elif isinstance(thing,ClassType) or isNewStyleClass(thing):
        module = thing.__module__
        if module:
            extra = 'module="%s" class="%s"' % (module, thing.__name__)
        else:
            extra = 'class="%s"' % _klass(thing.__name__)
        start_tag = start_tag + '%s %s/>\n' % \
                     (_family_type('lang','class',mtag,mextra),extra)

        close_tag = ''
    # have to check for instance-like next since ints, etc., can be
    # instance-like in Python 2.2+. if it's really an object, we don't
    # want to fall through to the regular int,float,etc. code, since
    # that would skip the special handling in pickle_instance().
    elif isInstanceLike(thing):
        module = _module(thing)
        if module:
            extra = 'module="%s" class="%s"' % (module, _klass(thing))
        else:
            extra = 'class="%s"' % _klass(thing)
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('obj','PyObject',mtag,mextra),
                                 orig_thing, deepcopy, extra)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            pickle_instance(thing, tag_body, level+1, deepcopy)
        else:
            close_tag = ''
    elif isinstance_any(thing, (IntType, LongType, FloatType, ComplexType)):
        #thing_str = repr(thing)
        thing_str = ntoa(thing)

        if in_body:
            # we don't call safe_content() here since numerics won't
            # contain special XML chars.
            # the unpickler can either call unsafe_content() or not,
            # it won't matter
            start_tag = start_tag + '%s>%s' % \
                      (_family_type('atom','numeric',mtag,mextra),
                       thing_str)
            close_tag = close_tag.lstrip()
        else:
            start_tag = start_tag + '%s value="%s" />\n' % \
                      (_family_type('atom','numeric',mtag,mextra),thing_str)
            close_tag = ''
    elif isinstance_any(thing, (StringType,UnicodeType)):
        #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        # special check for now - this will be fixed in the next major
        # gnosis release, so I don't care that the code is inline & gross
        # for now
        #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX       
        if isinstance(thing,UnicodeType):
            # can't pickle unicode containing the special "escape" sequence
            # we use for putting strings in the XML body (they'll be unpickled
            # as strings, not unicode, if we do!)
            if thing[0:2] == u'\xbb\xbb' and thing[-2:] == u'\xab\xab':
                raise Exception("Unpickleable Unicode value. To be fixed in next major Gnosis release.")
        
            # see if it contains any XML-illegal values
            if not is_legal_xml(thing):
                raise Exception("Unpickleable Unicode value. To be fixed in next major Gnosis release.")

        if isinstance(thing,StringType) and getInBody(StringType):
            # technically, this will crash safe_content(), but I prefer to
            # have the test here for clarity
            try:
                # safe_content assumes it can always convert the string
                # to unicode, which isn't true (eg. pickle a UTF-8 value)
                u = unicode(thing)
            except:
                raise Exception("Unpickleable string value (%s). To be fixed in next major Gnosis release." % repr(thing))

        #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        # End of temporary hack code
        #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
            
        if in_body:
            start_tag = start_tag + '%s>%s' % \
                      (_family_type('atom','string',mtag,mextra),
                       safe_content(thing))
            close_tag = close_tag.lstrip()
        else:
            start_tag = start_tag + '%s value="%s" />\n' % \
                      (_family_type('atom','string',mtag,mextra),
                       safe_string(thing))
            close_tag = ''
    # General notes:
    #	1. When we make references, set type to referenced object
    #	   type -- we don't need type when unpickling, but it may be useful
    #	   to someone reading the XML file
    #	2. For containers, we have to stick the container into visited{}
    #	   before pickling subitems, in case it contains self-references
    #	   (we CANNOT just move the visited{} update to the top of this
    #	   function, since that would screw up every _family_type() call)
    elif type(thing) is TupleType:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('seq','tuple',mtag,mextra),
                                 orig_thing,deepcopy)
        if do_copy:
            for item in thing:
                tag_body.append(_item_tag(item, level+1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) is ListType:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('seq','list',mtag,mextra),
                                 orig_thing,deepcopy)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            for item in thing:
                tag_body.append(_item_tag(item, level+1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) in [DictType]:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('map','dict',mtag,mextra),
                                 orig_thing,deepcopy)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            for key, val in thing.items():
                tag_body.append(_entry_tag(key, val, level+1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) in [FunctionType,BuiltinFunctionType]:
        info = get_function_info(thing)
        # use module/class tags -- not perfect semantically, but better
        # that creating new attr names
        start_tag = start_tag + '%s module="%s" class="%s"/>\n' % \
                     (_family_type('lang','function',mtag,mextra),
                      info[0],info[1])
        close_tag = ''
    else:
        # try using pickled value as the XML value tag.
        # rationale:  it won't be (easily) editable, but at least
        # you'll get valid XML even if your classes happen to
        # contain a few "foreign" types, and you don't feel like
        # writing a helper object (see gnosis.xml.pickle.ext for
        # how to do that)
        try:
            # we can't lookup the helper by type, since rawpickle can pickle
            # any pickleable class, so lookup by tag (unmutator) instead
            # (mutator & unmutator are always the same object)

            # always put rawpickles in the element body
            mutator = get_unmutator('rawpickle',None)
            thing = safe_content(mutator.mutate(thing).obj)
            start_tag = start_tag + '%s>%s' % (_family_type('atom',None,'rawpickle',None),
                                   thing)
            close_tag = close_tag.lstrip()
        except:
            raise XMLPicklingError, "non-handled type %s" % type(thing)

    # need to keep a ref to the object for two reasons -
    #  1. we can ref it later instead of copying it into the XML stream
    #  2. need to keep temporary objects around so their ids don't get reused

    # if DEEPCOPY, we can skip this -- reusing ids is not an issue if we
    # never look at them
    if not deepcopy:
        visited[id(orig_thing)] = orig_thing

    return start_tag + ''.join(tag_body) + close_tag
Пример #5
0
def _tag_completer(start_tag, orig_thing, close_tag, level, deepcopy):
    tag_body = []

    (mtag, thing, in_body, mextra) = try_mutate(orig_thing, None,
                                                getInBody(type(orig_thing)),
                                                None)

    if type(thing) is type(None):
        start_tag = start_tag + "%s />\n" % (_family_type(
            'none', 'None', None, None))
        close_tag = ''
    # bool cannot be used as a base class (see sanity check above) so if thing
    # is a bool it will always be BooleanType, and either True or False
    elif Have_BoolClass and type(thing) is bool:
        if thing is True:
            typestr = 'True'
        else:  # must be False
            typestr = 'False'

        if in_body:
            start_tag = start_tag + '%s>%s' % \
                      (_family_type('uniq',typestr,mtag,mextra),
                       '')
            close_tag = close_tag.lstrip()
        else:
            start_tag = start_tag + '%s value="%s" />\n' % \
                      (_family_type('uniq',typestr,mtag,mextra),
                       '')
            close_tag = ''
    # ClassType will get caught by isInstanceLike(), which is not
    # what we want. There are two cases here - the first catches
    # old-style classes, the second catches new-style classes.
    elif isinstance(thing, type) or isNewStyleClass(thing):
        module = thing.__module__
        if module:
            extra = 'module="%s" class="%s"' % (module, thing.__name__)
        else:
            extra = 'class="%s"' % _klass(thing.__name__)
        start_tag = start_tag + '%s %s/>\n' % \
                     (_family_type('lang','class',mtag,mextra),extra)

        close_tag = ''
    # have to check for instance-like next since ints, etc., can be
    # instance-like in Python 2.2+. if it's really an object, we don't
    # want to fall through to the regular int,float,etc. code, since
    # that would skip the special handling in pickle_instance().
    elif isInstanceLike(thing):
        module = _module(thing)
        if module:
            extra = 'module="%s" class="%s"' % (module, _klass(thing))
        else:
            extra = 'class="%s"' % _klass(thing)
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('obj','PyObject',mtag,mextra),
                                 orig_thing, deepcopy, extra)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            pickle_instance(thing, tag_body, level + 1, deepcopy)
        else:
            close_tag = ''
    elif isinstance_any(thing, (int, int, float, complex)):
        #thing_str = repr(thing)
        thing_str = ntoa(thing)

        if in_body:
            # we don't call safe_content() here since numerics won't
            # contain special XML chars.
            # the unpickler can either call unsafe_content() or not,
            # it won't matter
            start_tag = start_tag + '%s>%s' % \
                      (_family_type('atom','numeric',mtag,mextra),
                       thing_str)
            close_tag = close_tag.lstrip()
        else:
            start_tag = start_tag + '%s value="%s" />\n' % \
                      (_family_type('atom','numeric',mtag,mextra),thing_str)
            close_tag = ''
    elif isinstance_any(thing, (bytes, str)):
        #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        # special check for now - this will be fixed in the next major
        # gnosis release, so I don't care that the code is inline & gross
        # for now
        #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        if isinstance(thing, str):
            # can't pickle unicode containing the special "escape" sequence
            # we use for putting strings in the XML body (they'll be unpickled
            # as strings, not unicode, if we do!)
            if thing[0:2] == '\xbb\xbb' and thing[-2:] == '\xab\xab':
                raise Exception(
                    "Unpickleable Unicode value. To be fixed in next major Gnosis release."
                )

            # see if it contains any XML-illegal values
            if not is_legal_xml(thing):
                raise Exception(
                    "Unpickleable Unicode value. To be fixed in next major Gnosis release."
                )

        if isinstance(thing, bytes) and getInBody(bytes):
            # technically, this will crash safe_content(), but I prefer to
            # have the test here for clarity
            try:
                # safe_content assumes it can always convert the string
                # to unicode, which isn't true (eg. pickle a UTF-8 value)
                u = str(thing)
            except:
                raise Exception(
                    "Unpickleable string value (%s). To be fixed in next major Gnosis release."
                    % repr(thing))

        #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        # End of temporary hack code
        #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

        if in_body:
            start_tag = start_tag + '%s>%s' % \
                      (_family_type('atom','string',mtag,mextra),
                       safe_content(thing))
            close_tag = close_tag.lstrip()
        else:
            start_tag = start_tag + '%s value="%s" />\n' % \
                      (_family_type('atom','string',mtag,mextra),
                       safe_string(thing))
            close_tag = ''
    # General notes:
    #	1. When we make references, set type to referenced object
    #	   type -- we don't need type when unpickling, but it may be useful
    #	   to someone reading the XML file
    #	2. For containers, we have to stick the container into visited{}
    #	   before pickling subitems, in case it contains self-references
    #	   (we CANNOT just move the visited{} update to the top of this
    #	   function, since that would screw up every _family_type() call)
    elif type(thing) is tuple:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('seq','tuple',mtag,mextra),
                                 orig_thing,deepcopy)
        if do_copy:
            for item in thing:
                tag_body.append(_item_tag(item, level + 1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) is list:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('seq','list',mtag,mextra),
                                 orig_thing,deepcopy)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            for item in thing:
                tag_body.append(_item_tag(item, level + 1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) in [dict]:
        start_tag, do_copy = \
                   _tag_compound(start_tag,_family_type('map','dict',mtag,mextra),
                                 orig_thing,deepcopy)
        # need to remember we've seen container before pickling subitems
        visited[id(orig_thing)] = orig_thing
        if do_copy:
            for key, val in list(thing.items()):
                tag_body.append(_entry_tag(key, val, level + 1, deepcopy))
        else:
            close_tag = ''
    elif type(thing) in [FunctionType, BuiltinFunctionType]:
        info = get_function_info(thing)
        # use module/class tags -- not perfect semantically, but better
        # that creating new attr names
        start_tag = start_tag + '%s module="%s" class="%s"/>\n' % \
                     (_family_type('lang','function',mtag,mextra),
                      info[0],info[1])
        close_tag = ''
    else:
        # try using pickled value as the XML value tag.
        # rationale:  it won't be (easily) editable, but at least
        # you'll get valid XML even if your classes happen to
        # contain a few "foreign" types, and you don't feel like
        # writing a helper object (see gnosis.xml.pickle.ext for
        # how to do that)
        try:
            # we can't lookup the helper by type, since rawpickle can pickle
            # any pickleable class, so lookup by tag (unmutator) instead
            # (mutator & unmutator are always the same object)

            # always put rawpickles in the element body
            mutator = get_unmutator('rawpickle', None)
            thing = safe_content(mutator.mutate(thing).obj)
            start_tag = start_tag + '%s>%s' % (_family_type(
                'atom', None, 'rawpickle', None), thing)
            close_tag = close_tag.lstrip()
        except:
            raise XMLPicklingError("non-handled type %s" % type(thing))

    # need to keep a ref to the object for two reasons -
    #  1. we can ref it later instead of copying it into the XML stream
    #  2. need to keep temporary objects around so their ids don't get reused

    # if DEEPCOPY, we can skip this -- reusing ids is not an issue if we
    # never look at them
    if not deepcopy:
        visited[id(orig_thing)] = orig_thing

    return start_tag + ''.join(tag_body) + close_tag