From nobody Mon Mar 07 18:27:24 2022
X-Original-To: dev-commits-ports-main@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: Commits to the main branch of the FreeBSD ports repository
List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-main
List-Help:
List-Post:
List-Subscribe:
List-Unsubscribe:
Sender: owner-dev-commits-ports-main@freebsd.org
X-BeenThere: dev-commits-ports-main@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 ***