Beispiel #1
0
def getCallableString(callable):
    '''
    Returns a translated human readable string representing a callable.

    Parameters
    ----------
    callable: callable
        *function*, *method*, *class* or *instance* to inspect

    Returns
    --------
    string:
        type and name of the callable
    '''
    if inspect.isfunction(callable):
        name = _('function %s') % (callable.__name__, )
    elif inspect.ismethod(callable):
        name = _('method %s') % (
            six.get_method_self(callable).__class__.__name__ + '.' +
            callable.__name__, )
    elif inspect.isclass(callable):
        name = _('class %s') % (callable.__name__, )
    else:
        name = str(callable)
    return name
Beispiel #2
0
 def startElement(self, parser, name, attributes):
     if parser._minfStarted:
         nameAttr = attributes.pop(nameAttribute, None)
         if nameAttr is None:
             if self._obsoleteFormat:
                 parser.parseError(
                     _('%s attribute required for minf_1.0') %
                     (nameAttribute, ))
         else:
             if self._obsoleteFormat:
                 parser._nodesToProduce.append(nameAttr)
             else:
                 parser.parseError(
                     _('Unexpected attribute %s') % (nameAttribute, ))
         newHandler = MinfXMLHandler.getHandler(parser, self, name,
                                                attributes)
         if newHandler is None:
             parser.parseError(_('Unexpected tag "%s"') % (name, ))
         parser._handler = newHandler
     else:
         if name != minfTag:
             # Document is not a minf file
             parser.parseError(
                 _('Wrong document type, expecting "%(minf)s" instead of '
                   '"%(other)s>"') % {
                       'minf': minfTag,
                       'other': name
                   })
         # Checking minf format
         self._obsoleteFormat = False
         expanderName = attributes.pop(expanderAttribute, None)
         if expanderName is None:
             # Compatibility with obsolete minf 1.0 XML format
             version = attributes.pop('version', None)
             if version is None:
                 expanderName = 'minf_2.0'
             else:
                 if version != '1.0':
                     parser.parseError(
                         _('Wrong value for attribute "version", found '
                           '"%s" but only "1.0" is accepted') % (version, ))
                 self._obsoleteFormat = True
                 expanderName = 'minf_1.0'
         parser._nodesToProduce.append(
             StartStructure(minfStructure, reduction=expanderName))
         # Compatibility with obsolete minf 1.0 XML format
         if self._obsoleteFormat:
             parser._nodesToProduce.append(StartStructure(dictStructure))
         parser._minfStarted = True
         # Check attributes
         parser.checkNoMoreAttributes(attributes)
Beispiel #3
0
 def sequenceExpander(expander,
                      minfNode,
                      minfNodeIterator,
                      target,
                      targetType,
                      stop_on_error=True,
                      exceptions=[]):
     if target is None:
         result = []
     else:
         result = target
         while len(result) != 0:
             result.pop()
     if isinstance(targetType, Sequence) and targetType.elementType.mutable:
         length = minfNode.attributes.get('length')
         if length and len(result) < int(length):
             result += [
                 targetType.elementType.createValue()
                 for i in xrange(int(length) - len(result))
             ]
     itTarget = iter(result)
     for minfNode in minfNodeIterator:
         if isinstance(minfNode, EndStructure):
             if minfNode.type != listStructure:
                 raise MinfError(
                     _('Wrong Minf structure ending, expecting %(exp)s instead of %(rcv)s'
                       ) % {
                           'exp': listStructure,
                           'rcv': minfNode.type
                       })
             break
         else:
             target = None
             if itTarget is not None:
                 try:
                     target = next(itTarget)
                 except StopIteration:
                     itTarget = None
             if target is not None:
                 r = expander.expand(minfNodeIterator,
                                     minfNode,
                                     target=target,
                                     targetType=targetType.elementType,
                                     stop_on_error=stop_on_error,
                                     exceptions=exceptions)
                 result.append(r)
             else:
                 try:
                     result.append(
                         expander.expand(minfNodeIterator,
                                         minfNode,
                                         stop_on_error=stop_on_error,
                                         exceptions=exceptions))
                 except Exception as e:
                     if stop_on_error:
                         raise e
                     else:
                         result.append(None)
                         exceptions.append(sys.exc_info())
     return result
Beispiel #4
0
 def __init__(self, parser, parent, name, attributes):
     identifier = attributes.pop(identifierAttribute, None)
     if self.type is None:
         parser.parseError(
             _('%s attribute missing') % (identifierAttribute, ))
     parser._nodesToProduce.append(Reference(identifier=identifier))
     XMLHandler.__init__(self, parser, parent, name, attributes)
Beispiel #5
0
 def startElement(self, parser, name, attributes):
     nameAttr = attributes.pop(nameAttribute, None)
     parser._nodesToProduce.append(nameAttr)
     newHandler = MinfXMLHandler.getHandler(parser, self, name, attributes)
     if newHandler is None:
         parser.parseError(_('Unexpected tag "%s"') % (name, ))
     parser._handler = newHandler
Beispiel #6
0
 def createWriter(destFile, format, reducer):
     '''
     This static method create a L{MinfWriter} instance by looking for a
     registered L{MinfWriter} derived classe named C{format}. Parameters
     C{destFile} and C{reducer} are passed to the derived class constructor.
     @param format: name of the minf format.
     @type  format: string
     @returns: L{MinfWriter} derived class instance.
     @param file: file name or file object (opened for writing) where the minf
       file is written. If it is a file name, it is opened with
       C{open( destFile, 'wb' )}.
     @type  file: string or any object respecting Python file object API
     @param reducer: name of the reducer to use (see L{soma.minf.tree} for
       more information about reducers).
     @type  reducer: string
     '''
     writer = MinfWriter._allWriterClasses.get(format)
     if writer is None:
         raise ValueError(
             _('No minf writer for format "%(format)s", possible formats are: %(possible)s')
             %
             {'format': format,
              'possible': ', '.join(['"' + i + '"'
                                     for i in
                                     MinfWriter._allWriterClasses])})
     if not hasattr(destFile, 'write'):
         destFile = open(destFile, 'w')
     return writer(destFile, reducer, )
Beispiel #7
0
def timeDifferenceToString(difference):
    days = int(difference / 86400)
    difference -= days * 86400
    hours = int(difference / 3600)
    difference -= hours * 3600
    minutes = int(difference / 60)
    seconds = int(difference - minutes * 60)
    result = ''
    if days:
        return (_('%d days %d hours %d minutes %d seconds') %
                (days, hours, minutes, seconds))
    if hours:
        return (_('%d hours %d minutes %d seconds') %
                (hours, minutes, seconds))
    if minutes:
        return (_('%d minutes %d seconds') % (minutes, seconds))
    return (_('%d seconds') % (seconds, ))
Beispiel #8
0
 def __init__(self, parser, parent, name, attributes):
     self.type = attributes.pop(objectTypeAttribute, None)
     if self.type is None:
         parser.parseError(
             _('%s attribute missing') % (objectTypeAttribute, ))
     identifier = attributes.pop(identifierAttribute, None)
     parser._nodesToProduce.append(
         StartStructure(self.type, identifier=identifier))
     XMLHandler.__init__(self, parser, parent, name, attributes)
Beispiel #9
0
def getArgumentsSpecification(callable):
    '''
    This is an extension of Python module :py:mod:`inspect.getargspec` that
    accepts classes and returns only information about the parameters that can
    be used in a call to *callable* (*e.g.* the first *self* parameter of bound
    methods is ignored). If *callable* has not an appropriate type, a
    :class:`TypeError <exceptions.TypeError>` exception is raised.

    Parameters
    ----------
    callable: callable
        *function*, *method*, *class* or *instance* to inspect

    Returns
    -------
    tuple:
        As :func:`inspect.getargspec`, returns
        *(args, varargs, varkw, defaults)* where *args* is a list of the
        argument names (it may contain nested lists). *varargs* and *varkw* are
        the names of the ``*`` and ``**`` arguments or *None*. *defaults* is a
        n-tuple of the default values of the last *n* arguments.
    '''
    if inspect.isfunction(callable):
        return getfullargspec(callable)[:4]
    elif inspect.ismethod(callable):
        args, varargs, varkw, defaults = getfullargspec(callable)[:4]
        args = args[1:]  # ignore the first "self" parameter
        return args, varargs, varkw, defaults
    elif inspect.isclass(callable):
        try:
            init = callable.__init__
        except AttributeError:
            return [], None, None, None
        return getArgumentsSpecification(init)
    elif isinstance(callable, (partial, SomaPartial)):
        args, varargs, varkw, defaults = getArgumentsSpecification(
            callable.func)
        if defaults:
            d = dict(zip(reversed(args), reversed(defaults)))
        else:
            d = {}
        d.update(zip(reversed(args), reversed(callable.args)))
        if callable.keywords:
            d.update(callable.keywords)

        if len(d):
            defaults = tuple((d[i] for i in args[-len(d):]))
        else:
            defaults = d

        return (args, varargs, varkw, defaults)
    else:
        try:
            call = callable.__call__
        except AttributeError:
            raise TypeError(_('%s is not callable') % repr(callable))
        return getArgumentsSpecification(call)
Beispiel #10
0
def createMinfReducer(name):
    '''
    Return an instance of L{MinfReducer} previously registered.

    @param name: name of the reducer
    @type  name: string
    '''
    reducer = MinfReducer._allReducers.get(name)
    if reducer is None:
        raise MinfError(_('Unknown Minf reducer: %s') % (name, ))
    return reducer
Beispiel #11
0
def createMinfExpander(name):
    '''
    Return an instance of L{MinfExpander} previously registered.

    @param name: name of the expander
    @type  name: string
    '''
    expander = MinfExpander._allExpanders.get(name)
    if expander is None:
        raise KeyError(_('Unknown Minf expander: %s') % (name, ))
    return expander
Beispiel #12
0
 def xml(item):
     '''
     Build an XML unicode string based on either an XML string (in that case it
     is returned as is) or an XHTML instance.
     @param item: value to convert in XML.
     @type  item: XHTML instance or unicode containing XML
     '''
     if isinstance(item, six.string_types):
         return item
     elif isinstance(item, XHTML):
         return item._itemXML(item)
     else:
         raise RuntimeError(
             _('Cannot use XHTML converter for %s') % (str(item), ))
Beispiel #13
0
 def html(item):
     '''
     Build an HTML unicode string based on either an HTML string (in that case it
     is returned as is) or an XHTML instance.
     @param item: value to convert in HTML.
     @type  item: XHTML instance or unicode containing HTML
     '''
     if isinstance(item, basestring):
         return item
     elif isinstance(item, XHTML):
         return item._contentXML(item.content)
     else:
         raise RuntimeError(
             _('Cannot use XHTML converter for %s') % (unicode(item),))
Beispiel #14
0
 def getTypeReducer(self, classOrName):
     if not isinstance(classOrName, six.string_types):
         className = classOrName.__module__ + '.' + classOrName.__name__
     else:
         className = classOrName
     reducer = self.typeReducers.get(className)
     if reducer is None:
         for base in self.bases:
             reducer = base.getTypeReducer(className)
             if reducer is not None:
                 break
         else:
             if issubclass(classOrName, HasSignature):
                 return self.hasSignatureReducer
                 raise MinfError(
                     _('Automatic reduction of HasSignature not implemented'
                       ))
             raise MinfError(
                 _('Object of type %(class)s cannot be reduced '
                   'in Minf "%(minf)s" structure') % {
                       'class': className,
                       'minf': self.name
                   })
     return reducer
Beispiel #15
0
 def getTypeExpander(self, structureName):
     expander = self.typeExpanders.get(structureName)
     if expander is None:
         for base in self.bases:
             expander = base.getTypeExpander(structureName)
             if expander is not None:
                 break
         else:
             raise MinfError(
                 _('Minf structure %(struct)s cannot be expanded '
                   'from Minf "%(minf)s" structure') % {
                       'struct': structureName,
                       'minf': self.name
                   })
     return expander
Beispiel #16
0
 def createReader(format):
     '''
     This static method create a L{MinfReader} instance by looking for a registered
     L{MinfReader} derived classes named C{format}.
     @param format: name of the minf format.
     @type  format: string
     @returns: L{MinfReader} derived class instance.
     '''
     reader = MinfReader._allReaderClasses.get(format)
     if reader is None:
         raise ValueError(
             _('No minf reader for format "%(format)s", possible formats are: %(possible)s'
               ) %
             {
                 'format':
                 format,
                 'possible':
                 ', '.join(
                     ['"' + i + '"' for i in MinfReader._allReaderClasses])
             })
     return reader()
Beispiel #17
0
 def expand(self,
            minfNodeIterator,
            minfNode=Undefined,
            target=None,
            targetType=Undefined,
            stop_on_error=True,
            exceptions=[]):
     if minfNode is Undefined:
         if sys.version_info[0] >= 3:
             minfNode = next(minfNodeIterator)
         else:
             minfNode = minfNodeIterator.next()
     if isinstance(minfNode, StartStructure):
         identifier = minfNode.identifier
         typeExpander = self.getTypeExpander(minfNode.type)
         try:
             result = typeExpander(self,
                                   minfNode,
                                   minfNodeIterator,
                                   target=target,
                                   targetType=targetType,
                                   stop_on_error=stop_on_error,
                                   exceptions=exceptions)
         except Exception as e:
             if stop_on_error:
                 raise
             else:
                 result = None
                 exceptions.append(sys.exc_info())
         if identifier is not None:
             self.objectsWithIdentifier[identifier] = result
         return result
     elif isinstance(minfNode, EndStructure):
         raise MinfError(
             _('Minf structure %s ended but not started') %
             (minfNode.type, ))
     elif isinstance(minfNode, Reference):
         return self.objectsWithIdentifier[minfNode.identifier]
     else:
         return minfNode
Beispiel #18
0
 def __call__(self,
              expander,
              minfNode,
              minfNodeIterator,
              target,
              targetType,
              stop_on_error=True,
              exceptions=[]):
     structureName = minfNode.type
     args = []
     kwargs = {}
     for minfNode in minfNodeIterator:
         if isinstance(minfNode, EndStructure):
             if minfNode.type != structureName:
                 raise MinfError(
                     _('Wrong Minf structure ending, expecting %(exp)s instead of %(rcv)s'
                       ) % {
                           'exp': structureName,
                           'rcv': minfNode.type
                       })
             break
         else:
             key = expander.expand(minfNodeIterator,
                                   minfNode,
                                   stop_on_error=stop_on_error,
                                   exceptions=exceptions)
             try:
                 value = expander.expand(minfNodeIterator,
                                         stop_on_error=stop_on_error,
                                         exceptions=exceptions)
                 if key is None:
                     args.append(value)
                 else:
                     kwargs[str(key)] = value
             except Exception as e:
                 if stop_on_error:
                     raise e
                 else:
                     exceptions.append(sys.exc_info())
     return self.factory(*args, **kwargs)
Beispiel #19
0
def checkParameterCount(callable, paramCount):
    '''
    Checks that a callable can be called with *paramCount* arguments. If not, a
    RuntimeError is raised.

    .. seealso:: :func:`getArgumentsSpecification`

    Parameters
    ----------
    callable: callable
        *function*, *method*, *class* or *instance* to inspect
    paramCount: int
        number of parameters

    '''
    minimum, maximum = numberOfParameterRange(callable)
    if ( maximum is not None and paramCount > maximum ) or \
       paramCount < minimum:
        raise RuntimeError(
            _('%(callable)s cannot be called with %(paramCount)d arguments') %
            {
                'callable': getCallableString(callable),
                'paramCount': paramCount
            })
Beispiel #20
0
def minfFormat(source):
    '''
    Return a pair (format, reduction) identifying the minf format. If
    source is not a minf file, (None, None) is returned. Otherwise,
    format is a string representing the format of the minf file: 'XML' or
    'python'. reduction is the name of the reducer used to write the minf
    file or None if format is 'python'.

    Example:

    ::

      from soma.minf.api import minfFormat
      format, reduction = minfFormat('/home/me/test.minf')

    If source is a :class:`BufferAndFile` instance, this call behave as if nothing
    has been read from the file. This can be useful if you have an opened file
    that cannot be seeked backward:

    Example:

    ::

      from soma.bufferandfile import BufferAndFile
      from soma.minf.api import minfFormat, readMinf

      bf = BufferAndFile(stream_file_object)
      format, reduction = minfFormat(bf)
      if format is not None:
        minfContent = readMinf(bf)


    Parameters
    ----------
    source: string
      Input file name or file object. If it is a file name, it is
      opened with open(source).
    '''
    if not hasattr(source, 'readline'):
        source = BufferAndFile(open(source))
    elif not isinstance(source, BufferAndFile):
        source.seek(0)
        source = BufferAndFile(source)

    # Check first non white character to see if the minf file is XML or not
    start = source.read(5)
    if start == 'attri':
        source.unread(start)
        return ('python', None)
    elif start != '<?xml':
        # Try gzip compressed file
        gzipSource = source.clone()
        gzipSource.unread(start)
        gunzipSource = gzip.GzipFile(source.name)
        try:
            start = gunzipSource.read(5)
        except IOError:
            start = ''
        if start != '<?xml':
            raise MinfError(_('Invalid minf file: %s') % (source.name, ))
        source.change_file(gunzipSource)
        source.unread(start)
    else:
        source.unread(start)

    r = MinfReader.createReader('XML')
    reduction, buffer = r.reduction(source)
    source.unread(buffer)
    return ('XML', reduction)
Beispiel #21
0
def iterateMinf(source, targets=None, stop_on_error=True, exceptions=[]):
    '''
    Returns an iterator over all objects stored in a minf file.

    Example:

    ::

      from soma.minf.api import iterateMinf

      for item in iterateMinf('test.minf'):
        print(repr(item))

    Parameters
    ----------
    source: string
      Input file name or file object. If it is a file name, it is
      opened with C{open( source )}.
    '''
    if targets is not None:
        targets = iter(targets)

    initial_source = source

    if sys.version_info[0] >= 3 and not hasattr(initial_source, 'readline'):
        # in python3 the encoding of a file should be specified when opening
        # it: it cannot be changed afterwards. So in python3 we cannot read
        # the encoding within the file (for instance in a XML file).
        # This is completely silly, but here it is...
        # So we just have to try several encodings...
        try_encodings = ['UTF-8', 'latin1']
    else:
        try_encodings = [None]

    for encoding in try_encodings:
        if not hasattr(initial_source, 'readline'):
            if sys.version_info[0] >= 3:
                source = BufferAndFile(open(initial_source, encoding=encoding))
            else:
                source = BufferAndFile(open(initial_source))
        elif not isinstance(source, BufferAndFile):
            source.seek(0)
            source = BufferAndFile(source)

        try:
            # Check first non white character to see if the minf file is XML or not
            start = source.read(5)
            source.unread(start)
            if sys.version_info[0] >= 3:

                def next(it):
                    return it.__next__()
            else:

                def next(it):
                    return it.next()

            if start == 'attri':
                try:
                    import numpy
                    d = {'nan': numpy.nan}
                except:
                    d = {'nan': None}
                try:
                    six.exec_(source.read().replace("\r\n", "\n"), d)
                except Exception as e:
                    x = source
                    if hasattr(source, '_BufferAndFile__file'):
                        x = source._BufferAndFile__file
                    x = 'Error in iterateMinf while reading ' + str(x) + ': '
                    msg = x + e.message
                    # e.message = msg
                    # e.args = ( x + e.args[0], ) + e.args[1:]
                    print(x)
                    raise
                minf = d['attributes']
                if targets is not None:
                    result = next(targets)
                    _setTarget(result, minf)
                    yield result
                else:
                    yield minf
                return
            elif start != '<?xml':
                # Try gzip compressed file
                gzSource = gzip.GzipFile(source.name)
                if gzSource.read(5) != '<?xml':
                    raise MinfError(
                        _('Invalid minf file: %s') % (source.name, ))
                source = BufferAndFile(gzSource)
                source.unread('<?xml')

            r = MinfReader.createReader('XML')
            iterator = r.nodeIterator(source)
            minfNode = next(iterator)
            expander = createMinfExpander(minfNode.attributes['reduction'])
            count = 0
            for nodeItem in iterator:
                count += 1
                if isinstance(nodeItem, EndStructure):
                    break
                target = None
                if targets is not None:
                    try:
                        target = next(targets)
                    except StopIteration:
                        targets = None
                yield expander.expand(iterator,
                                      nodeItem,
                                      target=target,
                                      stop_on_error=stop_on_error,
                                      exceptions=exceptions)
        except UnicodeDecodeError as e:
            if encoding == try_encodings[-1]:
                raise
            continue
        break  # no error, don't process next encoding
Beispiel #22
0
 def fatalError(self, error):
     raise MinfError(_('XML parse error: %s') %
                    (unicode(error), ) + ' (stack = ' +
                     ','.join(['"' + i + '"' for i in self._stack]) + ')')
Beispiel #23
0
 def checkNoMoreAttributes(self, attributes):
     if attributes:
         self.parseError(_('Invalid attribute": %(attributes)s') %
                         {'attributes': ', '.join(['"' + n + '"' for n in attributes])})
Beispiel #24
0
 def startElement(self, parser, name, attributes):
     parser.parseError(_('Unexpected tag "%s"') % (name, ))
Beispiel #25
0
 def startElement(self, parser, name, attributes):
     newHandler = MinfXMLHandler.getHandler(parser, self, name, attributes)
     if newHandler is None:
         parser.parseError(_('Unexpected tag "%s"') % (name, ))
     parser._handler = newHandler
Beispiel #26
0
    def dictExpander(expander,
                     minfNode,
                     minfNodeIterator,
                     target,
                     targetType,
                     stop_on_error=True,
                     exceptions=[]):
        if target is None:
            result = {}
        else:
            result = target
        for minfNode in minfNodeIterator:
            if isinstance(minfNode, EndStructure):
                if minfNode.type != dictStructure:
                    raise MinfError(
                        _('Wrong Minf structure ending, expectinf %(exp)s instead of %(rcv)s'
                          ) % {
                              'exp': dictStructure,
                              'rcv': minfNode.type
                          })
                break
            else:
                key = expander.expand(minfNodeIterator,
                                      minfNode,
                                      stop_on_error=stop_on_error,
                                      exceptions=exceptions)
                if isinstance(key, list):
                    # list objects are unhashable and cannot be used as dictionary key
                    # in this case they are converted to tuple
                    key = tuple(key)
                if isinstance(result, HasSignature):
                    targetType = result.signature.get(key, Undefined)
                    if targetType is not Undefined:
                        targetType = targetType.type
                    target = getattr(result, key, None)
                    try:
                        if isinstance(target, HasSignature) or isinstance(
                                targetType, Sequence):
                            value = expander.expand(
                                minfNodeIterator,
                                target=target,
                                targetType=targetType,
                                stop_on_error=stop_on_error,
                                exceptions=exceptions)
                        else:
                            value = expander.expand(
                                minfNodeIterator,
                                stop_on_error=stop_on_error,
                                exceptions=exceptions)
                        setattr(result, key, value)
                    except Exception as e:
                        if stop_on_error:
                            raise
                        else:
                            exceptions.append(sys.exc_info())

                else:
                    try:
                        value = expander.expand(minfNodeIterator,
                                                stop_on_error=stop_on_error,
                                                exceptions=exceptions)
                        result[key] = value
                    except Exception as e:
                        if stop_on_error:
                            raise
                        else:
                            exceptions.append(sys.exc_info())

        return result
Beispiel #27
0
    def _write(self, minfNodeIterator, minfNode, level, name):
        if minfNode is Undefined:
            if sys.version_info[0] >= 3:
                minfNode = next(minfNodeIterator)
            else:
                minfNode = minfNodeIterator.next()
        attributes = {}
        if name is not None:
            attributes[nameAttribute] = name
        if isinstance(minfNode, StartStructure):
            if minfNode.type == listStructure:
                naming = False
                stringNaming = False
                length = minfNode.attributes.get('length')
                if length:
                    attributes[lengthAttribute] = length
                tag = listTag
            elif minfNode.type == dictStructure:
                naming = True
                stringNaming = False
                length = minfNode.attributes.get('length')
                if length:
                    attributes[lengthAttribute] = length
                tag = dictionaryTag
            else:
                naming = True
                stringNaming = True
                tag = factoryTag
                attributes[objectTypeAttribute] = minfNode.type
            if attributes:
                attributes = ' ' + \
                    ' '.join([n + '=' + xml_quoteattr(unicode(v))
                             for n, v in six.iteritems(attributes)])
            else:
                attributes = ''
            self._encodeAndWriteLine('<' + tag + attributes + '>', level)
            ntype = minfNode.type
            for minfNode in minfNodeIterator:
                if isinstance(minfNode, EndStructure):
                    if ntype != minfNode.type:
                        raise MinfError(
                            _('Wrong Minf structure ending, expecting %(exp)s instead of %(rcv)s'
                              ) % {
                                  'exp': ntype,
                                  'rcv': minfNode.type
                              })
                    self._encodeAndWriteLine('</' + tag + '>', level)
                    break
                elif naming:
                    if isinstance(minfNode, six.string_types):
                        self._write(minfNodeIterator, Undefined, level + 1,
                                    minfNode)
                    elif minfNode is None:
                        if not stringNaming:
                            self._write(minfNodeIterator, minfNode, level + 1,
                                        None)
                        self._write(minfNodeIterator, Undefined, level + 1,
                                    None)
                    else:
                        self._write(minfNodeIterator, minfNode, level + 1,
                                    None)
                        self._write(minfNodeIterator, Undefined, level + 1,
                                    None)
                else:
                    self._write(minfNodeIterator, minfNode, level + 1, None)
        elif isinstance(minfNode, EndStructure):
            raise MinfError(
                _('Unexpected Minf structure ending: %s') % (minfNode.type, ))
            level -= 1
        else:
            if attributes:
                attributesXML = ' ' + \
                    ' '.join([n + '=' + xml_quoteattr(unicode(v))
                             for n, v in six.iteritems(attributes)])
            else:
                attributesXML = ''
            if minfNode is None:
                self._encodeAndWriteLine('<' + noneTag + attributesXML + '/>',
                                         level)
            elif isinstance(minfNode, bool):
                if minfNode:
                    self._encodeAndWriteLine(
                        '<' + trueTag + attributesXML + '/>', level)
                else:
                    self._encodeAndWriteLine(
                        '<' + falseTag + attributesXML + '/>', level)
            elif isinstance(minfNode, (int, float, long)):
                self._encodeAndWriteLine(
                    '<' + numberTag + attributesXML + '>' + unicode(minfNode) +
                    '</' + numberTag + '>', level)
            elif isinstance(minfNode, six.string_types):

                if type(minfNode) is byte_type:
                    try:
                        minfNode = minfNode.decode("utf-8")
                    except UnicodeDecodeError:
                        minfNode = minfNode.decode("iso-8859-1")
                self._encodeAndWriteLine(
                    '<' + stringTag + attributesXML + '>' +
                    xml_escape(minfNode, xml_replacement) + '</' + stringTag +
                    '>', level)
            elif hasattr(minfNode, '__minfxml__'):
                minfNode.__minfxml__(self, attributes, level)
            else:
                raise MinfError(
                    _('Cannot save an object of type %s as an XML atom') %
                    (str(type(minfNode)), ))