Edgewall Software

Ticket #429: t429-refactor-r1038.patch

File t429-refactor-r1038.patch, 5.9 KB (added by cboos, 12 years ago)

first refactor r1038... (applies on r1162)

  • genshi/output.py

    # HG changeset patch
    # Parent 924949fd71673266ccb00169f99ae7cd47496d16
    output: refactor code relative to the token serialization cache (introduced in [1038]).
    
    In preparation for fixing #429.
    
    diff -r 924949fd7167 genshi/output.py
    a b def get_serializer(method='xml', **kwarg 
    7979    return method(**kwargs)
    8080
    8181
     82def _prepare_cache(use_cache=True):
     83    """Prepare a private token serialization cache.
     84
     85    :param use_cache: boolean indicating whether a real cache should
     86                      be used or not. If not, the returned functions
     87                      are no-ops.
     88
     89    :return: emit and get functions, for storing and retrieving
     90             serialized values from the cache.
     91    """
     92    cache = {}
     93    if use_cache:
     94        def _emit(kind, input, output):
     95            cache[kind, input] = output
     96            return output
     97        def _get(kind, input):
     98            return cache.get((kind, input))
     99    else:
     100        def _emit(kind, input, output):
     101            return output
     102        def _get(kind, input):
     103            pass
     104    return _emit, _get, cache
     105
     106
    82107class DocType(object):
    83108    """Defines a number of commonly used DOCTYPE declarations as constants."""
    84109
    class XMLSerializer(object): 
    204229            self.filters.append(DocTypeInserter(doctype))
    205230        self.cache = cache
    206231
     232    def _prepare_cache(self):
     233        return _prepare_cache(self.cache)[:2]
     234
    207235    def __call__(self, stream):
    208236        have_decl = have_doctype = False
    209237        in_cdata = False
    210 
    211         cache = {}
    212         cache_get = cache.get
    213         if self.cache:
    214             def _emit(kind, input, output):
    215                 cache[kind, input] = output
    216                 return output
    217         else:
    218             def _emit(kind, input, output):
    219                 return output
     238        _emit, _get = self._prepare_cache()
    220239
    221240        for filter_ in self.filters:
    222241            stream = filter_(stream)
    223242        for kind, data, pos in stream:
    224             cached = cache_get((kind, data))
     243            cached = _get(kind, data)
    225244            if cached is not None:
    226245                yield cached
    227 
    228246            elif kind is START or kind is EMPTY:
    229247                tag, attrib = data
    230248                buf = ['<', tag]
    class XHTMLSerializer(XMLSerializer): 
    323341        drop_xml_decl = self.drop_xml_decl
    324342        have_decl = have_doctype = False
    325343        in_cdata = False
    326 
    327         cache = {}
    328         cache_get = cache.get
    329         if self.cache:
    330             def _emit(kind, input, output):
    331                 cache[kind, input] = output
    332                 return output
    333         else:
    334             def _emit(kind, input, output):
    335                 return output
     344        _emit, _get = self._prepare_cache()
    336345
    337346        for filter_ in self.filters:
    338347            stream = filter_(stream)
    339348        for kind, data, pos in stream:
    340             cached = cache_get((kind, data))
     349            cached = _get(kind, data)
    341350            if cached is not None:
    342351                yield cached
    343352
    class HTMLSerializer(XHTMLSerializer): 
    454463        noescape_elems = self._NOESCAPE_ELEMS
    455464        have_doctype = False
    456465        noescape = False
    457 
    458         cache = {}
    459         cache_get = cache.get
    460         if self.cache:
    461             def _emit(kind, input, output):
    462                 cache[kind, input] = output
    463                 return output
    464         else:
    465             def _emit(kind, input, output):
    466                 return output
     466        _emit, _get = self._prepare_cache()
    467467
    468468        for filter_ in self.filters:
    469469            stream = filter_(stream)
    470470        for kind, data, _ in stream:
    471             output = cache_get((kind, data))
     471            output = _get(kind, data)
    472472            if output is not None:
    473473                yield output
    474474                if (kind is START or kind is EMPTY) \
    class NamespaceFlattener(object): 
    626626        self.cache = cache
    627627
    628628    def __call__(self, stream):
    629         cache = {}
    630         cache_get = cache.get
    631         if self.cache:
    632             def _emit(kind, input, output, pos):
    633                 cache[kind, input] = output
    634                 return kind, output, pos
    635         else:
    636             def _emit(kind, input, output, pos):
    637                 return output
    638 
    639629        prefixes = dict([(v, [k]) for k, v in self.prefixes.items()])
    640630        namespaces = {XML_NAMESPACE.uri: ['xml']}
     631        _emit, _get, cache = _prepare_cache(self.cache)
    641632        def _push_ns(prefix, uri):
    642633            namespaces.setdefault(uri, []).append(prefix)
    643634            prefixes.setdefault(prefix, []).append(uri)
    class NamespaceFlattener(object): 
    668659        _gen_prefix = _gen_prefix().next
    669660
    670661        for kind, data, pos in stream:
    671             output = cache_get((kind, data))
     662            output = _get(kind, data)
    672663            if output is not None:
    673664                yield kind, output, pos
    674665
    class NamespaceFlattener(object): 
    701692                            attrname = '%s:%s' % (prefix, attrname)
    702693                    new_attrs.append((attrname, value))
    703694
    704                 yield _emit(kind, data, (tagname, Attrs(ns_attrs + new_attrs)), pos)
     695                data = _emit(kind, data, (tagname, Attrs(ns_attrs + new_attrs)))
     696                yield kind, data, pos
    705697                del ns_attrs[:]
    706698
    707699            elif kind is END:
    class NamespaceFlattener(object): 
    711703                    prefix = namespaces[tagns][-1]
    712704                    if prefix:
    713705                        tagname = '%s:%s' % (prefix, tagname)
    714                 yield _emit(kind, data, tagname, pos)
     706                yield kind, _emit(kind, data, tagname), pos
    715707
    716708            elif kind is START_NS:
    717709                prefix, uri = data