From nobody Mon Mar 7 18:27:24 2022 X-Original-To: dev-commits-ports-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id B0DA61A0704E; Mon, 7 Mar 2022 18:27:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KC6Pp16SKz3h7g; Mon, 7 Mar 2022 18:27:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646677646; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=aFgDYOiqTbSD4JFCJqrWoubJTDi9vucwPynhHPG236c=; b=MQhvvp8bk2FWz7wlgF4+JpGOvpYOCqbkhHMooJ0xJCWIZURGmvtAqyhTpv0aoGzWCTVpyX sgNKkYUmvCwv+UKCbv6Xl0jjBvannrcYqzNAh+nT9HE8llVtbntk0lO166xXYoJPl/iX2/ BmDHvg3KWdY2ALpIZcLvaQ2zQQ0/hWKyatvQ9G8fqKnpY0gi3QSz3l5pDw7Y031bPuuGuH PUzl+R0cAsbUqxbaaR84u1cDKKWafbKvUtIwbUBa1PoAYlwsXFkVXRHIrkgpSKXiN7usmz 1yjE7oN0D6VZOMnEAGf2sZh/OUBUq3bdoiLoASodaZ+oiWzl+mu+8DjR3szy5w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3141A5910; Mon, 7 Mar 2022 18:27:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 227IRP6O085965; Mon, 7 Mar 2022 18:27:25 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 227IRO1F085964; Mon, 7 Mar 2022 18:27:24 GMT (envelope-from git) Date: Mon, 7 Mar 2022 18:27:24 GMT Message-Id: <202203071827.227IRO1F085964@gitrepo.freebsd.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: Po-Chuan Hsieh Subject: git: 86ae39175edc - main - textproc/py-genshi: Fix build with setuptools 58.0.0+ List-Id: Commit messages for all branches of the ports repository List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-ports-all@freebsd.org X-BeenThere: dev-commits-ports-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: sunpoet X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 86ae39175edc3d32e8aec35e374f9754cc607d31 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646677646; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=aFgDYOiqTbSD4JFCJqrWoubJTDi9vucwPynhHPG236c=; b=ntNkEzOM3xoq+u7ZS/rL9H2njP3W7XEzb9WTG4RDMWEFxb1YL8qoVQ5WqfIN5cch4W7rrr P/SbWFjJv/9M3Uj+AuANySuFFsn1oTyaI1ig8QqLichZcn71ME/Fkti9PXrF6LSgCqoFmi Ae3r6rIIj0bCeb4wcF+DI0an3hQUIHVfe5WMk6Rq3brfmp97rY0oKLdH+DNi24zCr0foe4 WoOYES9vC/0n+RduMSMEpq5zhSRKVqpx9HH1FfLsfcXQhRpgyn2fKz0YzMBJNo3jB7qRbO vwe/SW/x4N2v6ZnhXrUkVdjPSD94Ed7L5MQij0unGSppYsWDncuAi8prC6aV8A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1646677646; a=rsa-sha256; cv=none; b=XlcHHGX3kKXoHekg4KKwn7PkrFbNN0Mbjiy3e58xvNHEf1J3Tgs57zAwH9wqKLl/0fVrkJ 1QVQUGA/JT1UAAqh6LKKszMcKyUT5uhJf20w11qyOl1g0Y4AFQIstGkNT9F2nqAUrFhfU7 qx9Sl/lf09+VEMeTiUpOz7ZlajhTF4ArN6gnByjz1X/7zFPAr86RFPVR2qQMklX9xqLI/Y djboaduR/t05mgi6+HNgGkt389MzNlX2Q/2mhsmrscyqM29ROZVSuTqhqmDP6sV4djom3c u9f6V56080bFzew98am8BTTjE0B8Utb4oqRgaPxo92FGoHQbMdpnCWKfsPqe1Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by sunpoet: URL: https://cgit.FreeBSD.org/ports/commit/?id=86ae39175edc3d32e8aec35e374f9754cc607d31 commit 86ae39175edc3d32e8aec35e374f9754cc607d31 Author: Po-Chuan Hsieh AuthorDate: 2022-03-07 18:07:50 +0000 Commit: Po-Chuan Hsieh CommitDate: 2022-03-07 18:13:21 +0000 textproc/py-genshi: Fix build with setuptools 58.0.0+ With hat: python --- textproc/py-genshi/files/patch-2to3 | 5818 +++++++++++++++++++++++++++++++++++ 1 file changed, 5818 insertions(+) diff --git a/textproc/py-genshi/files/patch-2to3 b/textproc/py-genshi/files/patch-2to3 new file mode 100644 index 000000000000..1764fbffbda4 --- /dev/null +++ b/textproc/py-genshi/files/patch-2to3 @@ -0,0 +1,5818 @@ +--- 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: { *** 4854 LINES SKIPPED ***