diff --git a/textproc/py-genshi/Makefile b/textproc/py-genshi/Makefile index 6d4b0e44f90f..fba3d0399c41 100644 --- a/textproc/py-genshi/Makefile +++ b/textproc/py-genshi/Makefile @@ -1,27 +1,28 @@ PORTNAME= Genshi -PORTVERSION= 0.7.3 +PORTVERSION= 0.7.7 CATEGORIES= textproc www python MASTER_SITES= CHEESESHOP PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} MAINTAINER= nivit@FreeBSD.org COMMENT= Toolkit for generation of output for the web WWW= https://genshi.edgewall.org/ LICENSE= BSD3CLAUSE LICENSE_FILE= ${WRKSRC}/COPYING USES= python:3.6+ -USE_PYTHON= distutils autoplist +USE_PYTHON= autoplist distutils OPTIONS_DEFINE= BABEL BABEL_DESC= I18n support through the Babel plugin BABEL_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}Babel>=0.8:devel/py-babel@${PY_FLAVOR} +post-install: + @${STRIP_CMD} ${STAGEDIR}${PYTHON_SITELIBDIR}/genshi/_speedups${PYTHON_EXT_SUFFIX}.so + do-test: @cd ${WRKSRC} && ${PYTHON_CMD} ${PYDISTUTILS_SETUP} test -NO_ARCH= yes - .include diff --git a/textproc/py-genshi/distinfo b/textproc/py-genshi/distinfo index 468327f873ab..9de867152159 100644 --- a/textproc/py-genshi/distinfo +++ b/textproc/py-genshi/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1576467154 -SHA256 (Genshi-0.7.3.tar.gz) = 7933c95151d7dd2124a2b4c8dd85bb6aec881ca17c0556da0b40e56434b313a0 -SIZE (Genshi-0.7.3.tar.gz) = 271238 +TIMESTAMP = 1664204725 +SHA256 (Genshi-0.7.7.tar.gz) = c100520862cd69085d10ee1a87e91289e7f59f6b3d9bd622bf58b2804e6b9aab +SIZE (Genshi-0.7.7.tar.gz) = 267206 diff --git a/textproc/py-genshi/files/patch-2to3 b/textproc/py-genshi/files/patch-2to3 deleted file mode 100644 index 1764fbffbda4..000000000000 --- a/textproc/py-genshi/files/patch-2to3 +++ /dev/null @@ -1,5818 +0,0 @@ ---- examples/basic/kidrun.py.orig 2019-05-27 21:03:08 UTC -+++ examples/basic/kidrun.py -@@ -17,11 +17,11 @@ def test(): - - start = time.clock() - template = kid.Template(file='test.kid', **ctxt) -- print ' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000) -+ print(' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000)) - - for output in template.generate(): - sys.stdout.write(output) -- print -+ print() - - times = [] - for i in range(1000): -@@ -30,10 +30,10 @@ def test(): - times.append(time.clock() - start) - sys.stdout.write('.') - sys.stdout.flush() -- print -+ print() - -- print ' --> render stage: %s ms (average)' % ( -- (sum(times) / len(times) * 1000)) -+ print(' --> render stage: %s ms (average)' % ( -+ (sum(times) / len(times) * 1000))) - - if __name__ == '__main__': - if '-p' in sys.argv: ---- examples/basic/run.py.orig 2019-05-27 21:03:08 UTC -+++ examples/basic/run.py -@@ -13,13 +13,13 @@ def test(): - - start = time.clock() - tmpl = loader.load('test.html') -- print ' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000) -+ print(' --> parse stage: %.4f ms' % ((time.clock() - start) * 1000)) - - data = dict(hello='', skin='default', hey='ZYX', bozz=None, - items=['Number %d' % num for num in range(1, 15)], - prefix='#') - -- print tmpl.generate(**data).render(method='html') -+ print(tmpl.generate(**data).render(method='html')) - - times = [] - for i in range(1000): -@@ -28,10 +28,10 @@ def test(): - times.append(time.clock() - start) - sys.stdout.write('.') - sys.stdout.flush() -- print -+ print() - -- print ' --> render stage: %s ms (average)' % ( -- (sum(times) / len(times) * 1000)) -+ print(' --> render stage: %s ms (average)' % ( -+ (sum(times) / len(times) * 1000))) - - if __name__ == '__main__': - if '-p' in sys.argv: ---- examples/bench/basic.py.orig 2019-05-27 21:03:08 UTC -+++ examples/bench/basic.py -@@ -5,7 +5,7 @@ - - from cgi import escape - import os --from StringIO import StringIO -+from io import StringIO - import sys - import timeit - -@@ -22,7 +22,7 @@ def genshi(dirname, verbose=False): - return template.generate(**data).render('xhtml') - - if verbose: -- print render() -+ print(render()) - return render - - def genshi_text(dirname, verbose=False): -@@ -36,14 +36,14 @@ def genshi_text(dirname, verbose=False): - return template.generate(**data).render('text') - - if verbose: -- print render() -+ print(render()) - return render - - def mako(dirname, verbose=False): - try: - from mako.lookup import TemplateLookup - except ImportError: -- print>>sys.stderr, 'Mako not installed, skipping' -+ print('Mako not installed, skipping', file=sys.stderr) - return lambda: None - lookup = TemplateLookup(directories=[dirname], filesystem_checks=False) - template = lookup.get_template('template.html') -@@ -52,7 +52,7 @@ def mako(dirname, verbose=False): - list_items=['Number %d' % num for num in range(1, 15)]) - return template.render(**data) - if verbose: -- print render() -+ print(render()) - return render - - def cheetah(dirname, verbose=False): -@@ -60,7 +60,7 @@ def cheetah(dirname, verbose=False): - try: - from Cheetah.Template import Template - except ImportError: -- print>>sys.stderr, 'Cheetah not installed, skipping' -+ print('Cheetah not installed, skipping', file=sys.stderr) - return lambda: None - class MyTemplate(Template): - def serverSidePath(self, path): return os.path.join(dirname, path) -@@ -70,18 +70,18 @@ def cheetah(dirname, verbose=False): - def render(): - template = MyTemplate(file=filename, - searchList=[{'title': 'Just a test', 'user': 'joe', -- 'items': [u'Number %d' % num for num in range(1, 15)]}]) -+ 'items': ['Number %d' % num for num in range(1, 15)]}]) - return template.respond() - - if verbose: -- print render() -+ print(render()) - return render - - def clearsilver(dirname, verbose=False): - try: - import neo_cgi - except ImportError: -- print>>sys.stderr, 'ClearSilver not installed, skipping' -+ print('ClearSilver not installed, skipping', file=sys.stderr) - return lambda: None - neo_cgi.update() - import neo_util -@@ -98,7 +98,7 @@ def clearsilver(dirname, verbose=False): - return cs.render() - - if verbose: -- print render() -+ print(render()) - return render - - def django(dirname, verbose=False): -@@ -106,7 +106,7 @@ def django(dirname, verbose=False): - from django.conf import settings - settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')]) - except ImportError: -- print>>sys.stderr, 'Django not installed, skipping' -+ print('Django not installed, skipping', file=sys.stderr) - return lambda: None - from django import template, templatetags - from django.template import loader -@@ -119,14 +119,14 @@ def django(dirname, verbose=False): - return tmpl.render(template.Context(data)) - - if verbose: -- print render() -+ print(render()) - return render - - def kid(dirname, verbose=False): - try: - import kid - except ImportError: -- print>>sys.stderr, "Kid not installed, skipping" -+ print("Kid not installed, skipping", file=sys.stderr) - return lambda: None - kid.path = kid.TemplatePath([dirname]) - template = kid.load_template('template.kid').Template -@@ -137,14 +137,14 @@ def kid(dirname, verbose=False): - ).serialize(output='xhtml') - - if verbose: -- print render() -+ print(render()) - return render - - def simpletal(dirname, verbose=False): - try: - from simpletal import simpleTAL, simpleTALES - except ImportError: -- print>>sys.stderr, "SimpleTAL not installed, skipping" -+ print("SimpleTAL not installed, skipping", file=sys.stderr) - return lambda: None - fileobj = open(os.path.join(dirname, 'base.html')) - base = simpleTAL.compileHTMLTemplate(fileobj) -@@ -163,7 +163,7 @@ def simpletal(dirname, verbose=False): - return buf.getvalue() - - if verbose: -- print render() -+ print(render()) - return render - - def run(engines, number=2000, verbose=False): -@@ -171,19 +171,19 @@ def run(engines, number=2000, verbose=False): - for engine in engines: - dirname = os.path.join(basepath, engine) - if verbose: -- print '%s:' % engine.capitalize() -- print '--------------------------------------------------------' -+ print('%s:' % engine.capitalize()) -+ print('--------------------------------------------------------') - else: -- print '%s:' % engine.capitalize(), -+ print('%s:' % engine.capitalize(), end=' ') - t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)' - % (engine, engine, dirname, verbose), - stmt='render()') - time = t.timeit(number=number) / number - if verbose: -- print '--------------------------------------------------------' -- print '%.2f ms' % (1000 * time) -+ print('--------------------------------------------------------') -+ print('%.2f ms' % (1000 * time)) - if verbose: -- print '--------------------------------------------------------' -+ print('--------------------------------------------------------') - - - if __name__ == '__main__': ---- examples/bench/bigtable.py.orig 2019-05-27 21:03:08 UTC -+++ examples/bench/bigtable.py -@@ -8,7 +8,7 @@ - import cgi - import sys - import timeit --from StringIO import StringIO -+from io import StringIO - from genshi.builder import tag - from genshi.template import MarkupTemplate, NewTextTemplate - -@@ -111,7 +111,7 @@ def test_genshi_text(): - def test_genshi_builder(): - """Genshi template + tag builder""" - stream = tag.TABLE([ -- tag.tr([tag.td(c) for c in row.values()]) -+ tag.tr([tag.td(c) for c in list(row.values())]) - for row in table - ]).generate() - stream = genshi_tmpl2.generate(table=stream) -@@ -121,7 +121,7 @@ def test_builder(): - """Genshi tag builder""" - stream = tag.TABLE([ - tag.tr([ -- tag.td(c) for c in row.values() -+ tag.td(c) for c in list(row.values()) - ]) - for row in table - ]).generate() -@@ -151,7 +151,7 @@ if kid: - _table = cet.Element('table') - for row in table: - td = cet.SubElement(_table, 'tr') -- for c in row.values(): -+ for c in list(row.values()): - cet.SubElement(td, 'td').text=str(c) - kid_tmpl2.table = _table - kid_tmpl2.serialize(output='html') -@@ -162,7 +162,7 @@ if et: - _table = et.Element('table') - for row in table: - tr = et.SubElement(_table, 'tr') -- for c in row.values(): -+ for c in list(row.values()): - et.SubElement(tr, 'td').text=str(c) - et.tostring(_table) - -@@ -172,7 +172,7 @@ if cet: - _table = cet.Element('table') - for row in table: - tr = cet.SubElement(_table, 'tr') -- for c in row.values(): -+ for c in list(row.values()): - cet.SubElement(tr, 'td').text=str(c) - cet.tostring(_table) - -@@ -201,7 +201,7 @@ def run(which=None, number=10): - 'test_et', 'test_cet', 'test_clearsilver', 'test_django'] - - if which: -- tests = filter(lambda n: n[5:] in which, tests) -+ tests = [n for n in tests if n[5:] in which] - - for test in [t for t in tests if hasattr(sys.modules[__name__], t)]: - t = timeit.Timer(setup='from __main__ import %s;' % test, -@@ -212,7 +212,7 @@ def run(which=None, number=10): - result = ' (not installed?)' - else: - result = '%16.2f ms' % (1000 * time) -- print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result) -+ print('%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)) - - - if __name__ == '__main__': ---- examples/bench/xpath.py.orig 2019-05-27 21:03:08 UTC -+++ examples/bench/xpath.py -@@ -32,7 +32,7 @@ def benchmark(f, acurate_time=1): - runs = 1 - while True: - start_time = time_func() -- for _ in xrange(runs): -+ for _ in range(runs): - f() - dt = time_func() - start_time - if dt >= acurate_time: -@@ -61,23 +61,23 @@ def spell(t): - - def test_paths_in_streams(exprs, streams, test_strategies=False): - for expr in exprs: -- print "Testing path %r" % expr -+ print("Testing path %r" % expr) - for stream, sname in streams: -- print '\tRunning on "%s" example:' % sname -+ print('\tRunning on "%s" example:' % sname) - - path = Path(expr) - def f(): - for e in path.select(stream): - pass - t = spell(benchmark(f)) -- print "\t\tselect:\t\t%s" % t -+ print("\t\tselect:\t\t%s" % t) - - def f(): - path = Path(expr) - for e in path.select(stream): - pass - t = spell(benchmark(f)) -- print "\t\tinit + select:\t%s" % t -+ print("\t\tinit + select:\t%s" % t) - - if test_strategies and len(path.paths) == 1: - from genshi.path import GenericStrategy, SingleStepStrategy, \ -@@ -88,13 +88,13 @@ def test_paths_in_streams(exprs, streams, test_strateg - for strategy in strategies: - if not strategy.supports(path.paths[0]): - continue -- print "\t\t%s Strategy"%strategy.__name__ -+ print("\t\t%s Strategy"%strategy.__name__) - fp = FakePath(strategy(path.paths[0])) - def f(): - for e in fp.select(stream): - pass - t = spell(benchmark(f)) -- print "\t\t\tselect:\t\t%s"%t -+ print("\t\t\tselect:\t\t%s"%t) - - - def test_documents(test_strategies=False): ---- examples/tutorial/geddit/controller.py.orig 2019-05-27 21:03:08 UTC -+++ examples/tutorial/geddit/controller.py -@@ -20,7 +20,7 @@ class Root(object): - @cherrypy.expose - @template.output('index.html') - def index(self): -- links = sorted(self.data.values(), key=operator.attrgetter('time')) -+ links = sorted(list(self.data.values()), key=operator.attrgetter('time')) - return template.render(links=links) - - @cherrypy.expose -@@ -35,7 +35,7 @@ class Root(object): - link = Link(**data) - self.data[link.id] = link - raise cherrypy.HTTPRedirect('/') -- except Invalid, e: -+ except Invalid as e: - errors = e.unpack_errors() - else: - errors = {} -@@ -69,7 +69,7 @@ class Root(object): - raise cherrypy.HTTPRedirect('/info/%s' % link.id) - return template.render('_comment.html', comment=comment, - num=len(link.comments)) -- except Invalid, e: -+ except Invalid as e: - errors = e.unpack_errors() - else: - errors = {} -@@ -89,7 +89,7 @@ class Root(object): - raise cherrypy.NotFound() - return template.render('info.xml', link=link) - else: -- links = sorted(self.data.values(), key=operator.attrgetter('time')) -+ links = sorted(list(self.data.values()), key=operator.attrgetter('time')) - return template.render(links=links) - - ---- genshi/builder.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/builder.py -@@ -107,7 +107,7 @@ class Fragment(object): - return str(self.generate()) - - def __unicode__(self): -- return unicode(self.generate()) -+ return str(self.generate()) - - def __html__(self): - return Markup(self.generate()) -@@ -118,7 +118,7 @@ class Fragment(object): - :param node: the node to append; can be an `Element`, `Fragment`, or a - `Stream`, or a Python string or number - """ -- if isinstance(node, (Stream, Element, basestring, int, float, long)): -+ if isinstance(node, (Stream, Element, str, int, float)): - # For objects of a known/primitive type, we avoid the check for - # whether it is iterable for better performance - self.children.append(node) -@@ -140,8 +140,8 @@ class Fragment(object): - for event in child: - yield event - else: -- if not isinstance(child, basestring): -- child = unicode(child) -+ if not isinstance(child, str): -+ child = str(child) - yield TEXT, child, (None, -1, -1) - - def generate(self): -@@ -155,10 +155,10 @@ class Fragment(object): - def _kwargs_to_attrs(kwargs): - attrs = [] - names = set() -- for name, value in kwargs.items(): -+ for name, value in list(kwargs.items()): - name = name.rstrip('_').replace('_', '-') - if value is not None and name not in names: -- attrs.append((QName(name), unicode(value))) -+ attrs.append((QName(name), str(value))) - names.add(name) - return Attrs(attrs) - ---- genshi/compat.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/compat.py -@@ -40,7 +40,7 @@ else: - - if IS_PYTHON2: - def isstring(obj): -- return isinstance(obj, basestring) -+ return isinstance(obj, str) - else: - def isstring(obj): - return isinstance(obj, str) -@@ -48,9 +48,9 @@ else: - # We need to differentiate between StringIO and BytesIO in places - - if IS_PYTHON2: -- from StringIO import StringIO -+ from io import StringIO - try: -- from cStringIO import StringIO as BytesIO -+ from io import StringIO as BytesIO - except ImportError: - BytesIO = StringIO - else: -@@ -124,7 +124,7 @@ try: - next = next - except NameError: - def next(iterator): -- return iterator.next() -+ return iterator.__next__() - - # Compatibility fallback implementations for Python < 2.5 - ---- genshi/core.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/core.py -@@ -271,7 +271,7 @@ def _ensure(stream): - """Ensure that every item on the stream is actually a markup event.""" - stream = iter(stream) - try: -- event = stream.next() -+ event = next(stream) - except StopIteration: - return - -@@ -282,7 +282,7 @@ def _ensure(stream): - if hasattr(event, 'totuple'): - event = event.totuple() - else: -- event = TEXT, unicode(event), (None, -1, -1) -+ event = TEXT, str(event), (None, -1, -1) - yield event - return - -@@ -411,7 +411,7 @@ class Attrs(tuple): - :return: a new instance with the attribute removed - :rtype: `Attrs` - """ -- if isinstance(names, basestring): -+ if isinstance(names, str): - names = (names,) - return Attrs([(name, val) for name, val in self if name not in names]) - -@@ -445,33 +445,33 @@ class Attrs(tuple): - return TEXT, ''.join([x[1] for x in self]), (None, -1, -1) - - --class Markup(unicode): -+class Markup(str): - """Marks a string as being safe for inclusion in HTML/XML output without - needing to be escaped. - """ - __slots__ = [] - - def __add__(self, other): -- return Markup(unicode.__add__(self, escape(other))) -+ return Markup(str.__add__(self, escape(other))) - - def __radd__(self, other): -- return Markup(unicode.__add__(escape(other), self)) -+ return Markup(str.__add__(escape(other), self)) - - def __mod__(self, args): - if isinstance(args, dict): -- args = dict(zip(args.keys(), map(escape, args.values()))) -+ args = dict(list(zip(list(args.keys()), list(map(escape, list(args.values())))))) - elif isinstance(args, (list, tuple)): - args = tuple(map(escape, args)) - else: - args = escape(args) -- return Markup(unicode.__mod__(self, args)) -+ return Markup(str.__mod__(self, args)) - - def __mul__(self, num): -- return Markup(unicode.__mul__(self, num)) -+ return Markup(str.__mul__(self, num)) - __rmul__ = __mul__ - - def __repr__(self): -- return "<%s %s>" % (type(self).__name__, unicode.__repr__(self)) -+ return "<%s %s>" % (type(self).__name__, str.__repr__(self)) - - def join(self, seq, escape_quotes=True): - """Return a `Markup` object which is the concatenation of the strings -@@ -488,7 +488,7 @@ class Markup(unicode): - :rtype: `Markup` - :see: `escape` - """ -- return Markup(unicode.join(self, [escape(item, quotes=escape_quotes) -+ return Markup(str.join(self, [escape(item, quotes=escape_quotes) - for item in seq])) - - @classmethod -@@ -538,7 +538,7 @@ class Markup(unicode): - """ - if not self: - return '' -- return unicode(self).replace('"', '"') \ -+ return str(self).replace('"', '"') \ - .replace('>', '>') \ - .replace('<', '<') \ - .replace('&', '&') -@@ -652,7 +652,7 @@ class Namespace(object): - self.uri = uri - - def __init__(self, uri): -- self.uri = unicode(uri) -+ self.uri = str(uri) - - def __contains__(self, qname): - return qname.namespace == self.uri -@@ -691,7 +691,7 @@ class Namespace(object): - XML_NAMESPACE = Namespace('http://www.w3.org/XML/1998/namespace') - - --class QName(unicode): -+class QName(str): - """A qualified element or attribute name. - - The unicode value of instances of this class contains the qualified name of -@@ -729,11 +729,11 @@ class QName(unicode): - qname = qname.lstrip('{') - parts = qname.split('}', 1) - if len(parts) > 1: -- self = unicode.__new__(cls, '{%s' % qname) -- self.namespace, self.localname = map(unicode, parts) -+ self = str.__new__(cls, '{%s' % qname) -+ self.namespace, self.localname = list(map(str, parts)) - else: -- self = unicode.__new__(cls, qname) -- self.namespace, self.localname = None, unicode(qname) -+ self = str.__new__(cls, qname) -+ self.namespace, self.localname = None, str(qname) - return self - - def __getnewargs__(self): ---- genshi/filters/html.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/filters/html.py -@@ -101,13 +101,13 @@ class HTMLFormFiller(object): - checked = False - if isinstance(value, (list, tuple)): - if declval is not None: -- checked = declval in [unicode(v) for v -+ checked = declval in [str(v) for v - in value] - else: - checked = any(value) - else: - if declval is not None: -- checked = declval == unicode(value) -+ checked = declval == str(value) - elif type == 'checkbox': - checked = bool(value) - if checked: -@@ -123,7 +123,7 @@ class HTMLFormFiller(object): - value = value[0] - if value is not None: - attrs |= [ -- (QName('value'), unicode(value)) -+ (QName('value'), str(value)) - ] - elif tagname == 'select': - name = attrs.get('name') -@@ -166,10 +166,10 @@ class HTMLFormFiller(object): - select_value = None - elif in_select and tagname == 'option': - if isinstance(select_value, (tuple, list)): -- selected = option_value in [unicode(v) for v -+ selected = option_value in [str(v) for v - in select_value] - else: -- selected = option_value == unicode(select_value) -+ selected = option_value == str(select_value) - okind, (tag, attrs), opos = option_start - if selected: - attrs |= [(QName('selected'), 'selected')] -@@ -185,7 +185,7 @@ class HTMLFormFiller(object): - option_text = [] - elif in_textarea and tagname == 'textarea': - if textarea_value: -- yield TEXT, unicode(textarea_value), pos -+ yield TEXT, str(textarea_value), pos - textarea_value = None - in_textarea = False - yield kind, data, pos -@@ -311,7 +311,7 @@ class HTMLSanitizer(object): - # The set of URI schemes that are considered safe. - - # IE6 -- _EXPRESSION_SEARCH = re.compile(u""" -+ _EXPRESSION_SEARCH = re.compile(""" - [eE - \uFF25 # FULLWIDTH LATIN CAPITAL LETTER E - \uFF45 # FULLWIDTH LATIN SMALL LETTER E -@@ -356,7 +356,7 @@ class HTMLSanitizer(object): - # IE6 - # 7) Particular bit of Unicode characters - _URL_FINDITER = re.compile( -- u'[Uu][Rr\u0280][Ll\u029F]\s*\(([^)]+)').finditer -+ '[Uu][Rr\u0280][Ll\u029F]\s*\(([^)]+)').finditer - - def __call__(self, stream): - """Apply the filter to the given stream. -@@ -528,7 +528,7 @@ class HTMLSanitizer(object): - def _repl(match): - t = match.group(1) - if t: -- return unichr(int(t, 16)) -+ return chr(int(t, 16)) - t = match.group(2) - if t == '\\': - return r'\\' ---- genshi/filters/i18n.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/filters/i18n.py -@@ -163,12 +163,12 @@ class MsgDirective(ExtractableI18NDirective): - - def _generate(): - msgbuf = MessageBuffer(self) -- previous = stream.next() -+ previous = next(stream) - if previous[0] is START: - yield previous - else: - msgbuf.append(*previous) -- previous = stream.next() -+ previous = next(stream) - for kind, data, pos in stream: - msgbuf.append(*previous) - previous = kind, data, pos -@@ -188,13 +188,13 @@ class MsgDirective(ExtractableI18NDirective): - strip = False - - stream = iter(stream) -- previous = stream.next() -+ previous = next(stream) - if previous[0] is START: - for message in translator._extract_attrs(previous, - gettext_functions, - search_text=search_text): - yield message -- previous = stream.next() -+ previous = next(stream) - strip = True - for event in stream: - if event[0] is START: -@@ -218,14 +218,14 @@ class ChooseBranchDirective(I18NDirective): - msgbuf = MessageBuffer(self) - stream = _apply_directives(stream, directives, ctxt, vars) - -- previous = stream.next() -+ previous = next(stream) - if previous[0] is START: - yield previous - else: - msgbuf.append(*previous) - - try: -- previous = stream.next() -+ previous = next(stream) - except StopIteration: - # For example or directives - yield MSGBUF, (), -1 # the place holder for msgbuf output -@@ -246,7 +246,7 @@ class ChooseBranchDirective(I18NDirective): - def extract(self, translator, stream, gettext_functions=GETTEXT_FUNCTIONS, - search_text=True, comment_stack=None, msgbuf=None): - stream = iter(stream) -- previous = stream.next() -+ previous = next(stream) - - if previous[0] is START: - # skip the enclosing element -@@ -254,7 +254,7 @@ class ChooseBranchDirective(I18NDirective): - gettext_functions, - search_text=search_text): - yield message -- previous = stream.next() -+ previous = next(stream) - - for event in stream: - if previous[0] is START: -@@ -427,7 +427,7 @@ class ChooseDirective(ExtractableI18NDirective): - search_text=True, comment_stack=None): - strip = False - stream = iter(stream) -- previous = stream.next() -+ previous = next(stream) - - if previous[0] is START: - # skip the enclosing element -@@ -435,7 +435,7 @@ class ChooseDirective(ExtractableI18NDirective): - gettext_functions, - search_text=search_text): - yield message -- previous = stream.next() -+ previous = next(stream) - strip = True - - singular_msgbuf = MessageBuffer(self) -@@ -480,8 +480,8 @@ class ChooseDirective(ExtractableI18NDirective): - # XXX: should we test which form was chosen like this!?!?!? - # There should be no match in any catalogue for these singular and - # plural test strings -- singular = u'O\x85\xbe\xa9\xa8az\xc3?\xe6\xa1\x02n\x84\x93' -- plural = u'\xcc\xfb+\xd3Pn\x9d\tT\xec\x1d\xda\x1a\x88\x00' -+ singular = 'O\x85\xbe\xa9\xa8az\xc3?\xe6\xa1\x02n\x84\x93' -+ plural = '\xcc\xfb+\xd3Pn\x9d\tT\xec\x1d\xda\x1a\x88\x00' - return ngettext(singular, plural, numeral) == plural - - -@@ -703,7 +703,7 @@ class Translator(DirectiveFactory): - if kind is START: - tag, attrs = data - if tag in self.ignore_tags or \ -- isinstance(attrs.get(xml_lang), basestring): -+ isinstance(attrs.get(xml_lang), str): - skip += 1 - yield kind, data, pos - continue -@@ -713,7 +713,7 @@ class Translator(DirectiveFactory): - - for name, value in attrs: - newval = value -- if isinstance(value, basestring): -+ if isinstance(value, str): - if translate_attrs and name in include_attrs: - newval = gettext(value) - else: -@@ -732,7 +732,7 @@ class Translator(DirectiveFactory): - elif translate_text and kind is TEXT: - text = data.strip() - if text: -- data = data.replace(text, unicode(gettext(text))) -+ data = data.replace(text, str(gettext(text))) - yield kind, data, pos - - elif kind is SUB: -@@ -830,7 +830,7 @@ class Translator(DirectiveFactory): - if kind is START and not skip: - tag, attrs = data - if tag in self.ignore_tags or \ -- isinstance(attrs.get(xml_lang), basestring): -+ isinstance(attrs.get(xml_lang), str): - skip += 1 - continue - -@@ -917,7 +917,7 @@ class Translator(DirectiveFactory): - - def _extract_attrs(self, event, gettext_functions, search_text): - for name, value in event[1][1]: -- if search_text and isinstance(value, basestring): -+ if search_text and isinstance(value, str): - if name in self.include_attrs: - text = value.strip() - if text: -@@ -1188,10 +1188,10 @@ def extract_from_code(code, gettext_functions): - strings = [] - def _add(arg): - if isinstance(arg, _ast_Str) \ -- and isinstance(_ast_Str_value(arg), unicode): -+ and isinstance(_ast_Str_value(arg), str): - strings.append(_ast_Str_value(arg)) - elif isinstance(arg, _ast_Str): -- strings.append(unicode(_ast_Str_value(arg), 'utf-8')) -+ strings.append(str(_ast_Str_value(arg), 'utf-8')) - elif arg: - strings.append(None) - [_add(arg) for arg in node.args] -@@ -1232,22 +1232,22 @@ def extract(fileobj, keywords, comment_tags, options): - :rtype: ``iterator`` - """ - template_class = options.get('template_class', MarkupTemplate) -- if isinstance(template_class, basestring): -+ if isinstance(template_class, str): - module, clsname = template_class.split(':', 1) - template_class = getattr(__import__(module, {}, {}, [clsname]), clsname) - encoding = options.get('encoding', None) - - extract_text = options.get('extract_text', True) -- if isinstance(extract_text, basestring): -+ if isinstance(extract_text, str): - extract_text = extract_text.lower() in ('1', 'on', 'yes', 'true') - - ignore_tags = options.get('ignore_tags', Translator.IGNORE_TAGS) -- if isinstance(ignore_tags, basestring): -+ if isinstance(ignore_tags, str): - ignore_tags = ignore_tags.split() - ignore_tags = [QName(tag) for tag in ignore_tags] - - include_attrs = options.get('include_attrs', Translator.INCLUDE_ATTRS) -- if isinstance(include_attrs, basestring): -+ if isinstance(include_attrs, str): - include_attrs = include_attrs.split() - include_attrs = [QName(attr) for attr in include_attrs] - ---- genshi/filters/tests/i18n.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/filters/tests/i18n.py -@@ -46,7 +46,7 @@ class DummyTranslations(NullTranslations): - if tmsg is missing: - if self._fallback: - return self._fallback.ugettext(message) -- return unicode(message) -+ return str(message) - return tmsg - else: - def gettext(self, message): -@@ -55,7 +55,7 @@ class DummyTranslations(NullTranslations): - if tmsg is missing: - if self._fallback: - return self._fallback.gettext(message) -- return unicode(message) -+ return str(message) - return tmsg - - if IS_PYTHON2: -@@ -94,10 +94,10 @@ class TranslatorTestCase(unittest.TestCase): - """ - Verify that translated attributes end up in a proper `Attrs` instance. - """ -- html = HTML(u""" -+ html = HTML(""" - - """) -- translator = Translator(lambda s: u"Voh") -+ translator = Translator(lambda s: "Voh") - stream = list(html.filter(translator)) - kind, data, pos = stream[2] - assert isinstance(data[1], Attrs) -@@ -139,7 +139,7 @@ class TranslatorTestCase(unittest.TestCase): - translator = Translator() - messages = list(translator.extract(tmpl.stream)) - self.assertEqual(1, len(messages)) -- self.assertEqual((2, 'gettext', u'Gr\xfc\xdfe', []), messages[0]) -+ self.assertEqual((2, 'gettext', 'Gr\xfc\xdfe', []), messages[0]) - - def test_extract_included_attribute_text(self): - tmpl = MarkupTemplate(""" -@@ -237,10 +237,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - Please see Help for details. -

- """) -- gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]." -+ gettext = lambda s: "Für Details siehe bitte [1:Hilfe]." - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Für Details siehe bitte Hilfe.

- """.encode('utf-8'), tmpl.generate().render(encoding='utf-8')) - -@@ -260,10 +260,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - xmlns:i18n="http://genshi.edgewall.org/i18n"> -

Please see Help

- """) -- gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]" -+ gettext = lambda s: "Für Details siehe bitte [1:Hilfe]" - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Für Details siehe bitte Hilfe

- """, tmpl.generate().render()) - -@@ -283,10 +283,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - xmlns:i18n="http://genshi.edgewall.org/i18n"> - Please see Help - """) -- gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]" -+ gettext = lambda s: "Für Details siehe bitte [1:Hilfe]" - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" - Für Details siehe bitte Hilfe - """.encode('utf-8'), tmpl.generate().render(encoding='utf-8')) - -@@ -317,11 +317,11 @@ class MsgDirectiveTestCase(unittest.TestCase): - """) - translator = Translator(lambda msgid: { - 'A helpful paragraph': 'Ein hilfreicher Absatz', -- 'Click for help': u'Klicken für Hilfe', -- 'Please see [1:Help]': u'Siehe bitte [1:Hilfe]' -+ 'Click for help': 'Klicken für Hilfe', -+ 'Please see [1:Help]': 'Siehe bitte [1:Hilfe]' - }[msgid]) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Siehe bitte Hilfe

- """, tmpl.generate().render(encoding=None)) - -@@ -352,11 +352,11 @@ class MsgDirectiveTestCase(unittest.TestCase): - """) - translator = Translator(lambda msgid: { - 'A helpful paragraph': 'Ein hilfreicher Absatz', -- 'Click for help': u'Klicken für Hilfe', -- 'Please see [1:Help]': u'Siehe bitte [1:Hilfe]' -+ 'Click for help': 'Klicken für Hilfe', -+ 'Please see [1:Help]': 'Siehe bitte [1:Hilfe]' - }[msgid]) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Siehe bitte Hilfe

- """, tmpl.generate(_=translator.translate).render(encoding=None)) - -@@ -384,11 +384,11 @@ class MsgDirectiveTestCase(unittest.TestCase): - - """) - translator = Translator(lambda msgid: { -- 'Click for help': u'Klicken für Hilfe', -- 'Please see [1:Help]': u'Siehe bitte [1:Hilfe]' -+ 'Click for help': 'Klicken für Hilfe', -+ 'Please see [1:Help]': 'Siehe bitte [1:Hilfe]' - }[msgid]) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" - Siehe bitte Hilfe - """, tmpl.generate().render(encoding=None)) - -@@ -413,10 +413,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - Please see Help page for details. -

- """) -- gettext = lambda s: u"Für Details siehe bitte [1:[2:Hilfeseite]]." -+ gettext = lambda s: "Für Details siehe bitte [1:[2:Hilfeseite]]." - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Für Details siehe bitte Hilfeseite.

- """, tmpl.generate().render()) - -@@ -468,10 +468,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - Show me entries per page. -

- """) -- gettext = lambda s: u"[1:] Einträge pro Seite anzeigen." -+ gettext = lambda s: "[1:] Einträge pro Seite anzeigen." - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Einträge pro Seite anzeigen.

- """, tmpl.generate().render()) - -@@ -495,10 +495,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - Please see Help for details. -

- """) -- gettext = lambda s: u"Für [2:Details] siehe bitte [1:Hilfe]." -+ gettext = lambda s: "Für [2:Details] siehe bitte [1:Hilfe]." - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Für Details siehe bitte Hilfe.

- """, tmpl.generate().render()) - -@@ -523,10 +523,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - Show me entries per page, starting at page . -

- """, encoding='utf-8') -- gettext = lambda s: u"[1:] Einträge pro Seite, beginnend auf Seite [2:]." -+ gettext = lambda s: "[1:] Einträge pro Seite, beginnend auf Seite [2:]." - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Eintr\u00E4ge pro Seite, beginnend auf Seite .

- """.encode('utf-8'), tmpl.generate().render(encoding='utf-8')) - -@@ -550,7 +550,7 @@ class MsgDirectiveTestCase(unittest.TestCase): - Hello, ${user.name}! -

- """) -- gettext = lambda s: u"Hallo, %(name)s!" -+ gettext = lambda s: "Hallo, %(name)s!" - translator = Translator(gettext) - translator.setup(tmpl) - self.assertEqual(""" -@@ -564,10 +564,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - Hello, ${user.name}! -

- """) -- gettext = lambda s: u"%(name)s, sei gegrüßt!" -+ gettext = lambda s: "%(name)s, sei gegrüßt!" - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Jim, sei gegrüßt!

- """, tmpl.generate(user=dict(name='Jim')).render()) - -@@ -578,10 +578,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - Hello, dude! -

- """) -- gettext = lambda s: u"Sei gegrüßt, [1:Alter]!" -+ gettext = lambda s: "Sei gegrüßt, [1:Alter]!" - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Sei gegrüßt, Alter!

- """, tmpl.generate(anchor='42').render()) - -@@ -605,7 +605,7 @@ class MsgDirectiveTestCase(unittest.TestCase): - Written by ${entry.author} at ${entry.time.strftime('%H:%M')} -

- """) -- gettext = lambda s: u"%(name)s schrieb dies um %(time)s" -+ gettext = lambda s: "%(name)s schrieb dies um %(time)s" - translator = Translator(gettext) - translator.setup(tmpl) - entry = { -@@ -636,10 +636,10 @@ class MsgDirectiveTestCase(unittest.TestCase): - Show me entries per page. -

- """) -- gettext = lambda s: u"[1:] Einträge pro Seite anzeigen." -+ gettext = lambda s: "[1:] Einträge pro Seite anzeigen." - translator = Translator(gettext) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Einträge pro Seite anzeigen.

- """, tmpl.generate().render()) - -@@ -668,7 +668,7 @@ class MsgDirectiveTestCase(unittest.TestCase): - xmlns:i18n="http://genshi.edgewall.org/i18n"> -

Foo

- """) -- gettext = lambda s: u"Voh" -+ gettext = lambda s: "Voh" - translator = Translator(gettext) - translator.setup(tmpl) - self.assertEqual(""" -@@ -691,14 +691,14 @@ class MsgDirectiveTestCase(unittest.TestCase): - xmlns:i18n="http://genshi.edgewall.org/i18n"> -

Foo

- """) -- gettext = lambda s: u"Voh" -+ gettext = lambda s: "Voh" - translator = Translator(DummyTranslations({ - 'Foo': 'Voh', -- 'Foo bar': u'Voh bär' -+ 'Foo bar': 'Voh bär' - })) - tmpl.filters.insert(0, translator) - tmpl.add_directives(Translator.NAMESPACE, translator) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Voh

- """, tmpl.generate().render()) - -@@ -738,11 +738,11 @@ class MsgDirectiveTestCase(unittest.TestCase): - - """) - translations = DummyTranslations({ -- 'Changed %(date)s ago by %(author)s': u'Modificado à %(date)s por %(author)s' -+ 'Changed %(date)s ago by %(author)s': 'Modificado à %(date)s por %(author)s' - }) - translator = Translator(translations) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" - Modificado à um dia por Pedro - """.encode('utf-8'), tmpl.generate(date='um dia', author="Pedro").render(encoding='utf-8')) - -@@ -757,7 +757,7 @@ class MsgDirectiveTestCase(unittest.TestCase): - messages = list(translator.extract(tmpl.stream)) - self.assertEqual(1, len(messages)) - self.assertEqual( -- (3, None, u'[1:[2:Translation\\[\xa00\xa0\\]]: [3:One coin]]', []), messages[0] -+ (3, None, '[1:[2:Translation\\[\xa00\xa0\\]]: [3:One coin]]', []), messages[0] - ) - - def test_i18n_msg_ticket_251_translate(self): -@@ -766,12 +766,12 @@ class MsgDirectiveTestCase(unittest.TestCase): -

Translation[ 0 ]: One coin

- """) - translations = DummyTranslations({ -- u'[1:[2:Translation\\[\xa00\xa0\\]]: [3:One coin]]': -- u'[1:[2:Trandução\\[\xa00\xa0\\]]: [3:Uma moeda]]' -+ '[1:[2:Translation\\[\xa00\xa0\\]]: [3:One coin]]': -+ '[1:[2:Trandução\\[\xa00\xa0\\]]: [3:Uma moeda]]' - }) - translator = Translator(translations) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Trandução[ 0 ]: Uma moeda

- """.encode('utf-8'), tmpl.generate().render(encoding='utf-8')) - -@@ -820,12 +820,12 @@ class MsgDirectiveTestCase(unittest.TestCase): - 'before. For questions about installation\n and ' - 'configuration of Trac, please try the\n ' - '[3:mailing list]\n instead of filing a ticket.': -- u'Antes de o fazer, porém,\n ' -- u'[1:por favor tente [2:procurar]\n por problemas semelhantes], uma vez que ' -- u'é muito provável que este problema\n já tenha sido reportado ' -- u'anteriormente. Para questões relativas à instalação\n e ' -- u'configuração do Trac, por favor tente a\n ' -- u'[3:mailing list]\n em vez de criar um assunto.' -+ 'Antes de o fazer, porém,\n ' -+ '[1:por favor tente [2:procurar]\n por problemas semelhantes], uma vez que ' -+ 'é muito provável que este problema\n já tenha sido reportado ' -+ 'anteriormente. Para questões relativas à instalação\n e ' -+ 'configuração do Trac, por favor tente a\n ' -+ '[3:mailing list]\n em vez de criar um assunto.' - }) - translator = Translator(translations) - translator.setup(tmpl) -@@ -833,7 +833,7 @@ class MsgDirectiveTestCase(unittest.TestCase): - self.assertEqual(1, len(messages)) - ctx = Context() - ctx.push({'trac': {'homepage': 'http://trac.edgewall.org/'}}) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Antes de o fazer, porém, - por favor tente procurar - por problemas semelhantes, uma vez que é muito provável que este problema -@@ -856,8 +856,8 @@ class MsgDirectiveTestCase(unittest.TestCase): - translations = DummyTranslations({ - '[1:Note:] This repository is defined in\n ' - '[2:[3:trac.ini]]\n and cannot be edited on this page.': -- u'[1:Nota:] Este repositório está definido em \n ' -- u'[2:[3:trac.ini]]\n e não pode ser editado nesta página.', -+ '[1:Nota:] Este repositório está definido em \n ' -+ '[2:[3:trac.ini]]\n e não pode ser editado nesta página.', - }) - translator = Translator(translations) - translator.setup(tmpl) -@@ -868,7 +868,7 @@ class MsgDirectiveTestCase(unittest.TestCase): - '[2:[3:trac.ini]]\n and cannot be edited on this page.', - messages[0][2] - ) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Nota: Este repositório está definido em - trac.ini - e não pode ser editado nesta página.

-@@ -933,7 +933,7 @@ class MsgDirectiveTestCase(unittest.TestCase): - xmlns:i18n="http://genshi.edgewall.org/i18n"> -

text $name

- """) -- gettext = lambda s: u'head [1:%(name)s] tail' -+ gettext = lambda s: 'head [1:%(name)s] tail' - translator = Translator(gettext) - translator.setup(tmpl) - self.assertEqual(""" -@@ -1342,12 +1342,12 @@ class ChooseDirectiveTestCase(unittest.TestCase): - }) - translator = Translator(translations) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

- Da ist 1 Sache. -

- """, tmpl.generate(link="/things", num=1).render(encoding=None)) -- self.assertEqual(u""" -+ self.assertEqual(""" -

- Da sind 3 Sachen. -

-@@ -1399,10 +1399,10 @@ class ChooseDirectiveTestCase(unittest.TestCase): - }) - translator = Translator(translations) - translator.setup(tmpl) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Da ist 1 Sache.

- """, tmpl.generate(link="/things", num=1).render(encoding=None)) -- self.assertEqual(u""" -+ self.assertEqual(""" -

Da sind 3 Sachen.

- """, tmpl.generate(link="/things", num=3).render(encoding=None)) - ---- genshi/filters/tests/test_html.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/filters/tests/test_html.py -@@ -21,115 +21,115 @@ from genshi.template import MarkupTemplate - class HTMLFormFillerTestCase(unittest.TestCase): - - def test_fill_input_text_no_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller() -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_input_text_single_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller(data={'foo': 'bar'}) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_input_text_multi_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller(data={'foo': ['bar']}) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_input_hidden_no_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller() -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_input_hidden_single_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller(data={'foo': 'bar'}) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_input_hidden_multi_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller(data={'foo': ['bar']}) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_textarea_no_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller() -- self.assertEquals("""

-+ self.assertEqual("""

- -

""") | HTMLFormFiller(data={'foo': 'bar'}) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_textarea_multi_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller(data={'foo': ['bar']}) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_textarea_multiple(self): - # Ensure that the subsequent textarea doesn't get the data from the - # first -- html = HTML(u"""

-+ html = HTML("""

- - -

""") | HTMLFormFiller(data={'foo': 'Some text'}) -- self.assertEquals("""

-+ self.assertEqual("""

- - - -

""") | HTMLFormFiller(data={'foo': 'Some text'}) -- self.assertEquals("""

-+ self.assertEqual("""

- - -

""", html.render()) - - def test_fill_input_checkbox_single_value_auto_no_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller() -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_input_checkbox_single_value_auto(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': ''})).render()) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': 'on'})).render()) - -@@ -137,10 +137,10 @@ class HTMLFormFillerTestCase(unittest.TestCase): - html = HTML("""

- -

""", encoding='ascii') -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': '1'})).render()) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': '2'})).render()) - -@@ -148,79 +148,79 @@ class HTMLFormFillerTestCase(unittest.TestCase): - html = HTML("""

- -

""", encoding='ascii') -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': []})).render()) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': ['on']})).render()) - - def test_fill_input_checkbox_multi_value_defined(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': ['1']})).render()) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': ['2']})).render()) - - def test_fill_input_radio_no_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller() -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_input_radio_single_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': '1'})).render()) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': '2'})).render()) - - def test_fill_input_radio_multi_value(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': ['1']})).render()) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': ['2']})).render()) - - def test_fill_input_radio_empty_string(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': ''})).render()) - - def test_fill_input_radio_multi_empty_string(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", (html | HTMLFormFiller(data={'foo': ['']})).render()) - - def test_fill_select_no_value_auto(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller() -- self.assertEquals("""

-+ self.assertEqual("""

- - - - - -

""") | HTMLFormFiller() -- self.assertEquals("""

-+ self.assertEqual("""

- - - - - -

""") | HTMLFormFiller(data={'foo': '1'}) -- self.assertEquals("""

-+ self.assertEqual("""

- - - - - -

""") | HTMLFormFiller(data={'foo': '1'}) -- self.assertEquals("""

-+ self.assertEqual("""

- - - - - -

""") | HTMLFormFiller(data={'foo': ['1', '3']}) -- self.assertEquals("""

-+ self.assertEqual("""

- - - - - -

""") | HTMLFormFiller(data={'foo': ['1', '3']}) -- self.assertEquals("""

-+ self.assertEqual("""

- - - -

""").generate(x=1) | HTMLFormFiller(data={'foo': '1'}) -- self.assertEquals(u"""
-+ self.assertEqual(""" - -@@ -326,37 +326,37 @@ class HTMLFormFillerTestCase(unittest.TestCase): - - -
""").generate(x=1) | HTMLFormFiller(data={'foo': 'foo 1 bar'}) -- self.assertEquals("""
-+ self.assertEqual(""" - -
""", html.render()) - - def test_fill_option_unicode_value(self): -- html = HTML(u"""
-+ html = HTML(""" - --
""") | HTMLFormFiller(data={'foo': u'ö'}) -- self.assertEquals(u"""
-+
""") | HTMLFormFiller(data={'foo': 'ö'}) -+ self.assertEqual("""
- -
""", html.render(encoding=None)) - - def test_fill_input_password_disabled(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller(data={'pass': 'bar'}) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - - def test_fill_input_password_enabled(self): -- html = HTML(u"""

-+ html = HTML("""

- -

""") | HTMLFormFiller(data={'pass': '1234'}, passwords=True) -- self.assertEquals("""

-+ self.assertEqual("""

- -

""", html.render()) - -@@ -377,237 +377,237 @@ class HTMLSanitizerTestCase(unittest.TestCase): - sanitized_html = (html | HTMLSanitizer()).render() - if not sanitized_html and allow_strip: - return -- self.assertEquals(expected, sanitized_html) -+ self.assertEqual(expected, sanitized_html) - - def test_sanitize_unchanged(self): -- html = HTML(u'fo
o
') -- self.assertEquals('fo
o
', -+ html = HTML('fo
o
') -+ self.assertEqual('fo
o
', - (html | HTMLSanitizer()).render()) -- html = HTML(u'foo') -- self.assertEquals('foo', -+ html = HTML('foo') -+ self.assertEqual('foo', - (html | HTMLSanitizer()).render()) - - def test_sanitize_escape_text(self): -- html = HTML(u'fo&') -- self.assertEquals('fo&', -+ html = HTML('fo&') -+ self.assertEqual('fo&', - (html | HTMLSanitizer()).render()) -- html = HTML(u'<foo>') -- self.assertEquals('<foo>', -+ html = HTML('<foo>') -+ self.assertEqual('<foo>', - (html | HTMLSanitizer()).render()) - - def test_sanitize_entityref_text(self): -- html = HTML(u'foö') -- self.assertEquals(u'foö', -+ html = HTML('foö') -+ self.assertEqual('foö', - (html | HTMLSanitizer()).render(encoding=None)) - - def test_sanitize_escape_attr(self): -- html = HTML(u'
') -- self.assertEquals('
', -+ html = HTML('
') -+ self.assertEqual('
', - (html | HTMLSanitizer()).render()) - - def test_sanitize_close_empty_tag(self): -- html = HTML(u'fo
o
') -- self.assertEquals('fo
o
', -+ html = HTML('fo
o
') -+ self.assertEqual('fo
o
', - (html | HTMLSanitizer()).render()) - - def test_sanitize_invalid_entity(self): -- html = HTML(u'&junk;') -- self.assertEquals('&junk;', (html | HTMLSanitizer()).render()) -+ html = HTML('&junk;') -+ self.assertEqual('&junk;', (html | HTMLSanitizer()).render()) - - def test_sanitize_remove_script_elem(self): -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -- src = u'alert("foo")' -+ html = HTML('') -+ self.assertEqual('', (html | HTMLSanitizer()).render()) -+ html = HTML('') -+ self.assertEqual('', (html | HTMLSanitizer()).render()) -+ src = 'alert("foo")' - self.assert_parse_error_or_equal('<SCR\x00IPT>alert("foo")', src, - allow_strip=True) -- src = u'' -+ src = '' - self.assert_parse_error_or_equal('<SCRIPT&XYZ; ' - 'SRC="http://example.com/">', src, - allow_strip=True) - - def test_sanitize_remove_onclick_attr(self): -- html = HTML(u'
') -- self.assertEquals('
', (html | HTMLSanitizer()).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | HTMLSanitizer()).render()) - - def test_sanitize_remove_input_password(self): -- html = HTML(u'
') -- self.assertEquals('
', (html | HTMLSanitizer()).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | HTMLSanitizer()).render()) - - def test_sanitize_remove_comments(self): -- html = HTML(u'''
''') -- self.assertEquals('
', (html | HTMLSanitizer()).render()) -+ html = HTML('''
''') -+ self.assertEqual('
', (html | HTMLSanitizer()).render()) - - def test_sanitize_remove_style_scripts(self): - sanitizer = StyleSanitizer() - # Inline style with url() using javascript: scheme -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) - # Inline style with url() using javascript: scheme, using control char -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) - # Inline style with url() using javascript: scheme, in quotes -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) - # IE expressions in CSS not allowed -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -- html = HTML(u'
') -+ self.assertEqual('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) -+ html = HTML('
') -- self.assertEquals('
', -+ self.assertEqual('
', - (html | sanitizer).render()) - # Inline style with url() using javascript: scheme, using unicode - # escapes -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) - - def test_sanitize_remove_style_phishing(self): - sanitizer = StyleSanitizer() - # The position property is not allowed -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) - # Normal margins get passed through -- html = HTML(u'
') -- self.assertEquals('
', -+ html = HTML('
') -+ self.assertEqual('
', - (html | sanitizer).render()) - # But not negative margins -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -- html = HTML(u'
') -- self.assertEquals('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) -+ html = HTML('
') -+ self.assertEqual('
', (html | sanitizer).render()) - - def test_sanitize_remove_src_javascript(self): -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -+ html = HTML('') -+ self.assertEqual('', (html | HTMLSanitizer()).render()) - # Case-insensitive protocol matching -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -+ html = HTML('') -+ self.assertEqual('', (html | HTMLSanitizer()).render()) - # Grave accents (not parsed) -- src = u'' -+ src = '' - self.assert_parse_error_or_equal('', src) - # Protocol encoded using UTF-8 numeric entities -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -+ self.assertEqual('', (html | HTMLSanitizer()).render()) - # Protocol encoded using UTF-8 numeric entities without a semicolon - # (which is allowed because the max number of digits is used) -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -+ self.assertEqual('', (html | HTMLSanitizer()).render()) - # Protocol encoded using UTF-8 numeric hex entities without a semicolon - # (which is allowed because the max number of digits is used) -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -+ self.assertEqual('', (html | HTMLSanitizer()).render()) - # Embedded tab character in protocol -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -+ html = HTML('') -+ self.assertEqual('', (html | HTMLSanitizer()).render()) - # Embedded tab character in protocol, but encoded this time -- html = HTML(u'') -- self.assertEquals('', (html | HTMLSanitizer()).render()) -+ html = HTML('') -+ self.assertEqual('', (html | HTMLSanitizer()).render()) - - def test_sanitize_expression(self): -- html = HTML(ur'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML(r'
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_capital_expression(self): -- html = HTML(ur'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML(r'
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_sanitize_url_with_javascript(self): -- html = HTML(u'
' -- u'XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
' -+ 'XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_sanitize_capital_url_with_javascript(self): -- html = HTML(u'
' -- u'XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
' -+ 'XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_sanitize_unicode_escapes(self): -- html = HTML(ur'
' -- ur'XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML(r'
' -+ r'XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_sanitize_backslash_without_hex(self): -- html = HTML(ur'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -- html = HTML(ur'
XSS
') -+ html = HTML(r'
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) -+ html = HTML(r'
XSS
') - self.assertEqual(r'
' - 'XSS
', -- unicode(html | StyleSanitizer())) -+ str(html | StyleSanitizer())) - - def test_sanitize_unsafe_props(self): -- html = HTML(u'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - -- html = HTML(u'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - -- html = HTML(u'
' -- u'XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
' -+ 'XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - -- html = HTML(u"""
XSS
""") -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML("""
XSS
""") -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - -- html = HTML(u"""
XSS
""") -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML("""
XSS
""") -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_sanitize_negative_margin(self): -- html = HTML(u'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -- html = HTML(u'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) -+ html = HTML('
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_sanitize_css_hack(self): -- html = HTML(u'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - -- html = HTML(u'
XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_sanitize_property_name(self): -- html = HTML(u'
prop
') -+ html = HTML('
prop
') - self.assertEqual('
prop
', -- unicode(html | StyleSanitizer())) -+ str(html | StyleSanitizer())) - - def test_sanitize_unicode_expression(self): - # Fullwidth small letters -- html = HTML(u'
' -- u'XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
' -+ 'XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - # Fullwidth capital letters -- html = HTML(u'
' -- u'XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
' -+ 'XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - # IPA extensions -- html = HTML(u'
' -- u'XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
' -+ 'XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - def test_sanitize_unicode_url(self): - # IPA extensions -- html = HTML(u'
' -- u'XSS
') -- self.assertEqual('
XSS
', unicode(html | StyleSanitizer())) -+ html = HTML('
' -+ 'XSS
') -+ self.assertEqual('
XSS
', str(html | StyleSanitizer())) - - - def suite(): ---- genshi/filters/tests/transform.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/filters/tests/transform.py -@@ -33,24 +33,24 @@ def _simplify(stream, with_attrs=False): - for mark, (kind, data, pos) in stream: - if kind is START: - if with_attrs: -- data = (unicode(data[0]), dict((unicode(k), v) -+ data = (str(data[0]), dict((str(k), v) - for k, v in data[1])) - else: -- data = unicode(data[0]) -+ data = str(data[0]) - elif kind is END: -- data = unicode(data) -+ data = str(data) - elif kind is ATTR: - kind = ATTR -- data = dict((unicode(k), v) for k, v in data[1]) -+ data = dict((str(k), v) for k, v in data[1]) - yield mark, kind, data - return list(_generate()) - - - def _transform(html, transformer, with_attrs=False): - """Apply transformation returning simplified marked stream.""" -- if isinstance(html, basestring) and not isinstance(html, unicode): -+ if isinstance(html, str) and not isinstance(html, str): - html = HTML(html, encoding='utf-8') -- elif isinstance(html, unicode): -+ elif isinstance(html, str): - html = HTML(html, encoding='utf-8') - stream = transformer(html, keep_marks=True) - return _simplify(stream, with_attrs) -@@ -60,7 +60,7 @@ class SelectTest(unittest.TestCase): - """Test .select()""" - def _select(self, select): - html = HTML(FOOBAR, encoding='utf-8') -- if isinstance(select, basestring): -+ if isinstance(select, str): - select = [select] - transformer = Transformer(select[0]) - for sel in select[1:]: -@@ -70,78 +70,78 @@ class SelectTest(unittest.TestCase): - def test_select_single_element(self): - self.assertEqual( - self._select('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')], -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')], - ) - - def test_select_context(self): - self.assertEqual( - self._select('.'), -- [(ENTER, START, u'root'), -- (INSIDE, TEXT, u'ROOT'), -- (INSIDE, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, END, u'foo'), -- (INSIDE, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (INSIDE, END, u'bar'), -- (EXIT, END, u'root')] -+ [(ENTER, START, 'root'), -+ (INSIDE, TEXT, 'ROOT'), -+ (INSIDE, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, END, 'foo'), -+ (INSIDE, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (INSIDE, END, 'bar'), -+ (EXIT, END, 'root')] - ) - - def test_select_inside_select(self): - self.assertEqual( - self._select(['.', 'foo']), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')], -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')], - ) - - def test_select_text(self): - self.assertEqual( - self._select('*/text()'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (OUTSIDE, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (OUTSIDE, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')], -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (OUTSIDE, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (OUTSIDE, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')], - ) - - def test_select_attr(self): - self.assertEqual( - self._select('foo/@name'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ATTR, ATTR, {'name': u'foo'}), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ATTR, ATTR, {'name': 'foo'}), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_select_text_context(self): - self.assertEqual( -- list(Transformer('.')(HTML(u'foo'), keep_marks=True)), -- [('OUTSIDE', ('TEXT', u'foo', (None, 1, 0)))], -+ list(Transformer('.')(HTML('foo'), keep_marks=True)), -+ [('OUTSIDE', ('TEXT', 'foo', (None, 1, 0)))], - ) - - -@@ -152,63 +152,63 @@ class InvertTest(unittest.TestCase): - def test_invert_element(self): - self.assertEqual( - self._invert('foo'), -- [(OUTSIDE, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (OUTSIDE, END, u'root')] -+ [(OUTSIDE, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (OUTSIDE, END, 'root')] - ) - - def test_invert_inverted_element(self): - self.assertEqual( - _transform(FOO, Transformer('foo').invert().invert()), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (OUTSIDE, START, u'foo'), -- (OUTSIDE, TEXT, u'FOO'), -- (OUTSIDE, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (OUTSIDE, START, 'foo'), -+ (OUTSIDE, TEXT, 'FOO'), -+ (OUTSIDE, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_invert_text(self): - self.assertEqual( - self._invert('foo/text()'), -- [(OUTSIDE, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (OUTSIDE, START, u'foo'), -- (None, TEXT, u'FOO'), -- (OUTSIDE, END, u'foo'), -- (OUTSIDE, END, u'root')] -+ [(OUTSIDE, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (OUTSIDE, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (OUTSIDE, END, 'foo'), -+ (OUTSIDE, END, 'root')] - ) - - def test_invert_attribute(self): - self.assertEqual( - self._invert('foo/@name'), -- [(OUTSIDE, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (None, ATTR, {'name': u'foo'}), -- (OUTSIDE, START, u'foo'), -- (OUTSIDE, TEXT, u'FOO'), -- (OUTSIDE, END, u'foo'), -- (OUTSIDE, END, u'root')] -+ [(OUTSIDE, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (None, ATTR, {'name': 'foo'}), -+ (OUTSIDE, START, 'foo'), -+ (OUTSIDE, TEXT, 'FOO'), -+ (OUTSIDE, END, 'foo'), -+ (OUTSIDE, END, 'root')] - ) - - def test_invert_context(self): - self.assertEqual( - self._invert('.'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_invert_text_context(self): - self.assertEqual( -- _simplify(Transformer('.').invert()(HTML(u'foo'), keep_marks=True)), -- [(None, 'TEXT', u'foo')], -+ _simplify(Transformer('.').invert()(HTML('foo'), keep_marks=True)), -+ [(None, 'TEXT', 'foo')], - ) - - -@@ -218,12 +218,12 @@ class EndTest(unittest.TestCase): - stream = _transform(FOO, Transformer('foo').end()) - self.assertEqual( - stream, -- [(OUTSIDE, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (OUTSIDE, START, u'foo'), -- (OUTSIDE, TEXT, u'FOO'), -- (OUTSIDE, END, u'foo'), -- (OUTSIDE, END, u'root')] -+ [(OUTSIDE, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (OUTSIDE, START, 'foo'), -+ (OUTSIDE, TEXT, 'FOO'), -+ (OUTSIDE, END, 'foo'), -+ (OUTSIDE, END, 'root')] - ) - - -@@ -234,47 +234,47 @@ class EmptyTest(unittest.TestCase): - def test_empty_element(self): - self.assertEqual( - self._empty('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (EXIT, END, u'foo'), -- (None, END, u'root')], -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (EXIT, END, 'foo'), -+ (None, END, 'root')], - ) - - def test_empty_text(self): - self.assertEqual( - self._empty('foo/text()'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (OUTSIDE, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (OUTSIDE, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_empty_attr(self): - self.assertEqual( - self._empty('foo/@name'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ATTR, ATTR, {'name': u'foo'}), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ATTR, ATTR, {'name': 'foo'}), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_empty_context(self): - self.assertEqual( - self._empty('.'), -- [(ENTER, START, u'root'), -- (EXIT, END, u'root')] -+ [(ENTER, START, 'root'), -+ (EXIT, END, 'root')] - ) - - def test_empty_text_context(self): - self.assertEqual( -- _simplify(Transformer('.')(HTML(u'foo'), keep_marks=True)), -- [(OUTSIDE, TEXT, u'foo')], -+ _simplify(Transformer('.')(HTML('foo'), keep_marks=True)), -+ [(OUTSIDE, TEXT, 'foo')], - ) - - -@@ -285,29 +285,29 @@ class RemoveTest(unittest.TestCase): - def test_remove_element(self): - self.assertEqual( - self._remove('foo|bar'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, END, 'root')] - ) - - def test_remove_text(self): - self.assertEqual( - self._remove('//text()'), -- [(None, START, u'root'), -- (None, START, u'foo'), -- (None, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, START, 'foo'), -+ (None, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_remove_attr(self): - self.assertEqual( - self._remove('foo/@name'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_remove_context(self): -@@ -330,52 +330,52 @@ class UnwrapText(unittest.TestCase): - def test_unwrap_element(self): - self.assertEqual( - self._unwrap('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (INSIDE, TEXT, u'FOO'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (INSIDE, TEXT, 'FOO'), -+ (None, END, 'root')] - ) - - def test_unwrap_text(self): - self.assertEqual( - self._unwrap('foo/text()'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (OUTSIDE, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (OUTSIDE, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_unwrap_attr(self): - self.assertEqual( - self._unwrap('foo/@name'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ATTR, ATTR, {'name': u'foo'}), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ATTR, ATTR, {'name': 'foo'}), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_unwrap_adjacent(self): - self.assertEqual( - _transform(FOOBAR, Transformer('foo|bar').unwrap()), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, TEXT, u'BAR'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, TEXT, 'BAR'), -+ (None, END, 'root')] - ) - - def test_unwrap_root(self): - self.assertEqual( - self._unwrap('.'), -- [(INSIDE, TEXT, u'ROOT'), -- (INSIDE, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, END, u'foo')] -+ [(INSIDE, TEXT, 'ROOT'), -+ (INSIDE, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, END, 'foo')] - ) - - def test_unwrap_text_root(self): -@@ -392,75 +392,75 @@ class WrapTest(unittest.TestCase): - def test_wrap_element(self): - self.assertEqual( - self._wrap('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'wrap'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, END, u'wrap'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'wrap'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, END, 'wrap'), -+ (None, END, 'root')] - ) - - def test_wrap_adjacent_elements(self): - self.assertEqual( - _transform(FOOBAR, Transformer('foo|bar').wrap('wrap')), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'wrap'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, END, u'wrap'), -- (None, START, u'wrap'), -- (ENTER, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'bar'), -- (None, END, u'wrap'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'wrap'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, END, 'wrap'), -+ (None, START, 'wrap'), -+ (ENTER, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'bar'), -+ (None, END, 'wrap'), -+ (None, END, 'root')] - ) - - def test_wrap_text(self): - self.assertEqual( - self._wrap('foo/text()'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, START, u'wrap'), -- (OUTSIDE, TEXT, u'FOO'), -- (None, END, u'wrap'), -- (None, END, u'foo'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, START, 'wrap'), -+ (OUTSIDE, TEXT, 'FOO'), -+ (None, END, 'wrap'), -+ (None, END, 'foo'), -+ (None, END, 'root')] - ) - - def test_wrap_root(self): - self.assertEqual( - self._wrap('.'), -- [(None, START, u'wrap'), -- (ENTER, START, u'root'), -- (INSIDE, TEXT, u'ROOT'), -- (INSIDE, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, END, u'foo'), -- (EXIT, END, u'root'), -- (None, END, u'wrap')] -+ [(None, START, 'wrap'), -+ (ENTER, START, 'root'), -+ (INSIDE, TEXT, 'ROOT'), -+ (INSIDE, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, END, 'foo'), -+ (EXIT, END, 'root'), -+ (None, END, 'wrap')] - ) - - def test_wrap_text_root(self): - self.assertEqual( - _transform('foo', Transformer('.').wrap('wrap')), -- [(None, START, u'wrap'), -- (OUTSIDE, TEXT, u'foo'), -- (None, END, u'wrap')], -+ [(None, START, 'wrap'), -+ (OUTSIDE, TEXT, 'foo'), -+ (None, END, 'wrap')], - ) - - def test_wrap_with_element(self): - element = Element('a', href='http://localhost') - self.assertEqual( - _transform('foo', Transformer('.').wrap(element), with_attrs=True), -- [(None, START, (u'a', {u'href': u'http://localhost'})), -- (OUTSIDE, TEXT, u'foo'), -- (None, END, u'a')] -+ [(None, START, ('a', {'href': 'http://localhost'})), -+ (OUTSIDE, TEXT, 'foo'), -+ (None, END, 'a')] - ) - - -@@ -483,55 +483,55 @@ class FilterTest(unittest.TestCase): - def test_filter_element(self): - self.assertEqual( - self._filter('foo'), -- [[(None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo')]] -+ [[(None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo')]] - ) - - def test_filter_adjacent_elements(self): - self.assertEqual( - self._filter('foo|bar'), -- [[(None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo')], -- [(None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar')]] -+ [[(None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo')], -+ [(None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar')]] - ) - - def test_filter_text(self): - self.assertEqual( - self._filter('*/text()'), -- [[(None, TEXT, u'FOO')], -- [(None, TEXT, u'BAR')]] -+ [[(None, TEXT, 'FOO')], -+ [(None, TEXT, 'BAR')]] - ) - def test_filter_root(self): - self.assertEqual( - self._filter('.'), -- [[(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')]] -+ [[(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')]] - ) - - def test_filter_text_root(self): - self.assertEqual( - self._filter('.', 'foo'), -- [[(None, TEXT, u'foo')]]) -+ [[(None, TEXT, 'foo')]]) - - def test_filter_after_outside(self): - stream = _transform( - 'x', Transformer('//root/text()').filter(lambda x: x)) - self.assertEqual( - list(stream), -- [(None, START, u'root'), -- (OUTSIDE, TEXT, u'x'), -- (None, END, u'root')]) -+ [(None, START, 'root'), -+ (OUTSIDE, TEXT, 'x'), -+ (None, END, 'root')]) - - - class MapTest(unittest.TestCase): -@@ -546,16 +546,16 @@ class MapTest(unittest.TestCase): - def test_map_element(self): - self.assertEqual( - self._map('foo'), -- [(QName('foo'), Attrs([(QName('name'), u'foo'), -- (QName('size'), u'100')])), -- u'FOO', -+ [(QName('foo'), Attrs([(QName('name'), 'foo'), -+ (QName('size'), '100')])), -+ 'FOO', - QName('foo')] - ) - - def test_map_with_text_kind(self): - self.assertEqual( - self._map('.', TEXT), -- [u'ROOT', u'FOO', u'BAR'] -+ ['ROOT', 'FOO', 'BAR'] - ) - - def test_map_with_root_and_end_kind(self): -@@ -567,7 +567,7 @@ class MapTest(unittest.TestCase): - def test_map_with_attribute(self): - self.assertEqual( - self._map('foo/@name'), -- [(QName('foo@*'), Attrs([('name', u'foo')]))] -+ [(QName('foo@*'), Attrs([('name', 'foo')]))] - ) - - -@@ -578,29 +578,29 @@ class SubstituteTest(unittest.TestCase): - def test_substitute_foo(self): - self.assertEqual( - self._substitute('foo', 'FOO|BAR', 'FOOOOO'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOOOOO'), -- (EXIT, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOOOOO'), -+ (EXIT, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_substitute_foobar_with_group(self): - self.assertEqual( - self._substitute('foo|bar', '(FOO|BAR)', r'(\1)'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'(FOO)'), -- (EXIT, END, u'foo'), -- (ENTER, START, u'bar'), -- (INSIDE, TEXT, u'(BAR)'), -- (EXIT, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, '(FOO)'), -+ (EXIT, END, 'foo'), -+ (ENTER, START, 'bar'), -+ (INSIDE, TEXT, '(BAR)'), -+ (EXIT, END, 'bar'), -+ (None, END, 'root')] - ) - - -@@ -611,43 +611,43 @@ class RenameTest(unittest.TestCase): - def test_rename_root(self): - self.assertEqual( - self._rename('.'), -- [(ENTER, START, u'foobar'), -- (INSIDE, TEXT, u'ROOT'), -- (INSIDE, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, END, u'foo'), -- (INSIDE, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (INSIDE, END, u'bar'), -- (EXIT, END, u'foobar')] -+ [(ENTER, START, 'foobar'), -+ (INSIDE, TEXT, 'ROOT'), -+ (INSIDE, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, END, 'foo'), -+ (INSIDE, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (INSIDE, END, 'bar'), -+ (EXIT, END, 'foobar')] - ) - - def test_rename_element(self): - self.assertEqual( - self._rename('foo|bar'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foobar'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foobar'), -- (ENTER, START, u'foobar'), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'foobar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foobar'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foobar'), -+ (ENTER, START, 'foobar'), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'foobar'), -+ (None, END, 'root')] - ) - - def test_rename_text(self): - self.assertEqual( - self._rename('foo/text()'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (OUTSIDE, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (OUTSIDE, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - -@@ -658,15 +658,15 @@ class ContentTestMixin(object): - - def __iter__(self): - self.count += 1 -- return iter(HTML(u'CONTENT %i' % self.count)) -+ return iter(HTML('CONTENT %i' % self.count)) - -- if isinstance(html, basestring) and not isinstance(html, unicode): -+ if isinstance(html, str) and not isinstance(html, str): - html = HTML(html, encoding='utf-8') - else: - html = HTML(html) - if content is None: - content = Injector() -- elif isinstance(content, basestring): -+ elif isinstance(content, str): - content = HTML(content) - return _transform(html, getattr(Transformer(select), self.operation) - (content)) -@@ -678,59 +678,59 @@ class ReplaceTest(unittest.TestCase, ContentTestMixin) - def test_replace_element(self): - self.assertEqual( - self._apply('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, TEXT, u'CONTENT 1'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, TEXT, 'CONTENT 1'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_replace_text(self): - self.assertEqual( - self._apply('text()'), -- [(None, START, u'root'), -- (None, TEXT, u'CONTENT 1'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'CONTENT 1'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_replace_context(self): - self.assertEqual( - self._apply('.'), -- [(None, TEXT, u'CONTENT 1')], -+ [(None, TEXT, 'CONTENT 1')], - ) - - def test_replace_text_context(self): - self.assertEqual( - self._apply('.', html='foo'), -- [(None, TEXT, u'CONTENT 1')], -+ [(None, TEXT, 'CONTENT 1')], - ) - - def test_replace_adjacent_elements(self): - self.assertEqual( - self._apply('*'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, TEXT, u'CONTENT 1'), -- (None, TEXT, u'CONTENT 2'), -- (None, END, u'root')], -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, TEXT, 'CONTENT 1'), -+ (None, TEXT, 'CONTENT 2'), -+ (None, END, 'root')], - ) - - def test_replace_all(self): - self.assertEqual( - self._apply('*|text()'), -- [(None, START, u'root'), -- (None, TEXT, u'CONTENT 1'), -- (None, TEXT, u'CONTENT 2'), -- (None, TEXT, u'CONTENT 3'), -- (None, END, u'root')], -+ [(None, START, 'root'), -+ (None, TEXT, 'CONTENT 1'), -+ (None, TEXT, 'CONTENT 2'), -+ (None, TEXT, 'CONTENT 3'), -+ (None, END, 'root')], - ) - - def test_replace_with_callback(self): -@@ -740,11 +740,11 @@ class ReplaceTest(unittest.TestCase, ContentTestMixin) - yield '%2i.' % count[0] - self.assertEqual( - self._apply('*', content), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, TEXT, u' 1.'), -- (None, TEXT, u' 2.'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, TEXT, ' 1.'), -+ (None, TEXT, ' 2.'), -+ (None, END, 'root')] - ) - - -@@ -754,87 +754,87 @@ class BeforeTest(unittest.TestCase, ContentTestMixin): - def test_before_element(self): - self.assertEqual( - self._apply('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, TEXT, u'CONTENT 1'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, TEXT, 'CONTENT 1'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_before_text(self): - self.assertEqual( - self._apply('text()'), -- [(None, START, u'root'), -- (None, TEXT, u'CONTENT 1'), -- (OUTSIDE, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'CONTENT 1'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_before_context(self): - self.assertEqual( - self._apply('.'), -- [(None, TEXT, u'CONTENT 1'), -- (ENTER, START, u'root'), -- (INSIDE, TEXT, u'ROOT'), -- (INSIDE, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, END, u'foo'), -- (INSIDE, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (INSIDE, END, u'bar'), -- (EXIT, END, u'root')] -+ [(None, TEXT, 'CONTENT 1'), -+ (ENTER, START, 'root'), -+ (INSIDE, TEXT, 'ROOT'), -+ (INSIDE, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, END, 'foo'), -+ (INSIDE, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (INSIDE, END, 'bar'), -+ (EXIT, END, 'root')] - ) - - def test_before_text_context(self): - self.assertEqual( - self._apply('.', html='foo'), -- [(None, TEXT, u'CONTENT 1'), -- (OUTSIDE, TEXT, u'foo')] -+ [(None, TEXT, 'CONTENT 1'), -+ (OUTSIDE, TEXT, 'foo')] - ) - - def test_before_adjacent_elements(self): - self.assertEqual( - self._apply('*'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, TEXT, u'CONTENT 1'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, TEXT, u'CONTENT 2'), -- (ENTER, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, TEXT, 'CONTENT 1'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, TEXT, 'CONTENT 2'), -+ (ENTER, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'bar'), -+ (None, END, 'root')] - - ) - - def test_before_all(self): - self.assertEqual( - self._apply('*|text()'), -- [(None, START, u'root'), -- (None, TEXT, u'CONTENT 1'), -- (OUTSIDE, TEXT, u'ROOT'), -- (None, TEXT, u'CONTENT 2'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, TEXT, u'CONTENT 3'), -- (ENTER, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'CONTENT 1'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (None, TEXT, 'CONTENT 2'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, TEXT, 'CONTENT 3'), -+ (ENTER, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_before_with_callback(self): -@@ -844,16 +844,16 @@ class BeforeTest(unittest.TestCase, ContentTestMixin): - yield '%2i.' % count[0] - self.assertEqual( - self._apply('foo/text()', content), -- [(None, 'START', u'root'), -- (None, 'TEXT', u'ROOT'), -- (None, 'START', u'foo'), -- (None, 'TEXT', u' 1.'), -- ('OUTSIDE', 'TEXT', u'FOO'), -- (None, 'END', u'foo'), -- (None, 'START', u'bar'), -- (None, 'TEXT', u'BAR'), -- (None, 'END', u'bar'), -- (None, 'END', u'root')] -+ [(None, 'START', 'root'), -+ (None, 'TEXT', 'ROOT'), -+ (None, 'START', 'foo'), -+ (None, 'TEXT', ' 1.'), -+ ('OUTSIDE', 'TEXT', 'FOO'), -+ (None, 'END', 'foo'), -+ (None, 'START', 'bar'), -+ (None, 'TEXT', 'BAR'), -+ (None, 'END', 'bar'), -+ (None, 'END', 'root')] - ) - - -@@ -863,87 +863,87 @@ class AfterTest(unittest.TestCase, ContentTestMixin): - def test_after_element(self): - self.assertEqual( - self._apply('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, TEXT, u'CONTENT 1'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, TEXT, 'CONTENT 1'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_after_text(self): - self.assertEqual( - self._apply('text()'), -- [(None, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (None, TEXT, u'CONTENT 1'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (None, TEXT, 'CONTENT 1'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_after_context(self): - self.assertEqual( - self._apply('.'), -- [(ENTER, START, u'root'), -- (INSIDE, TEXT, u'ROOT'), -- (INSIDE, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, END, u'foo'), -- (INSIDE, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (INSIDE, END, u'bar'), -- (EXIT, END, u'root'), -- (None, TEXT, u'CONTENT 1')] -+ [(ENTER, START, 'root'), -+ (INSIDE, TEXT, 'ROOT'), -+ (INSIDE, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, END, 'foo'), -+ (INSIDE, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (INSIDE, END, 'bar'), -+ (EXIT, END, 'root'), -+ (None, TEXT, 'CONTENT 1')] - ) - - def test_after_text_context(self): - self.assertEqual( - self._apply('.', html='foo'), -- [(OUTSIDE, TEXT, u'foo'), -- (None, TEXT, u'CONTENT 1')] -+ [(OUTSIDE, TEXT, 'foo'), -+ (None, TEXT, 'CONTENT 1')] - ) - - def test_after_adjacent_elements(self): - self.assertEqual( - self._apply('*'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, TEXT, u'CONTENT 1'), -- (ENTER, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'bar'), -- (None, TEXT, u'CONTENT 2'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, TEXT, 'CONTENT 1'), -+ (ENTER, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'bar'), -+ (None, TEXT, 'CONTENT 2'), -+ (None, END, 'root')] - - ) - - def test_after_all(self): - self.assertEqual( - self._apply('*|text()'), -- [(None, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (None, TEXT, u'CONTENT 1'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, TEXT, u'CONTENT 2'), -- (ENTER, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'bar'), -- (None, TEXT, u'CONTENT 3'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (None, TEXT, 'CONTENT 1'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, TEXT, 'CONTENT 2'), -+ (ENTER, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'bar'), -+ (None, TEXT, 'CONTENT 3'), -+ (None, END, 'root')] - ) - - def test_after_with_callback(self): -@@ -953,16 +953,16 @@ class AfterTest(unittest.TestCase, ContentTestMixin): - yield '%2i.' % count[0] - self.assertEqual( - self._apply('foo/text()', content), -- [(None, 'START', u'root'), -- (None, 'TEXT', u'ROOT'), -- (None, 'START', u'foo'), -- ('OUTSIDE', 'TEXT', u'FOO'), -- (None, 'TEXT', u' 1.'), -- (None, 'END', u'foo'), -- (None, 'START', u'bar'), -- (None, 'TEXT', u'BAR'), -- (None, 'END', u'bar'), -- (None, 'END', u'root')] -+ [(None, 'START', 'root'), -+ (None, 'TEXT', 'ROOT'), -+ (None, 'START', 'foo'), -+ ('OUTSIDE', 'TEXT', 'FOO'), -+ (None, 'TEXT', ' 1.'), -+ (None, 'END', 'foo'), -+ (None, 'START', 'bar'), -+ (None, 'TEXT', 'BAR'), -+ (None, 'END', 'bar'), -+ (None, 'END', 'root')] - ) - - -@@ -972,84 +972,84 @@ class PrependTest(unittest.TestCase, ContentTestMixin) - def test_prepend_element(self): - self.assertEqual( - self._apply('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (None, TEXT, u'CONTENT 1'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (None, TEXT, 'CONTENT 1'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_prepend_text(self): - self.assertEqual( - self._apply('text()'), -- [(None, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_prepend_context(self): - self.assertEqual( - self._apply('.'), -- [(ENTER, START, u'root'), -- (None, TEXT, u'CONTENT 1'), -- (INSIDE, TEXT, u'ROOT'), -- (INSIDE, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, END, u'foo'), -- (INSIDE, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (INSIDE, END, u'bar'), -- (EXIT, END, u'root')], -+ [(ENTER, START, 'root'), -+ (None, TEXT, 'CONTENT 1'), -+ (INSIDE, TEXT, 'ROOT'), -+ (INSIDE, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, END, 'foo'), -+ (INSIDE, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (INSIDE, END, 'bar'), -+ (EXIT, END, 'root')], - ) - - def test_prepend_text_context(self): - self.assertEqual( - self._apply('.', html='foo'), -- [(OUTSIDE, TEXT, u'foo')] -+ [(OUTSIDE, TEXT, 'foo')] - ) - - def test_prepend_adjacent_elements(self): - self.assertEqual( - self._apply('*'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (None, TEXT, u'CONTENT 1'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (ENTER, START, u'bar'), -- (None, TEXT, u'CONTENT 2'), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (None, TEXT, 'CONTENT 1'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (ENTER, START, 'bar'), -+ (None, TEXT, 'CONTENT 2'), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'bar'), -+ (None, END, 'root')] - - ) - - def test_prepend_all(self): - self.assertEqual( - self._apply('*|text()'), -- [(None, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (None, TEXT, u'CONTENT 1'), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (ENTER, START, u'bar'), -- (None, TEXT, u'CONTENT 2'), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (None, TEXT, 'CONTENT 1'), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (ENTER, START, 'bar'), -+ (None, TEXT, 'CONTENT 2'), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_prepend_with_callback(self): -@@ -1059,16 +1059,16 @@ class PrependTest(unittest.TestCase, ContentTestMixin) - yield '%2i.' % count[0] - self.assertEqual( - self._apply('foo', content), -- [(None, 'START', u'root'), -- (None, 'TEXT', u'ROOT'), -- (ENTER, 'START', u'foo'), -- (None, 'TEXT', u' 1.'), -- (INSIDE, 'TEXT', u'FOO'), -- (EXIT, 'END', u'foo'), -- (None, 'START', u'bar'), -- (None, 'TEXT', u'BAR'), -- (None, 'END', u'bar'), -- (None, 'END', u'root')] -+ [(None, 'START', 'root'), -+ (None, 'TEXT', 'ROOT'), -+ (ENTER, 'START', 'foo'), -+ (None, 'TEXT', ' 1.'), -+ (INSIDE, 'TEXT', 'FOO'), -+ (EXIT, 'END', 'foo'), -+ (None, 'START', 'bar'), -+ (None, 'TEXT', 'BAR'), -+ (None, 'END', 'bar'), -+ (None, 'END', 'root')] - ) - - -@@ -1078,84 +1078,84 @@ class AppendTest(unittest.TestCase, ContentTestMixin): - def test_append_element(self): - self.assertEqual( - self._apply('foo'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (None, TEXT, u'CONTENT 1'), -- (EXIT, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (None, TEXT, 'CONTENT 1'), -+ (EXIT, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_append_text(self): - self.assertEqual( - self._apply('text()'), -- [(None, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_append_context(self): - self.assertEqual( - self._apply('.'), -- [(ENTER, START, u'root'), -- (INSIDE, TEXT, u'ROOT'), -- (INSIDE, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (INSIDE, END, u'foo'), -- (INSIDE, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (INSIDE, END, u'bar'), -- (None, TEXT, u'CONTENT 1'), -- (EXIT, END, u'root')], -+ [(ENTER, START, 'root'), -+ (INSIDE, TEXT, 'ROOT'), -+ (INSIDE, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (INSIDE, END, 'foo'), -+ (INSIDE, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (INSIDE, END, 'bar'), -+ (None, TEXT, 'CONTENT 1'), -+ (EXIT, END, 'root')], - ) - - def test_append_text_context(self): - self.assertEqual( - self._apply('.', html='foo'), -- [(OUTSIDE, TEXT, u'foo')] -+ [(OUTSIDE, TEXT, 'foo')] - ) - - def test_append_adjacent_elements(self): - self.assertEqual( - self._apply('*'), -- [(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (None, TEXT, u'CONTENT 1'), -- (EXIT, END, u'foo'), -- (ENTER, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (None, TEXT, u'CONTENT 2'), -- (EXIT, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (None, TEXT, 'CONTENT 1'), -+ (EXIT, END, 'foo'), -+ (ENTER, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (None, TEXT, 'CONTENT 2'), -+ (EXIT, END, 'bar'), -+ (None, END, 'root')] - - ) - - def test_append_all(self): - self.assertEqual( - self._apply('*|text()'), -- [(None, START, u'root'), -- (OUTSIDE, TEXT, u'ROOT'), -- (ENTER, START, u'foo'), -- (INSIDE, TEXT, u'FOO'), -- (None, TEXT, u'CONTENT 1'), -- (EXIT, END, u'foo'), -- (ENTER, START, u'bar'), -- (INSIDE, TEXT, u'BAR'), -- (None, TEXT, u'CONTENT 2'), -- (EXIT, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, 'root'), -+ (OUTSIDE, TEXT, 'ROOT'), -+ (ENTER, START, 'foo'), -+ (INSIDE, TEXT, 'FOO'), -+ (None, TEXT, 'CONTENT 1'), -+ (EXIT, END, 'foo'), -+ (ENTER, START, 'bar'), -+ (INSIDE, TEXT, 'BAR'), -+ (None, TEXT, 'CONTENT 2'), -+ (EXIT, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_append_with_callback(self): -@@ -1165,16 +1165,16 @@ class AppendTest(unittest.TestCase, ContentTestMixin): - yield '%2i.' % count[0] - self.assertEqual( - self._apply('foo', content), -- [(None, 'START', u'root'), -- (None, 'TEXT', u'ROOT'), -- (ENTER, 'START', u'foo'), -- (INSIDE, 'TEXT', u'FOO'), -- (None, 'TEXT', u' 1.'), -- (EXIT, 'END', u'foo'), -- (None, 'START', u'bar'), -- (None, 'TEXT', u'BAR'), -- (None, 'END', u'bar'), -- (None, 'END', u'root')] -+ [(None, 'START', 'root'), -+ (None, 'TEXT', 'ROOT'), -+ (ENTER, 'START', 'foo'), -+ (INSIDE, 'TEXT', 'FOO'), -+ (None, 'TEXT', ' 1.'), -+ (EXIT, 'END', 'foo'), -+ (None, 'START', 'bar'), -+ (None, 'TEXT', 'BAR'), -+ (None, 'END', 'bar'), -+ (None, 'END', 'root')] - ) - - -@@ -1187,29 +1187,29 @@ class AttrTest(unittest.TestCase): - def test_set_existing_attr(self): - self.assertEqual( - self._attr('foo', 'name', 'FOO'), -- [(None, START, (u'root', {})), -- (None, TEXT, u'ROOT'), -- (ENTER, START, (u'foo', {u'name': 'FOO', u'size': '100'})), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, START, (u'bar', {u'name': u'bar'})), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, ('root', {})), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, ('foo', {'name': 'FOO', 'size': '100'})), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, START, ('bar', {'name': 'bar'})), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_set_new_attr(self): - self.assertEqual( - self._attr('foo', 'title', 'FOO'), -- [(None, START, (u'root', {})), -- (None, TEXT, u'ROOT'), -- (ENTER, START, (u'foo', {u'name': u'foo', u'title': 'FOO', u'size': '100'})), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, START, (u'bar', {u'name': u'bar'})), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, ('root', {})), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, ('foo', {'name': 'foo', 'title': 'FOO', 'size': '100'})), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, START, ('bar', {'name': 'bar'})), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_attr_from_function(self): -@@ -1219,29 +1219,29 @@ class AttrTest(unittest.TestCase): - - self.assertEqual( - self._attr('foo|bar', 'name', set), -- [(None, START, (u'root', {})), -- (None, TEXT, u'ROOT'), -- (ENTER, START, (u'foo', {u'name': 'FOO', u'size': '100'})), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (ENTER, START, (u'bar', {u'name': 'BAR'})), -- (INSIDE, TEXT, u'BAR'), -- (EXIT, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, ('root', {})), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, ('foo', {'name': 'FOO', 'size': '100'})), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (ENTER, START, ('bar', {'name': 'BAR'})), -+ (INSIDE, TEXT, 'BAR'), -+ (EXIT, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_remove_attr(self): - self.assertEqual( - self._attr('foo', 'name', None), -- [(None, START, (u'root', {})), -- (None, TEXT, u'ROOT'), -- (ENTER, START, (u'foo', {u'size': '100'})), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, START, (u'bar', {u'name': u'bar'})), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, ('root', {})), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, ('foo', {'size': '100'})), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, START, ('bar', {'name': 'bar'})), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - def test_remove_attr_with_function(self): -@@ -1250,15 +1250,15 @@ class AttrTest(unittest.TestCase): - - self.assertEqual( - self._attr('foo', 'name', set), -- [(None, START, (u'root', {})), -- (None, TEXT, u'ROOT'), -- (ENTER, START, (u'foo', {u'size': '100'})), -- (INSIDE, TEXT, u'FOO'), -- (EXIT, END, u'foo'), -- (None, START, (u'bar', {u'name': u'bar'})), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')] -+ [(None, START, ('root', {})), -+ (None, TEXT, 'ROOT'), -+ (ENTER, START, ('foo', {'size': '100'})), -+ (INSIDE, TEXT, 'FOO'), -+ (EXIT, END, 'foo'), -+ (None, START, ('bar', {'name': 'bar'})), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')] - ) - - -@@ -1294,65 +1294,65 @@ class CopyTest(unittest.TestCase, BufferTestMixin): - def test_copy_element(self): - self.assertEqual( - self._apply('foo')[1], -- [[(None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo')]] -+ [[(None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo')]] - ) - - def test_copy_adjacent_elements(self): - self.assertEqual( - self._apply('foo|bar')[1], -- [[(None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo')], -- [(None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar')]] -+ [[(None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo')], -+ [(None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar')]] - ) - - def test_copy_all(self): - self.assertEqual( - self._apply('*|text()')[1], -- [[(None, TEXT, u'ROOT')], -- [(None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo')], -- [(None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar')]] -+ [[(None, TEXT, 'ROOT')], -+ [(None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo')], -+ [(None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar')]] - ) - - def test_copy_text(self): - self.assertEqual( - self._apply('*/text()')[1], -- [[(None, TEXT, u'FOO')], -- [(None, TEXT, u'BAR')]] -+ [[(None, TEXT, 'FOO')], -+ [(None, TEXT, 'BAR')]] - ) - - def test_copy_context(self): - self.assertEqual( - self._apply('.')[1], -- [[(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')]] -+ [[(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')]] - ) - - def test_copy_attribute(self): - self.assertEqual( - self._apply('foo/@name', with_attrs=True)[1], -- [[(None, ATTR, {'name': u'foo'})]] -+ [[(None, ATTR, {'name': 'foo'})]] - ) - - def test_copy_attributes(self): - self.assertEqual( - self._apply('foo/@*', with_attrs=True)[1], -- [[(None, ATTR, {u'name': u'foo', u'size': u'100'})]] -+ [[(None, ATTR, {'name': 'foo', 'size': '100'})]] - ) - - -@@ -1362,104 +1362,104 @@ class CutTest(unittest.TestCase, BufferTestMixin): - def test_cut_element(self): - self.assertEqual( - self._apply('foo'), -- ([(None, START, u'root'), -- (None, TEXT, u'ROOT'), -- (None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')], -- [[(None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo')]]) -+ ([(None, START, 'root'), -+ (None, TEXT, 'ROOT'), -+ (None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')], -+ [[(None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo')]]) - ) - - def test_cut_adjacent_elements(self): - self.assertEqual( - self._apply('foo|bar'), -- ([(None, START, u'root'), -- (None, TEXT, u'ROOT'), -+ ([(None, START, 'root'), -+ (None, TEXT, 'ROOT'), - (BREAK, BREAK, None), -- (None, END, u'root')], -- [[(None, START, u'foo'), -- (None, TEXT, u'FOO'), -- (None, END, u'foo')], -- [(None, START, u'bar'), -- (None, TEXT, u'BAR'), -- (None, END, u'bar')]]) -+ (None, END, 'root')], -+ [[(None, START, 'foo'), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo')], -+ [(None, START, 'bar'), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar')]]) - ) - - def test_cut_all(self): - self.assertEqual( - self._apply('*|text()'), -- ([(None, 'START', u'root'), -+ ([(None, 'START', 'root'), - ('BREAK', 'BREAK', None), - ('BREAK', 'BREAK', None), -- (None, 'END', u'root')], -- [[(None, 'TEXT', u'ROOT')], -- [(None, 'START', u'foo'), -- (None, 'TEXT', u'FOO'), -- (None, 'END', u'foo')], -- [(None, 'START', u'bar'), -- (None, 'TEXT', u'BAR'), -- (None, 'END', u'bar')]]) -+ (None, 'END', 'root')], -+ [[(None, 'TEXT', 'ROOT')], -+ [(None, 'START', 'foo'), -+ (None, 'TEXT', 'FOO'), -+ (None, 'END', 'foo')], -+ [(None, 'START', 'bar'), -+ (None, 'TEXT', 'BAR'), -+ (None, 'END', 'bar')]]) - ) - - def test_cut_text(self): - self.assertEqual( - self._apply('*/text()'), -- ([(None, 'START', u'root'), -- (None, 'TEXT', u'ROOT'), -- (None, 'START', u'foo'), -- (None, 'END', u'foo'), -- (None, 'START', u'bar'), -- (None, 'END', u'bar'), -- (None, 'END', u'root')], -- [[(None, 'TEXT', u'FOO')], -- [(None, 'TEXT', u'BAR')]]) -+ ([(None, 'START', 'root'), -+ (None, 'TEXT', 'ROOT'), -+ (None, 'START', 'foo'), -+ (None, 'END', 'foo'), -+ (None, 'START', 'bar'), -+ (None, 'END', 'bar'), -+ (None, 'END', 'root')], -+ [[(None, 'TEXT', 'FOO')], -+ [(None, 'TEXT', 'BAR')]]) - ) - - def test_cut_context(self): - self.assertEqual( - self._apply('.')[1], -- [[(None, 'START', u'root'), -- (None, 'TEXT', u'ROOT'), -- (None, 'START', u'foo'), -- (None, 'TEXT', u'FOO'), -- (None, 'END', u'foo'), -- (None, 'START', u'bar'), -- (None, 'TEXT', u'BAR'), -- (None, 'END', u'bar'), -- (None, 'END', u'root')]] -+ [[(None, 'START', 'root'), -+ (None, 'TEXT', 'ROOT'), -+ (None, 'START', 'foo'), -+ (None, 'TEXT', 'FOO'), -+ (None, 'END', 'foo'), -+ (None, 'START', 'bar'), -+ (None, 'TEXT', 'BAR'), -+ (None, 'END', 'bar'), -+ (None, 'END', 'root')]] - ) - - def test_cut_attribute(self): - self.assertEqual( - self._apply('foo/@name', with_attrs=True), -- ([(None, START, (u'root', {})), -- (None, TEXT, u'ROOT'), -- (None, START, (u'foo', {u'size': u'100'})), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, (u'bar', {u'name': u'bar'})), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')], -- [[(None, ATTR, {u'name': u'foo'})]]) -+ ([(None, START, ('root', {})), -+ (None, TEXT, 'ROOT'), -+ (None, START, ('foo', {'size': '100'})), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, ('bar', {'name': 'bar'})), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')], -+ [[(None, ATTR, {'name': 'foo'})]]) - ) - - def test_cut_attributes(self): - self.assertEqual( - self._apply('foo/@*', with_attrs=True), -- ([(None, START, (u'root', {})), -- (None, TEXT, u'ROOT'), -- (None, START, (u'foo', {})), -- (None, TEXT, u'FOO'), -- (None, END, u'foo'), -- (None, START, (u'bar', {u'name': u'bar'})), -- (None, TEXT, u'BAR'), -- (None, END, u'bar'), -- (None, END, u'root')], -- [[(None, ATTR, {u'name': u'foo', u'size': u'100'})]]) -+ ([(None, START, ('root', {})), -+ (None, TEXT, 'ROOT'), -+ (None, START, ('foo', {})), -+ (None, TEXT, 'FOO'), -+ (None, END, 'foo'), -+ (None, START, ('bar', {'name': 'bar'})), -+ (None, TEXT, 'BAR'), -+ (None, END, 'bar'), -+ (None, END, 'root')], -+ [[(None, ATTR, {'name': 'foo', 'size': '100'})]]) - ) - - # XXX Test this when the XPath implementation is fixed (#233). ---- genshi/filters/transform.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/filters/transform.py -@@ -115,7 +115,7 @@ class PushBackStream(object): - yield peek - else: - try: -- event = self.stream.next() -+ event = next(self.stream) - yield event - except StopIteration: - if self.peek is None: -@@ -730,7 +730,7 @@ class SelectTransformation(object): - variables = {} - test = self.path.test() - stream = iter(stream) -- next = stream.next -+ next = stream.__next__ - for mark, event in stream: - if mark is None: - yield mark, event -@@ -764,7 +764,7 @@ class SelectTransformation(object): - yield OUTSIDE, result - elif result: - # XXX Assume everything else is "text"? -- yield None, (TEXT, unicode(result), (None, -1, -1)) -+ yield None, (TEXT, str(result), (None, -1, -1)) - else: - yield None, event - -@@ -990,7 +990,7 @@ class SubstituteTransformation(object): - :param replace: Replacement pattern. - :param count: Number of replacements to make in each text fragment. - """ -- if isinstance(pattern, basestring): -+ if isinstance(pattern, str): - self.pattern = re.compile(pattern) - else: - self.pattern = pattern ---- genshi/input.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/input.py -@@ -17,8 +17,8 @@ sources. - - from itertools import chain - import codecs --import htmlentitydefs as entities --import HTMLParser as html -+import html.entities as entities -+import html.parser as html - from xml.parsers import expat - - from genshi.core import Attrs, QName, Stream, stripentities -@@ -39,7 +39,7 @@ def ET(element): - """ - tag_name = QName(element.tag.lstrip('{')) - attrs = Attrs([(QName(attr.lstrip('{')), value) -- for attr, value in element.items()]) -+ for attr, value in list(element.items())]) - - yield START, (tag_name, attrs), (None, -1, -1) - if element.text: -@@ -91,8 +91,8 @@ class XMLParser(object): - """ - - _entitydefs = ['' % (name, value) for name, value in -- entities.name2codepoint.items()] -- _external_dtd = u'\n'.join(_entitydefs).encode('utf-8') -+ list(entities.name2codepoint.items())] -+ _external_dtd = '\n'.join(_entitydefs).encode('utf-8') - - def __init__(self, source, filename=None, encoding=None): - """Initialize the parser for the given XML input. -@@ -156,7 +156,7 @@ class XMLParser(object): - del self.expat # get rid of circular references - done = True - else: -- if isinstance(data, unicode): -+ if isinstance(data, str): - data = data.encode('utf-8') - self.expat.Parse(data, False) - for event in self._queue: -@@ -164,7 +164,7 @@ class XMLParser(object): - self._queue = [] - if done: - break -- except expat.ExpatError, e: -+ except expat.ExpatError as e: - msg = str(e) - raise ParseError(msg, self.filename, e.lineno, e.offset) - return Stream(_generate()).filter(_coalesce) -@@ -242,7 +242,7 @@ class XMLParser(object): - if text.startswith('&'): - # deal with undefined entities - try: -- text = unichr(entities.name2codepoint[text[1:-1]]) -+ text = chr(entities.name2codepoint[text[1:-1]]) - self._enqueue(TEXT, text) - except KeyError: - filename, lineno, offset = self._getpos() -@@ -333,7 +333,7 @@ class HTMLParser(html.HTMLParser, object): - self.close() - done = True - else: -- if not isinstance(data, unicode): -+ if not isinstance(data, str): - raise UnicodeError("source returned bytes, but no encoding specified") - self.feed(data) - for kind, data, pos in self._queue: -@@ -345,7 +345,7 @@ class HTMLParser(html.HTMLParser, object): - for tag in open_tags: - yield END, QName(tag), pos - break -- except html.HTMLParseError, e: -+ except html.HTMLParseError as e: - msg = '%s: line %d, column %d' % (e.msg, e.lineno, e.offset) - raise ParseError(msg, self.filename, e.lineno, e.offset) - return Stream(_generate()).filter(_coalesce) -@@ -388,14 +388,14 @@ class HTMLParser(html.HTMLParser, object): - - def handle_charref(self, name): - if name.lower().startswith('x'): -- text = unichr(int(name[1:], 16)) -+ text = chr(int(name[1:], 16)) - else: -- text = unichr(int(name)) -+ text = chr(int(name)) - self._enqueue(TEXT, text) - - def handle_entityref(self, name): - try: -- text = unichr(entities.name2codepoint[name]) -+ text = chr(entities.name2codepoint[name]) - except KeyError: - text = '&%s;' % name - self._enqueue(TEXT, text) -@@ -434,7 +434,7 @@ def HTML(text, encoding=None): - :raises ParseError: if the HTML text is not well-formed, and error recovery - fails - """ -- if isinstance(text, unicode): -+ if isinstance(text, str): - # If it's unicode text the encoding should be set to None. - # The option to pass in an incorrect encoding is for ease - # of writing doctests that work in both Python 2.x and 3.x. ---- genshi/output.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/output.py -@@ -71,7 +71,7 @@ def get_serializer(method='xml', **kwargs): - :see: `XMLSerializer`, `XHTMLSerializer`, `HTMLSerializer`, `TextSerializer` - :since: version 0.4.1 - """ -- if isinstance(method, basestring): -+ if isinstance(method, str): - method = {'xml': XMLSerializer, - 'xhtml': XHTMLSerializer, - 'html': HTMLSerializer, -@@ -581,7 +581,7 @@ class TextSerializer(object): - data = event[1] - if strip_markup and type(data) is Markup: - data = data.striptags().stripentities() -- yield unicode(data) -+ yield str(data) - - - class EmptyTagFilter(object): -@@ -636,7 +636,7 @@ class NamespaceFlattener(object): - self.cache = cache - - def __call__(self, stream): -- prefixes = dict([(v, [k]) for k, v in self.prefixes.items()]) -+ prefixes = dict([(v, [k]) for k, v in list(self.prefixes.items())]) - namespaces = {XML_NAMESPACE.uri: ['xml']} - _emit, _get, cache = _prepare_cache(self.cache) - def _push_ns(prefix, uri): -@@ -666,7 +666,7 @@ class NamespaceFlattener(object): - while 1: - val += 1 - yield 'ns%d' % val -- _gen_prefix = _gen_prefix().next -+ _gen_prefix = _gen_prefix().__next__ - - for kind, data, pos in stream: - if kind is TEXT and isinstance(data, Markup): -@@ -822,7 +822,7 @@ class DocTypeInserter(object): - - :param doctype: DOCTYPE as a string or DocType object. - """ -- if isinstance(doctype, basestring): -+ if isinstance(doctype, str): - doctype = DocType.get(doctype) - self.doctype_event = (DOCTYPE, doctype, (None, -1, -1)) - ---- genshi/path.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/path.py -@@ -576,7 +576,7 @@ class Path(object): - variables = {} - stream = iter(stream) - def _generate(stream=stream, ns=namespaces, vs=variables): -- next = stream.next -+ next = stream.__next__ - test = self.test() - for event in stream: - result = test(event, ns, vs) -@@ -932,13 +932,13 @@ def as_float(value): - return float(as_scalar(value)) - - def as_long(value): -- return long(as_scalar(value)) -+ return int(as_scalar(value)) - - def as_string(value): - value = as_scalar(value) - if value is False: - return '' -- return unicode(value) -+ return str(value) - - def as_bool(value): - return bool(as_scalar(value)) -@@ -1346,8 +1346,8 @@ class TranslateFunction(Function): - string = as_string(self.string(kind, data, pos, namespaces, variables)) - fromchars = as_string(self.fromchars(kind, data, pos, namespaces, variables)) - tochars = as_string(self.tochars(kind, data, pos, namespaces, variables)) -- table = dict(zip([ord(c) for c in fromchars], -- [ord(c) for c in tochars])) -+ table = dict(list(zip([ord(c) for c in fromchars], -+ [ord(c) for c in tochars]))) - return string.translate(table) - def __repr__(self): - return 'translate(%r, %r, %r)' % (self.string, self.fromchars, ---- genshi/template/ast24.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/ast24.py -@@ -378,7 +378,7 @@ class ASTUpgrader(object): - def visit_Const(self, node): - if node.value is None: # appears in slices - return None -- elif isinstance(node.value, basestring): -+ elif isinstance(node.value, str): - return self._new(_ast.Str, node.value) - else: - return self._new(_ast.Num, node.value) ---- genshi/template/base.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/base.py -@@ -179,7 +179,7 @@ class Context(object): - - :return: the number of variables in the context - """ -- return len(self.items()) -+ return len(list(self.items())) - - def __setitem__(self, key, value): - """Set a variable in the current scope. -@@ -232,7 +232,7 @@ class Context(object): - - :return: a list of variables - """ -- return [(key, self.get(key)) for key in self.keys()] -+ return [(key, self.get(key)) for key in list(self.keys())] - - def update(self, mapping): - """Update the context from the mapping provided.""" -@@ -321,12 +321,11 @@ class DirectiveFactoryMeta(type): - return type.__new__(cls, name, bases, d) - - --class DirectiveFactory(object): -+class DirectiveFactory(object, metaclass=DirectiveFactoryMeta): - """Base for classes that provide a set of template directives. - - :since: version 0.6 - """ -- __metaclass__ = DirectiveFactoryMeta - - directives = [] - """A list of ``(name, cls)`` tuples that define the set of directives -@@ -379,7 +378,7 @@ class Template(DirectiveFactory): - """ - - serializer = None -- _number_conv = unicode # function used to convert numbers to event data -+ _number_conv = str # function used to convert numbers to event data - - def __init__(self, source, filepath=None, filename=None, loader=None, - encoding=None, lookup='strict', allow_exec=True): -@@ -411,13 +410,13 @@ class Template(DirectiveFactory): - self._prepared = False - - if not isinstance(source, Stream) and not hasattr(source, 'read'): -- if isinstance(source, unicode): -+ if isinstance(source, str): - source = StringIO(source) - else: - source = BytesIO(source) - try: - self._stream = self._parse(source, encoding) -- except ParseError, e: -+ except ParseError as e: - raise TemplateSyntaxError(e.msg, self.filepath, e.lineno, e.offset) - - def __getstate__(self): -@@ -502,7 +501,7 @@ class Template(DirectiveFactory): - if kind is INCLUDE: - href, cls, fallback = data - tmpl_inlined = False -- if (isinstance(href, basestring) and -+ if (isinstance(href, str) and - not getattr(self.loader, 'auto_reload', True)): - # If the path to the included template is static, and - # auto-reloading is disabled on the template loader, -@@ -601,16 +600,16 @@ class Template(DirectiveFactory): - # First check for a string, otherwise the iterable test - # below succeeds, and the string will be chopped up into - # individual characters -- if isinstance(result, basestring): -+ if isinstance(result, str): - yield TEXT, result, pos -- elif isinstance(result, (int, float, long)): -+ elif isinstance(result, (int, float)): - yield TEXT, number_conv(result), pos - elif hasattr(result, '__iter__'): - push(stream) - stream = _ensure(result) - break - else: -- yield TEXT, unicode(result), pos -+ yield TEXT, str(result), pos - - elif kind is SUB: - # This event is a list of directives and a list of nested -@@ -639,7 +638,7 @@ class Template(DirectiveFactory): - for event in stream: - if event[0] is INCLUDE: - href, cls, fallback = event[1] -- if not isinstance(href, basestring): -+ if not isinstance(href, str): - parts = [] - for subkind, subdata, subpos in self._flatten(href, ctxt, - **vars): ---- genshi/template/directives.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/directives.py -@@ -35,7 +35,7 @@ class DirectiveMeta(type): - return type.__new__(cls, name, bases, d) - - --class Directive(object): -+class Directive(object, metaclass=DirectiveMeta): - """Abstract base class for template directives. - - A directive is basically a callable that takes three positional arguments: -@@ -53,7 +53,6 @@ class Directive(object): - described above, and can only be applied programmatically (for example by - template filters). - """ -- __metaclass__ = DirectiveMeta - __slots__ = ['expr'] - - def __init__(self, value, template=None, namespaces=None, lineno=-1, -@@ -108,7 +107,7 @@ class Directive(object): - try: - return expr and Expression(expr, template.filepath, lineno, - lookup=template.lookup) or None -- except SyntaxError, err: -+ except SyntaxError as err: - err.msg += ' in expression "%s" of "%s" directive' % (expr, - cls.tagname) - raise TemplateSyntaxError(err, template.filepath, lineno, -@@ -165,18 +164,18 @@ class AttrsDirective(Directive): - - def __call__(self, stream, directives, ctxt, **vars): - def _generate(): -- kind, (tag, attrib), pos = stream.next() -+ kind, (tag, attrib), pos = next(stream) - attrs = _eval_expr(self.expr, ctxt, vars) - if attrs: - if isinstance(attrs, Stream): - try: -- attrs = iter(attrs).next() -+ attrs = next(iter(attrs)) - except StopIteration: - attrs = [] - elif not isinstance(attrs, list): # assume it's a dict -- attrs = attrs.items() -+ attrs = list(attrs.items()) - attrib |= [ -- (QName(n), v is not None and unicode(v).strip() or None) -+ (QName(n), v is not None and str(v).strip() or None) - for n, v in attrs - ] - yield kind, (tag, attrib), pos -@@ -537,8 +536,8 @@ class StripDirective(Directive): - def __call__(self, stream, directives, ctxt, **vars): - def _generate(): - if not self.expr or _eval_expr(self.expr, ctxt, vars): -- stream.next() # skip start tag -- previous = stream.next() -+ next(stream) # skip start tag -+ previous = next(stream) - for event in stream: - yield previous - previous = event -@@ -630,13 +629,13 @@ class WhenDirective(Directive): - if not info: - raise TemplateRuntimeError('"when" directives can only be used ' - 'inside a "choose" directive', -- self.filename, *(stream.next())[2][1:]) -+ self.filename, *(next(stream))[2][1:]) - if info[0]: - return [] - if not self.expr and not info[1]: - raise TemplateRuntimeError('either "choose" or "when" directive ' - 'must have a test expression', -- self.filename, *(stream.next())[2][1:]) -+ self.filename, *(next(stream))[2][1:]) - if info[1]: - value = info[2] - if self.expr: -@@ -669,7 +668,7 @@ class OtherwiseDirective(Directive): - if not info: - raise TemplateRuntimeError('an "otherwise" directive can only be ' - 'used inside a "choose" directive', -- self.filename, *(stream.next())[2][1:]) -+ self.filename, *(next(stream))[2][1:]) - if info[0]: - return [] - info[0] = True -@@ -706,7 +705,7 @@ class WithDirective(Directive): - self.vars.append(([_assignment(n) for n in node.targets], - Expression(node.value, template.filepath, - lineno, lookup=template.lookup))) -- except SyntaxError, err: -+ except SyntaxError as err: - err.msg += ' in expression "%s" of "%s" directive' % (value, - self.tagname) - raise TemplateSyntaxError(err, template.filepath, lineno, ---- genshi/template/eval.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/eval.py -@@ -13,7 +13,7 @@ - - """Support for "safe" evaluation of Python expressions.""" - --import __builtin__ -+import builtins - - from textwrap import dedent - from types import CodeType -@@ -37,7 +37,7 @@ has_star_import_bug = False - try: - class _FakeMapping(object): - __getitem__ = __setitem__ = lambda *a: None -- exec 'from sys import *' in {}, _FakeMapping() -+ exec('from sys import *', {}, _FakeMapping()) - except SystemError: - has_star_import_bug = True - del _FakeMapping -@@ -75,7 +75,7 @@ class Code(object): - if `None`, the appropriate transformation is chosen - depending on the mode - """ -- if isinstance(source, basestring): -+ if isinstance(source, str): - self.source = source - node = _parse(source, mode=self.mode) - else: -@@ -94,13 +94,13 @@ class Code(object): - filename=filename, lineno=lineno, xform=xform) - if lookup is None: - lookup = LenientLookup -- elif isinstance(lookup, basestring): -+ elif isinstance(lookup, str): - lookup = {'lenient': LenientLookup, 'strict': StrictLookup}[lookup] - self._globals = lookup.globals - - def __getstate__(self): - state = {'source': self.source, 'ast': self.ast, -- 'lookup': self._globals.im_self} -+ 'lookup': self._globals.__self__} - state['code'] = get_code_params(self.code) - return state - -@@ -196,7 +196,7 @@ class Suite(Code): - """ - __traceback_hide__ = 'before_and_this' - _globals = self._globals(data) -- exec self.code in _globals, data -+ exec(self.code, _globals, data) - - - UNDEFINED = object() -@@ -264,7 +264,7 @@ class Undefined(object): - def __iter__(self): - return iter([]) - -- def __nonzero__(self): -+ def __bool__(self): - return False - - def __repr__(self): -@@ -333,8 +333,8 @@ class LookupBase(object): - key = key[0] - try: - return obj[key] -- except (AttributeError, KeyError, IndexError, TypeError), e: -- if isinstance(key, basestring): -+ except (AttributeError, KeyError, IndexError, TypeError) as e: -+ if isinstance(key, str): - val = getattr(obj, key, UNDEFINED) - if val is UNDEFINED: - val = cls.undefined(key, owner=obj) -@@ -424,8 +424,8 @@ def _parse(source, mode='eval'): - if first.rstrip().endswith(':') and not rest[0].isspace(): - rest = '\n'.join([' %s' % line for line in rest.splitlines()]) - source = '\n'.join([first, rest]) -- if isinstance(source, unicode): -- source = (u'\ufeff' + source).encode('utf-8') -+ if isinstance(source, str): -+ source = ('\ufeff' + source).encode('utf-8') - return parse(source, mode) - - -@@ -435,11 +435,11 @@ def _compile(node, source=None, mode='eval', filename= - filename = '' - if IS_PYTHON2: - # Python 2 requires non-unicode filenames -- if isinstance(filename, unicode): -+ if isinstance(filename, str): - filename = filename.encode('utf-8', 'replace') - else: - # Python 3 requires unicode filenames -- if not isinstance(filename, unicode): -+ if not isinstance(filename, str): - filename = filename.decode('utf-8', 'replace') - if lineno <= 0: - lineno = 1 -@@ -483,7 +483,7 @@ def _new(class_, *args, **kwargs): - return ret - - --BUILTINS = __builtin__.__dict__.copy() -+BUILTINS = builtins.__dict__.copy() - BUILTINS.update({'Markup': Markup, 'Undefined': Undefined}) - CONSTANTS = frozenset(['False', 'True', 'None', 'NotImplemented', 'Ellipsis']) - -@@ -527,7 +527,7 @@ class TemplateASTTransformer(ASTTransformer): - return names - - def visit_Str(self, node): -- if not isinstance(node.s, unicode): -+ if not isinstance(node.s, str): - try: # If the string is ASCII, return a `str` object - node.s.decode('ascii') - except ValueError: # Otherwise return a `unicode` object ---- genshi/template/interpolation.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/interpolation.py -@@ -77,7 +77,7 @@ def interpolate(text, filepath=None, lineno=-1, offset - expr = Expression(chunk.strip(), pos[0], pos[1], - lookup=lookup) - yield EXPR, expr, tuple(pos) -- except SyntaxError, err: -+ except SyntaxError as err: - raise TemplateSyntaxError(err, filepath, pos[1], - pos[2] + (err.offset or 0)) - else: ---- genshi/template/loader.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/loader.py -@@ -217,7 +217,7 @@ class TemplateLoader(object): - raise TemplateError('Search path for templates not configured') - - for loadfunc in search_path: -- if isinstance(loadfunc, basestring): -+ if isinstance(loadfunc, str): - loadfunc = directory(loadfunc) - try: - filepath, filename, fileobj, uptodate = loadfunc(filename) -@@ -327,9 +327,9 @@ class TemplateLoader(object): - :rtype: ``function`` - """ - def _dispatch_by_prefix(filename): -- for prefix, delegate in delegates.items(): -+ for prefix, delegate in list(delegates.items()): - if filename.startswith(prefix): -- if isinstance(delegate, basestring): -+ if isinstance(delegate, str): - delegate = directory(delegate) - filepath, _, fileobj, uptodate = delegate( - filename[len(prefix):].lstrip('/\\') ---- genshi/template/markup.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/markup.py -@@ -93,7 +93,7 @@ class MarkupTemplate(Template): - try: - suite = Suite(data[1], self.filepath, pos[1], - lookup=self.lookup) -- except SyntaxError, err: -+ except SyntaxError as err: - raise TemplateSyntaxError(err, self.filepath, - pos[1] + (err.lineno or 1) - 1, - pos[2] + (err.offset or 0)) -@@ -311,7 +311,7 @@ class MarkupTemplate(Template): - - def _strip(stream, append): - depth = 1 -- next = stream.next -+ next = stream.__next__ - while 1: - event = next() - if event[0] is START: ---- genshi/template/plugin.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/plugin.py -@@ -46,7 +46,7 @@ class AbstractTemplateEnginePlugin(object): - - self.default_encoding = options.get('genshi.default_encoding', None) - auto_reload = options.get('genshi.auto_reload', '1') -- if isinstance(auto_reload, basestring): -+ if isinstance(auto_reload, str): - auto_reload = auto_reload.lower() in ('1', 'on', 'yes', 'true') - search_path = [p for p in - options.get('genshi.search_path', '').split(':') if p] -@@ -168,7 +168,7 @@ class TextTemplateEnginePlugin(AbstractTemplateEngineP - options = {} - - new_syntax = options.get('genshi.new_text_syntax') -- if isinstance(new_syntax, basestring): -+ if isinstance(new_syntax, str): - new_syntax = new_syntax.lower() in ('1', 'on', 'yes', 'true') - if new_syntax: - self.template_class = NewTextTemplate ---- genshi/template/tests/directives.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/tests/directives.py -@@ -426,7 +426,7 @@ class ForDirectiveTestCase(unittest.TestCase): - 3 - 4 - 5 -- """, tmpl.generate(items=range(1, 6)).render(encoding=None)) -+ """, tmpl.generate(items=list(range(1, 6))).render(encoding=None)) - - def test_as_element(self): - """ -@@ -443,7 +443,7 @@ class ForDirectiveTestCase(unittest.TestCase): - 3 - 4 - 5 -- """, tmpl.generate(items=range(1, 6)).render(encoding=None)) -+ """, tmpl.generate(items=list(range(1, 6))).render(encoding=None)) - - def test_multi_assignment(self): - """ -@@ -487,7 +487,7 @@ class ForDirectiveTestCase(unittest.TestCase): - try: - list(tmpl.generate(foo=12)) - self.fail('Expected TemplateRuntimeError') -- except TypeError, e: -+ except TypeError as e: - assert (str(e) == "iteration over non-sequence" or - str(e) == "'int' object is not iterable") - exc_type, exc_value, exc_traceback = sys.exc_info() -@@ -513,7 +513,7 @@ class ForDirectiveTestCase(unittest.TestCase): - - """, filename='test.html').generate() - self.fail('ExpectedTemplateSyntaxError') -- except TemplateSyntaxError, e: -+ except TemplateSyntaxError as e: - self.assertEqual('test.html', e.filename) - if sys.version_info[:2] > (2,4): - self.assertEqual(2, e.lineno) -@@ -1050,7 +1050,7 @@ class ContentDirectiveTestCase(unittest.TestCase): - Foo - """, filename='test.html').generate() - self.fail('Expected TemplateSyntaxError') -- except TemplateSyntaxError, e: -+ except TemplateSyntaxError as e: - self.assertEqual('test.html', e.filename) - self.assertEqual(2, e.lineno) - -@@ -1068,7 +1068,7 @@ class ReplaceDirectiveTestCase(unittest.TestCase): - Foo - """, filename='test.html').generate() - self.fail('Expected TemplateSyntaxError') -- except TemplateSyntaxError, e: -+ except TemplateSyntaxError as e: - self.assertEqual('test.html', e.filename) - self.assertEqual(2, e.lineno) - -@@ -1190,12 +1190,12 @@ class WithDirectiveTestCase(unittest.TestCase): -
""", tmpl.generate(foo={'bar': 42}).render(encoding=None)) - - def test_unicode_expr(self): -- tmpl = MarkupTemplate(u"""
-+ tmpl = MarkupTemplate("""
- - $weeks - -
""") -- self.assertEqual(u"""
-+ self.assertEqual("""
- - 一二三四五六日 - ---- genshi/template/tests/eval.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/tests/eval.py -@@ -58,34 +58,34 @@ class ExpressionTestCase(unittest.TestCase): - def test_str_literal(self): - self.assertEqual('foo', Expression('"foo"').evaluate({})) - self.assertEqual('foo', Expression('"""foo"""').evaluate({})) -- self.assertEqual(u'foo'.encode('utf-8'), -+ self.assertEqual('foo'.encode('utf-8'), - Expression(wrapped_bytes("b'foo'")).evaluate({})) - self.assertEqual('foo', Expression("'''foo'''").evaluate({})) - self.assertEqual('foo', Expression("u'foo'").evaluate({})) - self.assertEqual('foo', Expression("r'foo'").evaluate({})) - - def test_str_literal_non_ascii(self): -- expr = Expression(u"u'\xfe'") -- self.assertEqual(u'þ', expr.evaluate({})) - expr = Expression("u'\xfe'") -- self.assertEqual(u'þ', expr.evaluate({})) -+ self.assertEqual('þ', expr.evaluate({})) -+ expr = Expression("u'\xfe'") -+ self.assertEqual('þ', expr.evaluate({})) - # On Python2 strings are converted to unicode if they contained - # non-ASCII characters. - # On Py3k, we have no need to do this as non-prefixed strings aren't - # raw. - expr = Expression(wrapped_bytes(r"b'\xc3\xbe'")) - if IS_PYTHON2: -- self.assertEqual(u'þ', expr.evaluate({})) -+ self.assertEqual('þ', expr.evaluate({})) - else: -- self.assertEqual(u'þ'.encode('utf-8'), expr.evaluate({})) -+ self.assertEqual('þ'.encode('utf-8'), expr.evaluate({})) - - def test_num_literal(self): - self.assertEqual(42, Expression("42").evaluate({})) - if IS_PYTHON2: -- self.assertEqual(42L, Expression("42L").evaluate({})) -+ self.assertEqual(42, Expression("42L").evaluate({})) - self.assertEqual(.42, Expression(".42").evaluate({})) - if IS_PYTHON2: -- self.assertEqual(07, Expression("07").evaluate({})) -+ self.assertEqual(0o7, Expression("07").evaluate({})) - self.assertEqual(0xF2, Expression("0xF2").evaluate({})) - self.assertEqual(0XF2, Expression("0XF2").evaluate({})) - -@@ -236,7 +236,7 @@ class ExpressionTestCase(unittest.TestCase): - self.assertEqual(42, Expression("foo()").evaluate({'foo': lambda: 42})) - data = {'foo': 'bar'} - self.assertEqual('BAR', Expression("foo.upper()").evaluate(data)) -- data = {'foo': {'bar': range(42)}} -+ data = {'foo': {'bar': list(range(42))}} - self.assertEqual(42, Expression("len(foo.bar)").evaluate(data)) - - def test_call_keywords(self): -@@ -254,7 +254,7 @@ class ExpressionTestCase(unittest.TestCase): - self.assertEqual(42, expr.evaluate({'foo': foo, 'bar': {"x": 42}})) - - def test_lambda(self): -- data = {'items': range(5)} -+ data = {'items': list(range(5))} - expr = Expression("filter(lambda x: x > 2, items)") - self.assertEqual([3, 4], list(expr.evaluate(data))) - -@@ -268,19 +268,19 @@ class ExpressionTestCase(unittest.TestCase): - - def test_list_comprehension(self): - expr = Expression("[n for n in numbers if n < 2]") -- self.assertEqual([0, 1], expr.evaluate({'numbers': range(5)})) -+ self.assertEqual([0, 1], expr.evaluate({'numbers': list(range(5))})) - - expr = Expression("[(i, n + 1) for i, n in enumerate(numbers)]") - self.assertEqual([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)], -- expr.evaluate({'numbers': range(5)})) -+ expr.evaluate({'numbers': list(range(5))})) - - expr = Expression("[offset + n for n in numbers]") - self.assertEqual([2, 3, 4, 5, 6], -- expr.evaluate({'numbers': range(5), 'offset': 2})) -+ expr.evaluate({'numbers': list(range(5)), 'offset': 2})) - - expr = Expression("[n for group in groups for n in group]") - self.assertEqual([0, 1, 0, 1, 2], -- expr.evaluate({'groups': [range(2), range(3)]})) -+ expr.evaluate({'groups': [list(range(2)), list(range(3))]})) - - expr = Expression("[(a, b) for a in x for b in y]") - self.assertEqual([('x0', 'y0'), ('x0', 'y1'), ('x1', 'y0'), ('x1', 'y1')], -@@ -298,19 +298,19 @@ class ExpressionTestCase(unittest.TestCase): - - def test_generator_expression(self): - expr = Expression("list(n for n in numbers if n < 2)") -- self.assertEqual([0, 1], expr.evaluate({'numbers': range(5)})) -+ self.assertEqual([0, 1], expr.evaluate({'numbers': list(range(5))})) - - expr = Expression("list((i, n + 1) for i, n in enumerate(numbers))") - self.assertEqual([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)], -- expr.evaluate({'numbers': range(5)})) -+ expr.evaluate({'numbers': list(range(5))})) - - expr = Expression("list(offset + n for n in numbers)") - self.assertEqual([2, 3, 4, 5, 6], -- expr.evaluate({'numbers': range(5), 'offset': 2})) -+ expr.evaluate({'numbers': list(range(5)), 'offset': 2})) - - expr = Expression("list(n for group in groups for n in group)") - self.assertEqual([0, 1, 0, 1, 2], -- expr.evaluate({'groups': [range(2), range(3)]})) -+ expr.evaluate({'groups': [list(range(2)), list(range(3))]})) - - expr = Expression("list((a, b) for a in x for b in y)") - self.assertEqual([('x0', 'y0'), ('x0', 'y1'), ('x1', 'y0'), ('x1', 'y1')], -@@ -334,29 +334,29 @@ class ExpressionTestCase(unittest.TestCase): - - def test_slice(self): - expr = Expression("numbers[0:2]") -- self.assertEqual([0, 1], expr.evaluate({'numbers': range(5)})) -+ self.assertEqual([0, 1], expr.evaluate({'numbers': list(range(5))})) - - def test_slice_with_vars(self): - expr = Expression("numbers[start:end]") -- self.assertEqual([0, 1], expr.evaluate({'numbers': range(5), 'start': 0, -+ self.assertEqual([0, 1], expr.evaluate({'numbers': list(range(5)), 'start': 0, - 'end': 2})) - - def test_slice_copy(self): - expr = Expression("numbers[:]") -- self.assertEqual([0, 1, 2, 3, 4], expr.evaluate({'numbers': range(5)})) -+ self.assertEqual([0, 1, 2, 3, 4], expr.evaluate({'numbers': list(range(5))})) - - def test_slice_stride(self): - expr = Expression("numbers[::stride]") -- self.assertEqual([0, 2, 4], expr.evaluate({'numbers': range(5), -+ self.assertEqual([0, 2, 4], expr.evaluate({'numbers': list(range(5)), - 'stride': 2})) - - def test_slice_negative_start(self): - expr = Expression("numbers[-1:]") -- self.assertEqual([4], expr.evaluate({'numbers': range(5)})) -+ self.assertEqual([4], expr.evaluate({'numbers': list(range(5))})) - - def test_slice_negative_end(self): - expr = Expression("numbers[:-1]") -- self.assertEqual([0, 1, 2, 3], expr.evaluate({'numbers': range(5)})) -+ self.assertEqual([0, 1, 2, 3], expr.evaluate({'numbers': list(range(5))})) - - def test_access_undefined(self): - expr = Expression("nothing", filename='index.html', lineno=50, -@@ -416,7 +416,7 @@ class ExpressionTestCase(unittest.TestCase): - try: - expr.evaluate({}) - self.fail('Expected UndefinedError') -- except UndefinedError, e: -+ except UndefinedError as e: - exc_type, exc_value, exc_traceback = sys.exc_info() - frame = exc_traceback.tb_next - frames = [] -@@ -439,7 +439,7 @@ class ExpressionTestCase(unittest.TestCase): - try: - expr.evaluate({'something': Something()}) - self.fail('Expected UndefinedError') -- except UndefinedError, e: -+ except UndefinedError as e: - self.assertEqual(' has no member named "nil"', str(e)) - exc_type, exc_value, exc_traceback = sys.exc_info() - search_string = "" -@@ -463,7 +463,7 @@ class ExpressionTestCase(unittest.TestCase): - try: - expr.evaluate({'something': Something()}) - self.fail('Expected UndefinedError') -- except UndefinedError, e: -+ except UndefinedError as e: - self.assertEqual(' has no member named "nil"', str(e)) - exc_type, exc_value, exc_traceback = sys.exc_info() - search_string = '''''' -@@ -834,12 +834,12 @@ assert f() == 42 - self.attr = 'foo' - obj = Something() - Suite("del obj.attr").execute({'obj': obj}) -- self.failIf(hasattr(obj, 'attr')) -+ self.assertFalse(hasattr(obj, 'attr')) - - def test_delitem(self): - d = {'k': 'foo'} - Suite("del d['k']").execute({'d': d}) -- self.failIf('k' in d, repr(d)) -+ self.assertFalse('k' in d, repr(d)) - - if sys.version_info >= (2, 5): - def test_with_statement(self): ---- genshi/template/tests/interpolation.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/tests/interpolation.py -@@ -131,7 +131,7 @@ class InterpolateTestCase(unittest.TestCase): - def test_interpolate_full_mismatched_brackets(self): - try: - list(interpolate('${{1:2}')) -- except TemplateSyntaxError, e: -+ except TemplateSyntaxError as e: - pass - else: - self.fail('Expected TemplateSyntaxError') ---- genshi/template/tests/loader.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/tests/loader.py -@@ -372,7 +372,7 @@ class TemplateLoaderTestCase(unittest.TestCase): - def test_load_with_default_encoding(self): - f = open(os.path.join(self.dirname, 'tmpl.html'), 'wb') - try: -- f.write(u'
\xf6
'.encode('iso-8859-1')) -+ f.write('
\xf6
'.encode('iso-8859-1')) - finally: - f.close() - loader = TemplateLoader([self.dirname], default_encoding='iso-8859-1') -@@ -381,7 +381,7 @@ class TemplateLoaderTestCase(unittest.TestCase): - def test_load_with_explicit_encoding(self): - f = open(os.path.join(self.dirname, 'tmpl.html'), 'wb') - try: -- f.write(u'
\xf6
'.encode('iso-8859-1')) -+ f.write('
\xf6
'.encode('iso-8859-1')) - finally: - f.close() - loader = TemplateLoader([self.dirname], default_encoding='utf-8') ---- genshi/template/tests/markup.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/tests/markup.py -@@ -83,7 +83,7 @@ class MarkupTemplateTestCase(unittest.TestCase): - xml = '

' - try: - tmpl = MarkupTemplate(xml, filename='test.html') -- except BadDirectiveError, e: -+ except BadDirectiveError as e: - self.assertEqual('test.html', e.filename) - self.assertEqual(1, e.lineno) - -@@ -92,7 +92,7 @@ class MarkupTemplateTestCase(unittest.TestCase): - try: - tmpl = MarkupTemplate(xml, filename='test.html').generate() - self.fail('Expected TemplateSyntaxError') -- except TemplateSyntaxError, e: -+ except TemplateSyntaxError as e: - self.assertEqual('test.html', e.filename) - self.assertEqual(1, e.lineno) - -@@ -103,7 +103,7 @@ class MarkupTemplateTestCase(unittest.TestCase): - try: - tmpl = MarkupTemplate(xml, filename='test.html') - self.fail('Expected TemplateSyntaxError') -- except TemplateSyntaxError, e: -+ except TemplateSyntaxError as e: - self.assertEqual('test.html', e.filename) - self.assertEqual(2, e.lineno) - -@@ -116,7 +116,7 @@ class MarkupTemplateTestCase(unittest.TestCase): - try: - tmpl = MarkupTemplate(xml, filename='test.html') - self.fail('Expected TemplateSyntaxError') -- except TemplateSyntaxError, e: -+ except TemplateSyntaxError as e: - self.assertEqual('test.html', e.filename) - self.assertEqual(3, e.lineno) - -@@ -190,21 +190,21 @@ class MarkupTemplateTestCase(unittest.TestCase): -

""", str(tmpl.generate())) - - def test_latin1_encoded_with_xmldecl(self): -- tmpl = MarkupTemplate(u""" -+ tmpl = MarkupTemplate(""" -
- \xf6 -
""".encode('iso-8859-1'), encoding='iso-8859-1') -- self.assertEqual(u"""\n
-+ self.assertEqual("""\n
- \xf6 --
""", unicode(tmpl.generate())) -+
""", str(tmpl.generate())) - - def test_latin1_encoded_explicit_encoding(self): -- tmpl = MarkupTemplate(u"""
-+ tmpl = MarkupTemplate("""
- \xf6 -
""".encode('iso-8859-1'), encoding='iso-8859-1') -- self.assertEqual(u"""
-+ self.assertEqual("""
- \xf6 --
""", unicode(tmpl.generate())) -+
""", str(tmpl.generate())) - - def test_exec_with_trailing_space(self): - """ -@@ -619,7 +619,7 @@ class MarkupTemplateTestCase(unittest.TestCase): - tmpl = MarkupTemplate(xml, filename='test.html', - allow_exec=False) - self.fail('Expected SyntaxError') -- except TemplateSyntaxError, e: -+ except TemplateSyntaxError as e: - pass - - def test_allow_exec_true(self): ---- genshi/template/tests/plugin.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/tests/plugin.py -@@ -165,7 +165,7 @@ class MarkupTemplateEnginePluginTestCase(unittest.Test - def test_helper_functions(self): - plugin = MarkupTemplateEnginePlugin() - tmpl = plugin.load_template(PACKAGE + '.templates.functions') -- output = plugin.render({'snippet': u'Foo'}, template=tmpl) -+ output = plugin.render({'snippet': 'Foo'}, template=tmpl) - self.assertEqual("""
- False - bar ---- genshi/template/tests/text.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/tests/text.py -@@ -52,15 +52,15 @@ class OldTextTemplateTestCase(unittest.TestCase): - self.assertEqual('\n', tmpl.generate(foo=False).render(encoding=None)) - - def test_latin1_encoded(self): -- text = u'$foo\xf6$bar'.encode('iso-8859-1') -+ text = '$foo\xf6$bar'.encode('iso-8859-1') - tmpl = OldTextTemplate(text, encoding='iso-8859-1') -- self.assertEqual(u'x\xf6y', -+ self.assertEqual('x\xf6y', - tmpl.generate(foo='x', bar='y').render(encoding=None)) - - def test_unicode_input(self): -- text = u'$foo\xf6$bar' -+ text = '$foo\xf6$bar' - tmpl = OldTextTemplate(text) -- self.assertEqual(u'x\xf6y', -+ self.assertEqual('x\xf6y', - tmpl.generate(foo='x', bar='y').render(encoding=None)) - - def test_empty_lines1(self): -@@ -74,7 +74,7 @@ class OldTextTemplateTestCase(unittest.TestCase): - * 0 - * 1 - * 2 --""", tmpl.generate(items=range(3)).render(encoding=None)) -+""", tmpl.generate(items=list(range(3))).render(encoding=None)) - - def test_empty_lines2(self): - tmpl = OldTextTemplate("""Your items: -@@ -91,18 +91,18 @@ class OldTextTemplateTestCase(unittest.TestCase): - - * 2 - --""", tmpl.generate(items=range(3)).render(encoding=None)) -+""", tmpl.generate(items=list(range(3))).render(encoding=None)) - - def test_include(self): - file1 = open(os.path.join(self.dirname, 'tmpl1.txt'), 'wb') - try: -- file1.write(u"Included\n".encode("utf-8")) -+ file1.write("Included\n".encode("utf-8")) - finally: - file1.close() - - file2 = open(os.path.join(self.dirname, 'tmpl2.txt'), 'wb') - try: -- file2.write(u"""----- Included data below this line ----- -+ file2.write("""----- Included data below this line ----- - #include tmpl1.txt - ----- Included data above this line -----""".encode("utf-8")) - finally: -@@ -147,15 +147,15 @@ class NewTextTemplateTestCase(unittest.TestCase): - self.assertEqual('\n', tmpl.generate(foo=False).render(encoding=None)) - - def test_latin1_encoded(self): -- text = u'$foo\xf6$bar'.encode('iso-8859-1') -+ text = '$foo\xf6$bar'.encode('iso-8859-1') - tmpl = NewTextTemplate(text, encoding='iso-8859-1') -- self.assertEqual(u'x\xf6y', -+ self.assertEqual('x\xf6y', - tmpl.generate(foo='x', bar='y').render(encoding=None)) - - def test_unicode_input(self): -- text = u'$foo\xf6$bar' -+ text = '$foo\xf6$bar' - tmpl = NewTextTemplate(text) -- self.assertEqual(u'x\xf6y', -+ self.assertEqual('x\xf6y', - tmpl.generate(foo='x', bar='y').render(encoding=None)) - - def test_empty_lines1(self): -@@ -169,7 +169,7 @@ class NewTextTemplateTestCase(unittest.TestCase): - * 0 - * 1 - * 2 --""", tmpl.generate(items=range(3)).render(encoding=None)) -+""", tmpl.generate(items=list(range(3))).render(encoding=None)) - - def test_empty_lines1_with_crlf(self): - tmpl = NewTextTemplate('Your items:\r\n' -@@ -182,7 +182,7 @@ class NewTextTemplateTestCase(unittest.TestCase): - '\r\n' - ' * 0\r\n' - ' * 1\r\n' --' * 2\r\n', tmpl.generate(items=range(3)).render(encoding=None)) -+' * 2\r\n', tmpl.generate(items=list(range(3))).render(encoding=None)) - - def test_empty_lines2(self): - tmpl = NewTextTemplate("""Your items: -@@ -199,7 +199,7 @@ class NewTextTemplateTestCase(unittest.TestCase): - - * 2 - --""", tmpl.generate(items=range(3)).render(encoding=None)) -+""", tmpl.generate(items=list(range(3))).render(encoding=None)) - - def test_empty_lines2_with_crlf(self): - tmpl = NewTextTemplate('Your items:\r\n' -@@ -215,7 +215,7 @@ class NewTextTemplateTestCase(unittest.TestCase): - ' * 1\r\n' - '\r\n' - ' * 2\r\n' --'\r\n', tmpl.generate(items=range(3)).render(encoding=None)) -+'\r\n', tmpl.generate(items=list(range(3))).render(encoding=None)) - - def test_exec_with_trailing_space(self): - """ -@@ -250,13 +250,13 @@ class NewTextTemplateTestCase(unittest.TestCase): - def test_include(self): - file1 = open(os.path.join(self.dirname, 'tmpl1.txt'), 'wb') - try: -- file1.write(u"Included".encode("utf-8")) -+ file1.write("Included".encode("utf-8")) - finally: - file1.close() - - file2 = open(os.path.join(self.dirname, 'tmpl2.txt'), 'wb') - try: -- file2.write(u"""----- Included data below this line ----- -+ file2.write("""----- Included data below this line ----- - {% include tmpl1.txt %} - ----- Included data above this line -----""".encode("utf-8")) - finally: -@@ -272,13 +272,13 @@ Included - def test_include_expr(self): - file1 = open(os.path.join(self.dirname, 'tmpl1.txt'), 'wb') - try: -- file1.write(u"Included".encode("utf-8")) -+ file1.write("Included".encode("utf-8")) - finally: - file1.close() - - file2 = open(os.path.join(self.dirname, 'tmpl2.txt'), 'wb') - try: -- file2.write(u"""----- Included data below this line ----- -+ file2.write("""----- Included data below this line ----- - {% include ${'%s.txt' % ('tmpl1',)} %} - ----- Included data above this line -----""".encode("utf-8")) - finally: ---- genshi/template/text.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/template/text.py -@@ -162,7 +162,7 @@ class NewTextTemplate(Template): - depth = 0 - - source = source.read() -- if not isinstance(source, unicode): -+ if not isinstance(source, str): - source = source.decode(encoding or 'utf-8', 'replace') - offset = 0 - lineno = 1 -@@ -201,7 +201,7 @@ class NewTextTemplate(Template): - try: - suite = Suite(value, self.filepath, lineno, - lookup=self.lookup) -- except SyntaxError, err: -+ except SyntaxError as err: - raise TemplateSyntaxError(err, self.filepath, - lineno + (err.lineno or 1) - 1) - pos = (self.filename, lineno, 0) -@@ -279,7 +279,7 @@ class OldTextTemplate(Template): - depth = 0 - - source = source.read() -- if not isinstance(source, unicode): -+ if not isinstance(source, str): - source = source.decode(encoding or 'utf-8', 'replace') - offset = 0 - lineno = 1 ---- genshi/tests/core.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/tests/core.py -@@ -25,28 +25,28 @@ class StreamTestCase(unittest.TestCase): - - def test_render_utf8(self): - xml = XML('
  • Über uns
  • ') -- self.assertEqual(u'
  • Über uns
  • '.encode('utf-8'), xml.render(encoding='utf-8')) -+ self.assertEqual('
  • Über uns
  • '.encode('utf-8'), xml.render(encoding='utf-8')) - - def test_render_unicode(self): - xml = XML('
  • Über uns
  • ') -- self.assertEqual(u'
  • Über uns
  • ', xml.render()) -- self.assertEqual(u'
  • Über uns
  • ', xml.render(encoding=None)) -+ self.assertEqual('
  • Über uns
  • ', xml.render()) -+ self.assertEqual('
  • Über uns
  • ', xml.render(encoding=None)) - - def test_render_ascii(self): - xml = XML('
  • Über uns
  • ') -- self.assertEqual(u'
  • Über uns
  • '.encode('ascii'), xml.render(encoding='ascii')) -+ self.assertEqual('
  • Über uns
  • '.encode('ascii'), xml.render(encoding='ascii')) - - def test_render_output_stream_utf8(self): - xml = XML('
  • Über uns
  • ') - strio = BytesIO() - self.assertEqual(None, xml.render(encoding='utf-8', out=strio)) -- self.assertEqual(u'
  • Über uns
  • '.encode('utf-8'), strio.getvalue()) -+ self.assertEqual('
  • Über uns
  • '.encode('utf-8'), strio.getvalue()) - - def test_render_output_stream_unicode(self): - xml = XML('
  • Über uns
  • ') - strio = StringIO() - self.assertEqual(None, xml.render(encoding=None, out=strio)) -- self.assertEqual(u'
  • Über uns
  • ', strio.getvalue()) -+ self.assertEqual('
  • Über uns
  • ', strio.getvalue()) - - def test_pickle(self): - xml = XML('
  • Foo
  • ') -@@ -54,122 +54,122 @@ class StreamTestCase(unittest.TestCase): - pickle.dump(xml, buf, 2) - buf.seek(0) - xml = pickle.load(buf) -- self.assertEquals('
  • Foo
  • ', xml.render(encoding=None)) -+ self.assertEqual('
  • Foo
  • ', xml.render(encoding=None)) - - - class MarkupTestCase(unittest.TestCase): - - def test_new_with_encoding(self): -- markup = Markup(u'Döner'.encode('utf-8'), encoding='utf-8') -+ markup = Markup('Döner'.encode('utf-8'), encoding='utf-8') - # mimic Markup.__repr__ when constructing output for Python 2/3 compatibility -- self.assertEquals("" % u'D\u00f6ner', repr(markup)) -+ self.assertEqual("" % 'D\u00f6ner', repr(markup)) - - def test_repr(self): - markup = Markup('foo') -- self.assertEquals("", repr(markup)) -+ self.assertEqual("", repr(markup)) - - def test_escape(self): - markup = escape('"&"') - assert type(markup) is Markup -- self.assertEquals('<b>"&"</b>', markup) -+ self.assertEqual('<b>"&"</b>', markup) - - def test_escape_noquotes(self): - markup = escape('"&"', quotes=False) - assert type(markup) is Markup -- self.assertEquals('<b>"&"</b>', markup) -+ self.assertEqual('<b>"&"</b>', markup) - - def test_unescape_markup(self): - string = '"&"' - markup = Markup.escape(string) - assert type(markup) is Markup -- self.assertEquals(string, unescape(markup)) -+ self.assertEqual(string, unescape(markup)) - - def test_Markup_escape_None_noquotes(self): - markup = Markup.escape(None, False) - assert type(markup) is Markup -- self.assertEquals('', markup) -+ self.assertEqual('', markup) - - def test_add_str(self): - markup = Markup('foo') + '
    ' - assert type(markup) is Markup -- self.assertEquals('foo<br/>', markup) -+ self.assertEqual('foo<br/>', markup) - - def test_add_markup(self): - markup = Markup('foo') + Markup('
    ') - assert type(markup) is Markup -- self.assertEquals('foo
    ', markup) -+ self.assertEqual('foo
    ', markup) - - def test_add_reverse(self): - markup = '
    ' + Markup('bar') - assert type(markup) is Markup -- self.assertEquals('<br/>bar', markup) -+ self.assertEqual('<br/>bar', markup) - - def test_mod(self): - markup = Markup('%s') % '&' - assert type(markup) is Markup -- self.assertEquals('&', markup) -+ self.assertEqual('&', markup) - - def test_mod_multi(self): - markup = Markup('%s %s') % ('&', 'boo') - assert type(markup) is Markup -- self.assertEquals('& boo', markup) -+ self.assertEqual('& boo', markup) - - def test_mod_mapping(self): - markup = Markup('%(foo)s') % {'foo': '&'} - assert type(markup) is Markup -- self.assertEquals('&', markup) -+ self.assertEqual('&', markup) - - def test_mod_noescape(self): - markup = Markup('%(amp)s') % {'amp': Markup('&')} - assert type(markup) is Markup -- self.assertEquals('&', markup) -+ self.assertEqual('&', markup) - - def test_mul(self): - markup = Markup('foo') * 2 - assert type(markup) is Markup -- self.assertEquals('foofoo', markup) -+ self.assertEqual('foofoo', markup) - - def test_mul_reverse(self): - markup = 2 * Markup('foo') - assert type(markup) is Markup -- self.assertEquals('foofoo', markup) -+ self.assertEqual('foofoo', markup) - - def test_join(self): - markup = Markup('
    ').join(['foo', '', Markup('')]) - assert type(markup) is Markup -- self.assertEquals('foo
    <bar />
    ', markup) -+ self.assertEqual('foo
    <bar />
    ', markup) - - def test_join_over_iter(self): - items = ['foo', '', Markup('')] - markup = Markup('
    ').join(i for i in items) -- self.assertEquals('foo
    <bar />
    ', markup) -+ self.assertEqual('foo
    <bar />
    ', markup) - - def test_stripentities_all(self): - markup = Markup('& j').stripentities() - assert type(markup) is Markup -- self.assertEquals('& j', markup) -+ self.assertEqual('& j', markup) - - def test_stripentities_keepxml(self): - markup = Markup('& j').stripentities(keepxmlentities=True) - assert type(markup) is Markup -- self.assertEquals('& j', markup) -+ self.assertEqual('& j', markup) - - def test_striptags_empty(self): - markup = Markup('
    ').striptags() - assert type(markup) is Markup -- self.assertEquals('', markup) -+ self.assertEqual('', markup) - - def test_striptags_mid(self): - markup = Markup('fo
    o
    ').striptags() - assert type(markup) is Markup -- self.assertEquals('foo', markup) -+ self.assertEqual('foo', markup) - - def test_pickle(self): - markup = Markup('foo') - buf = BytesIO() - pickle.dump(markup, buf, 2) - buf.seek(0) -- self.assertEquals("", repr(pickle.load(buf))) -+ self.assertEqual("", repr(pickle.load(buf))) - - - class AttrsTestCase(unittest.TestCase): -@@ -180,12 +180,12 @@ class AttrsTestCase(unittest.TestCase): - pickle.dump(attrs, buf, 2) - buf.seek(0) - unpickled = pickle.load(buf) -- self.assertEquals("Attrs([('attr1', 'foo'), ('attr2', 'bar')])", -+ self.assertEqual("Attrs([('attr1', 'foo'), ('attr2', 'bar')])", - repr(unpickled)) - - def test_non_ascii(self): -- attrs_tuple = Attrs([("attr1", u"föö"), ("attr2", u"bär")]).totuple() -- self.assertEqual(u'fööbär', attrs_tuple[1]) -+ attrs_tuple = Attrs([("attr1", "föö"), ("attr2", "bär")]).totuple() -+ self.assertEqual('fööbär', attrs_tuple[1]) - - - class NamespaceTestCase(unittest.TestCase): -@@ -199,7 +199,7 @@ class NamespaceTestCase(unittest.TestCase): - self.assertEqual(eval(repr(ns)), ns) - - def test_repr_eval_non_ascii(self): -- ns = Namespace(u'http://www.example.org/nämespäcé') -+ ns = Namespace('http://www.example.org/nämespäcé') - self.assertEqual(eval(repr(ns)), ns) - - def test_pickle(self): -@@ -208,9 +208,9 @@ class NamespaceTestCase(unittest.TestCase): - pickle.dump(ns, buf, 2) - buf.seek(0) - unpickled = pickle.load(buf) -- self.assertEquals("Namespace('http://www.example.org/namespace')", -+ self.assertEqual("Namespace('http://www.example.org/namespace')", - repr(unpickled)) -- self.assertEquals('http://www.example.org/namespace', unpickled.uri) -+ self.assertEqual('http://www.example.org/namespace', unpickled.uri) - - - class QNameTestCase(unittest.TestCase): -@@ -221,10 +221,10 @@ class QNameTestCase(unittest.TestCase): - pickle.dump(qname, buf, 2) - buf.seek(0) - unpickled = pickle.load(buf) -- self.assertEquals('{http://www.example.org/namespace}elem', unpickled) -- self.assertEquals('http://www.example.org/namespace', -+ self.assertEqual('{http://www.example.org/namespace}elem', unpickled) -+ self.assertEqual('http://www.example.org/namespace', - unpickled.namespace) -- self.assertEquals('elem', unpickled.localname) -+ self.assertEqual('elem', unpickled.localname) - - def test_repr(self): - self.assertEqual("QName('elem')", repr(QName('elem'))) -@@ -236,13 +236,13 @@ class QNameTestCase(unittest.TestCase): - self.assertEqual(eval(repr(qn)), qn) - - def test_repr_eval_non_ascii(self): -- qn = QName(u'élem') -+ qn = QName('élem') - self.assertEqual(eval(repr(qn)), qn) - - def test_leading_curly_brace(self): - qname = QName('{http://www.example.org/namespace}elem') -- self.assertEquals('http://www.example.org/namespace', qname.namespace) -- self.assertEquals('elem', qname.localname) -+ self.assertEqual('http://www.example.org/namespace', qname.namespace) -+ self.assertEqual('elem', qname.localname) - - def test_curly_brace_equality(self): - qname1 = QName('{http://www.example.org/namespace}elem') ---- genshi/tests/input.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/tests/input.py -@@ -51,27 +51,27 @@ bar''' - self.assertEqual(('class', 'bar'), attrib[2]) - - def test_unicode_input(self): -- text = u'
    \u2013
    ' -+ text = '
    \u2013
    ' - events = list(XMLParser(StringIO(text))) - kind, data, pos = events[1] - self.assertEqual(Stream.TEXT, kind) -- self.assertEqual(u'\u2013', data) -+ self.assertEqual('\u2013', data) - - def test_latin1_encoded(self): -- text = u'
    \xf6
    '.encode('iso-8859-1') -+ text = '
    \xf6
    '.encode('iso-8859-1') - events = list(XMLParser(BytesIO(text), encoding='iso-8859-1')) - kind, data, pos = events[1] - self.assertEqual(Stream.TEXT, kind) -- self.assertEqual(u'\xf6', data) -+ self.assertEqual('\xf6', data) - - def test_latin1_encoded_xmldecl(self): -- text = u""" -+ text = """ -
    \xf6
    - """.encode('iso-8859-1') - events = list(XMLParser(BytesIO(text))) - kind, data, pos = events[2] - self.assertEqual(Stream.TEXT, kind) -- self.assertEqual(u'\xf6', data) -+ self.assertEqual('\xf6', data) - - def test_html_entity_with_dtd(self): - text = """''' - events = list(XMLParser(StringIO(text))) - kind, data, pos = events[2] - self.assertEqual(Stream.TEXT, kind) -- self.assertEqual(u'\xa0', data) -+ self.assertEqual('\xa0', data) - - def test_html_entity_without_dtd(self): - text = ' ' - events = list(XMLParser(StringIO(text))) - kind, data, pos = events[1] - self.assertEqual(Stream.TEXT, kind) -- self.assertEqual(u'\xa0', data) -+ self.assertEqual('\xa0', data) - - def test_html_entity_in_attribute(self): - text = '

    ' - events = list(XMLParser(StringIO(text))) - kind, data, pos = events[0] - self.assertEqual(Stream.START, kind) -- self.assertEqual(u'\xa0', data[1].get('title')) -+ self.assertEqual('\xa0', data[1].get('title')) - kind, data, pos = events[1] - self.assertEqual(Stream.END, kind) - -@@ -116,7 +116,7 @@ bar''' - class HTMLParserTestCase(unittest.TestCase): - - def test_text_node_pos_single_line(self): -- text = u'foo bar' -+ text = 'foo bar' - events = list(HTMLParser(StringIO(text))) - kind, data, pos = events[1] - self.assertEqual(Stream.TEXT, kind) -@@ -124,7 +124,7 @@ class HTMLParserTestCase(unittest.TestCase): - self.assertEqual((None, 1, 6), pos) - - def test_text_node_pos_multi_line(self): -- text = u'''foo -+ text = '''foo - bar''' - events = list(HTMLParser(StringIO(text))) - kind, data, pos = events[1] -@@ -133,44 +133,44 @@ bar''' - self.assertEqual((None, 1, 6), pos) - - def test_input_encoding_text(self): -- text = u'

    \xf6
    '.encode('iso-8859-1') -+ text = '
    \xf6
    '.encode('iso-8859-1') - events = list(HTMLParser(BytesIO(text), encoding='iso-8859-1')) - kind, data, pos = events[1] - self.assertEqual(Stream.TEXT, kind) -- self.assertEqual(u'\xf6', data) -+ self.assertEqual('\xf6', data) - - def test_input_encoding_attribute(self): -- text = u'
    '.encode('iso-8859-1') -+ text = '
    '.encode('iso-8859-1') - events = list(HTMLParser(BytesIO(text), encoding='iso-8859-1')) - kind, (tag, attrib), pos = events[0] - self.assertEqual(Stream.START, kind) -- self.assertEqual(u'\xf6', attrib.get('title')) -+ self.assertEqual('\xf6', attrib.get('title')) - - def test_unicode_input(self): -- text = u'
    \u2013
    ' -+ text = '
    \u2013
    ' - events = list(HTMLParser(StringIO(text))) - kind, data, pos = events[1] - self.assertEqual(Stream.TEXT, kind) -- self.assertEqual(u'\u2013', data) -+ self.assertEqual('\u2013', data) - - def test_html_entity_in_attribute(self): -- text = u'

    ' -+ text = '

    ' - events = list(HTMLParser(StringIO(text))) - kind, data, pos = events[0] - self.assertEqual(Stream.START, kind) -- self.assertEqual(u'\xa0', data[1].get('title')) -+ self.assertEqual('\xa0', data[1].get('title')) - kind, data, pos = events[1] - self.assertEqual(Stream.END, kind) - - def test_html_entity_in_text(self): -- text = u'

     

    ' -+ text = '

     

    ' - events = list(HTMLParser(StringIO(text))) - kind, data, pos = events[1] - self.assertEqual(Stream.TEXT, kind) -- self.assertEqual(u'\xa0', data) -+ self.assertEqual('\xa0', data) - - def test_processing_instruction(self): -- text = u'' -+ text = '' - events = list(HTMLParser(StringIO(text))) - kind, (target, data), pos = events[0] - self.assertEqual(Stream.PI, kind) -@@ -178,7 +178,7 @@ bar''' - self.assertEqual('echo "Foobar"', data) - - def test_processing_instruction_no_data_1(self): -- text = u'' -+ text = '' - events = list(HTMLParser(StringIO(text))) - kind, (target, data), pos = events[0] - self.assertEqual(Stream.PI, kind) -@@ -186,7 +186,7 @@ bar''' - self.assertEqual('', data) - - def test_processing_instruction_no_data_2(self): -- text = u'...' -+ text = '...' - events = list(HTMLParser(StringIO(text))) - kind, (target, data), pos = events[0] - self.assertEqual(Stream.PI, kind) -@@ -224,7 +224,7 @@ bar''' - self.assertEqual(1, standalone) - - def test_processing_instruction_trailing_qmark(self): -- text = u'' -+ text = '' - events = list(HTMLParser(StringIO(text))) - kind, (target, data), pos = events[0] - self.assertEqual(Stream.PI, kind) -@@ -232,7 +232,7 @@ bar''' - self.assertEqual('echo "Foobar" ?', data) - - def test_out_of_order_tags1(self): -- text = u'Foobar' -+ text = 'Foobar' - events = list(HTMLParser(StringIO(text))) - self.assertEqual(5, len(events)) - self.assertEqual((Stream.START, ('span', ())), events[0][:2]) -@@ -242,7 +242,7 @@ bar''' - self.assertEqual((Stream.END, 'span'), events[4][:2]) - - def test_out_of_order_tags2(self): -- text = u'Foobar'.encode('utf-8') -+ text = 'Foobar'.encode('utf-8') - events = list(HTMLParser(BytesIO(text), encoding='utf-8')) - self.assertEqual(7, len(events)) - self.assertEqual((Stream.START, ('span', Attrs([('class', 'baz')]))), -@@ -255,7 +255,7 @@ bar''' - self.assertEqual((Stream.END, 'span'), events[6][:2]) - - def test_out_of_order_tags3(self): -- text = u'Foobar'.encode('utf-8') -+ text = 'Foobar'.encode('utf-8') - events = list(HTMLParser(BytesIO(text), encoding='utf-8')) - self.assertEqual(5, len(events)) - self.assertEqual((Stream.START, ('span', ())), events[0][:2]) -@@ -265,7 +265,7 @@ bar''' - self.assertEqual((Stream.END, 'span'), events[4][:2]) - - def test_hex_charref(self): -- text = u''' -+ text = ''' - events = list(HTMLParser(StringIO(text))) - self.assertEqual(3, len(events)) - self.assertEqual((Stream.START, ('span', ())), events[0][:2]) -@@ -273,7 +273,7 @@ bar''' - self.assertEqual((Stream.END, 'span'), events[2][:2]) - - def test_multibyte_character_on_chunk_boundary(self): -- text = u'a' * ((4 * 1024) - 1) + u'\xe6' -+ text = 'a' * ((4 * 1024) - 1) + '\xe6' - events = list(HTMLParser(BytesIO(text.encode('utf-8')), - encoding='utf-8')) - self.assertEqual(1, len(events)) ---- genshi/tests/output.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/tests/output.py -@@ -356,7 +356,7 @@ class XHTMLSerializerTestCase(unittest.TestCase): -
    """, output) - - def test_html5_doctype(self): -- stream = HTML(u'') -+ stream = HTML('') - output = stream.render(XHTMLSerializer, doctype=DocType.HTML5, - encoding=None) - self.assertEqual('\n', output) -@@ -369,7 +369,7 @@ class XHTMLSerializerTestCase(unittest.TestCase): - def test_cache_markup(self): - loc = (None, -1, -1) - stream = Stream([(Stream.START, (QName('foo'), Attrs()), loc), -- (Stream.TEXT, u'…', loc), -+ (Stream.TEXT, '…', loc), - (Stream.END, QName('foo'), loc), - (Stream.START, (QName('bar'), Attrs()), loc), - (Stream.TEXT, Markup('…'), loc), -@@ -444,7 +444,7 @@ class HTMLSerializerTestCase(unittest.TestCase): - """, output) - - def test_html5_doctype(self): -- stream = HTML(u'') -+ stream = HTML('') - output = stream.render(HTMLSerializer, doctype=DocType.HTML5, - encoding=None) - self.assertEqual('\n', output) ---- genshi/tests/path.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/tests/path.py -@@ -636,7 +636,7 @@ class PathTestCase(unittest.TestCase): - path = Path('foo/@bar') - result = path.select(xml) - self.assertEqual(list(result), [ -- Attrs([(QName('bar'), u'abc')]) -+ Attrs([(QName('bar'), 'abc')]) - ]) - - def test_attr_selection_with_namespace(self): -@@ -647,7 +647,7 @@ class PathTestCase(unittest.TestCase): - path = Path('foo/@ns1:bar') - result = path.select(xml, namespaces={'ns1': 'http://example.com'}) - self.assertEqual(list(result), [ -- Attrs([(QName('http://example.com}bar'), u'abc')]) -+ Attrs([(QName('http://example.com}bar'), 'abc')]) - ]) - - def _test_support(self, strategy_class, text): -@@ -655,21 +655,21 @@ class PathTestCase(unittest.TestCase): - return strategy_class.supports(path) - - def test_simple_strategy_support(self): -- self.assert_(self._test_support(SimplePathStrategy, 'a/b')) -- self.assert_(self._test_support(SimplePathStrategy, 'self::a/b')) -- self.assert_(self._test_support(SimplePathStrategy, 'descendant::a/b')) -- self.assert_(self._test_support(SimplePathStrategy, -+ self.assertTrue(self._test_support(SimplePathStrategy, 'a/b')) -+ self.assertTrue(self._test_support(SimplePathStrategy, 'self::a/b')) -+ self.assertTrue(self._test_support(SimplePathStrategy, 'descendant::a/b')) -+ self.assertTrue(self._test_support(SimplePathStrategy, - 'descendant-or-self::a/b')) -- self.assert_(self._test_support(SimplePathStrategy, '//a/b')) -- self.assert_(self._test_support(SimplePathStrategy, 'a/@b')) -- self.assert_(self._test_support(SimplePathStrategy, 'a/text()')) -+ self.assertTrue(self._test_support(SimplePathStrategy, '//a/b')) -+ self.assertTrue(self._test_support(SimplePathStrategy, 'a/@b')) -+ self.assertTrue(self._test_support(SimplePathStrategy, 'a/text()')) - - # a//b is a/descendant-or-self::node()/b -- self.assert_(not self._test_support(SimplePathStrategy, 'a//b')) -- self.assert_(not self._test_support(SimplePathStrategy, 'node()/@a')) -- self.assert_(not self._test_support(SimplePathStrategy, '@a')) -- self.assert_(not self._test_support(SimplePathStrategy, 'foo:bar')) -- self.assert_(not self._test_support(SimplePathStrategy, 'a/@foo:bar')) -+ self.assertTrue(not self._test_support(SimplePathStrategy, 'a//b')) -+ self.assertTrue(not self._test_support(SimplePathStrategy, 'node()/@a')) -+ self.assertTrue(not self._test_support(SimplePathStrategy, '@a')) -+ self.assertTrue(not self._test_support(SimplePathStrategy, 'foo:bar')) -+ self.assertTrue(not self._test_support(SimplePathStrategy, 'a/@foo:bar')) - - def _test_strategies(self, input, path, output, - namespaces=None, variables=None): ---- genshi/util.py.orig 2019-05-27 21:03:08 UTC -+++ genshi/util.py -@@ -13,10 +13,10 @@ - - """Various utility classes and functions.""" - --import htmlentitydefs as entities -+import html.entities as entities - import re - --from compat import any, all, stringrepr -+from .compat import any, all, stringrepr - - __docformat__ = 'restructuredtext en' - -@@ -193,17 +193,17 @@ def stripentities(text, keepxmlentities=False): - >>> stripentities('1 < 2') - u'1 < 2' - >>> stripentities('more …') -- u'more \u2026' -+ u'more \\u2026' - >>> stripentities('…') -- u'\u2026' -+ u'\\u2026' - >>> stripentities('…') -- u'\u2026' -+ u'\\u2026' - - If the `keepxmlentities` parameter is provided and is a truth value, the - core XML entities (&, ', >, < and ") are left intact. - - >>> stripentities('1 < 2 …', keepxmlentities=True) -- u'1 < 2 \u2026' -+ u'1 < 2 \\u2026' - """ - def _replace_entity(match): - if match.group(1): # numeric entity -@@ -212,13 +212,13 @@ def stripentities(text, keepxmlentities=False): - ref = int(ref[1:], 16) - else: - ref = int(ref, 10) -- return unichr(ref) -+ return chr(ref) - else: # character entity - ref = match.group(2) - if keepxmlentities and ref in ('amp', 'apos', 'gt', 'lt', 'quot'): - return '&%s;' % ref - try: -- return unichr(entities.name2codepoint[ref]) -+ return chr(entities.name2codepoint[ref]) - except KeyError: - if keepxmlentities: - return '&%s;' % ref ---- scripts/ast_generator.py.orig 2019-05-27 21:03:08 UTC -+++ scripts/ast_generator.py -@@ -23,12 +23,12 @@ def print_class(cls): - bnames.append("%s" % base.__name__) - else: - bnames.append("%s.%s" % (base.__module__,base.__name__)) -- print("class %s(%s):" % (cls.__name__, ", ".join(bnames))) -+ print(("class %s(%s):" % (cls.__name__, ", ".join(bnames)))) - written = False - for attr in cls.__dict__: - if attr not in IGNORE_ATTRS: - written = True -- print("\t%s = %s" % (attr, repr(cls.__dict__[attr]),)) -+ print(("\t%s = %s" % (attr, repr(cls.__dict__[attr]),))) - if not written: - print("\tpass") - done.add(cls) -@@ -36,11 +36,11 @@ def print_class(cls): - print('# Generated automatically, please do not edit') - print('# Generator can be found in Genshi SVN, scripts/ast_generator.py') - print('') --print('__version__ = %s' % _ast.__version__) -+print(('__version__ = %s' % _ast.__version__)) - print('') - - for name in dir(_ast): - cls = getattr(_ast, name) - if cls.__class__ is type: - print_class(cls) -- print -+ print() ---- setup.py.orig 2019-05-27 21:03:08 UTC -+++ setup.py -@@ -93,12 +93,8 @@ if bdist_egg: - cmdclass['bdist_egg'] = my_bdist_egg - - --# Use 2to3 if we're running under Python 3 (with Distribute) - extra = {} - if sys.version_info >= (3,): -- extra['use_2to3'] = True -- extra['convert_2to3_doctests'] = [] -- extra['use_2to3_fixers'] = ['fixes'] - # Install genshi template tests - extra['include_package_data'] = True -