git: f8e7edd70ae1 - main - www/py-nevow: Fix build with setuptools 58.0.0+
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 25 Mar 2022 13:51:15 UTC
The branch main has been updated by sunpoet:
URL: https://cgit.FreeBSD.org/ports/commit/?id=f8e7edd70ae17a158315534377ddc4be9814a8d6
commit f8e7edd70ae17a158315534377ddc4be9814a8d6
Author: Po-Chuan Hsieh <sunpoet@FreeBSD.org>
AuthorDate: 2022-03-25 13:35:15 +0000
Commit: Po-Chuan Hsieh <sunpoet@FreeBSD.org>
CommitDate: 2022-03-25 13:38:25 +0000
www/py-nevow: Fix build with setuptools 58.0.0+
With hat: python
---
www/py-nevow/files/patch-2to3 | 4233 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 4233 insertions(+)
diff --git a/www/py-nevow/files/patch-2to3 b/www/py-nevow/files/patch-2to3
new file mode 100644
index 000000000000..f669cb5b5eaa
--- /dev/null
+++ b/www/py-nevow/files/patch-2to3
@@ -0,0 +1,4233 @@
+--- formless/annotate.py.orig 2015-10-20 22:44:09 UTC
++++ formless/annotate.py
+@@ -22,11 +22,11 @@ from formless import iformless
+ class count(object):
+ def __init__(self):
+ self.id = 0
+- def next(self):
++ def __next__(self):
+ self.id += 1
+ return self.id
+
+-nextId = count().next
++nextId = count().__next__
+
+
+ class InputError(Exception):
+@@ -102,7 +102,7 @@ class Typed(Attribute):
+ required = False
+ requiredFailMessage = 'Please enter a value'
+ null = None
+- unicode = False
++ str = False
+
+ __name__ = ''
+
+@@ -114,7 +114,7 @@ class Typed(Attribute):
+ required=None,
+ requiredFailMessage=None,
+ null=None,
+- unicode=None,
++ str=None,
+ **attributes):
+
+ self.id = nextId()
+@@ -130,15 +130,15 @@ class Typed(Attribute):
+ self.requiredFailMessage = requiredFailMessage
+ if null is not None:
+ self.null = null
+- if unicode is not None:
+- self.unicode = unicode
++ if str is not None:
++ self.str = str
+ self.attributes = attributes
+
+ def getAttribute(self, name, default=None):
+ return self.attributes.get(name, default)
+
+ def coerce(self, val, configurable):
+- raise NotImplementedError, "Implement in %s" % util.qual(self.__class__)
++ raise NotImplementedError("Implement in %s" % util.qual(self.__class__))
+
+
+ #######################################
+@@ -209,7 +209,7 @@ class Integer(Typed):
+ except ValueError:
+ if sys.version_info < (2,3): # Long/Int aren't integrated
+ try:
+- return long(val)
++ return int(val)
+ except ValueError:
+ raise InputError("'%s' is not an integer." % val)
+
+@@ -540,7 +540,7 @@ class Binding(object):
+ return self.original.__class__.__name__.lower()
+
+ def configure(self, boundTo, results):
+- raise NotImplementedError, "Implement in %s" % util.qual(self.__class__)
++ raise NotImplementedError("Implement in %s" % util.qual(self.__class__))
+
+ def coerce(self, val, configurable):
+ if hasattr(self.original, 'coerce'):
+@@ -617,7 +617,7 @@ class GroupBinding(Binding):
+ self.complexType = typedValue.complexType
+
+ def configure(self, boundTo, group):
+- print "CONFIGURING GROUP BINDING", boundTo, group
++ print("CONFIGURING GROUP BINDING", boundTo, group)
+
+
+ def _sorter(x, y):
+@@ -670,7 +670,7 @@ def nameToLabel(mname):
+ def labelAndDescriptionFromDocstring(docstring):
+ if docstring is None:
+ docstring = ''
+- docs = filter(lambda x: x, [x.strip() for x in docstring.split('\n')])
++ docs = [x for x in [x.strip() for x in docstring.split('\n')] if x]
+ if len(docs) > 1:
+ return docs[0], '\n'.join(docs[1:])
+ else:
+@@ -723,7 +723,7 @@ class MetaTypedInterface(InterfaceClass):
+ cls.complexType = True
+ possibleActions = []
+ actionAttachers = []
+- for key, value in dct.items():
++ for key, value in list(dct.items()):
+ if key[0] == '_': continue
+
+ if isinstance(value, MetaTypedInterface):
+--- formless/configurable.py.orig 2015-10-20 22:44:09 UTC
++++ formless/configurable.py
+@@ -66,7 +66,7 @@ class Configurable(object):
+ try:
+ binding = self.bindingDict[name]
+ except KeyError:
+- raise RuntimeError, "%s is not an exposed binding on object %s." % (name, self.boundTo)
++ raise RuntimeError("%s is not an exposed binding on object %s." % (name, self.boundTo))
+ binding.boundTo = self.boundTo
+ return binding
+
+@@ -125,7 +125,7 @@ class Configurable(object):
+
+ class NotFoundConfigurable(Configurable):
+ def getBinding(self, context, name):
+- raise RuntimeError, self.original
++ raise RuntimeError(self.original)
+
+
+ class TypedInterfaceConfigurable(Configurable):
+--- formless/processors.py.orig 2015-10-20 22:44:09 UTC
++++ formless/processors.py
+@@ -21,7 +21,7 @@ faketag = tags.html()
+ def exceptblock(f, handler, exception, *a, **kw):
+ try:
+ result = f(*a, **kw)
+- except exception, e:
++ except exception as e:
+ return handler(e)
+ if isinstance(result, Deferred):
+ def _(fail):
+@@ -91,7 +91,7 @@ class ProcessMethodBinding(components.Adapter):
+ typedValue = self.original.typedValue
+ results = {}
+ failures = {}
+- if data.has_key('----'):
++ if '----' in data:
+ ## ---- is the "direct object", the one argument you can specify using the command line without saying what the argument name is
+ data[typedValue.arguments[0].name] = data['----']
+ del data['----']
+@@ -101,7 +101,7 @@ class ProcessMethodBinding(components.Adapter):
+ context = WovenContext(context, faketag)
+ context.remember(binding, iformless.IBinding)
+ results[name] = iformless.IInputProcessor(binding.typedValue).process(context, boundTo, data.get(name, ['']))
+- except formless.InputError, e:
++ except formless.InputError as e:
+ results[name] = data.get(name, [''])[0]
+ failures[name] = e.reason
+
+@@ -130,14 +130,14 @@ class ProcessPropertyBinding(components.Adapter):
+ result = {}
+ try:
+ result[binding.name] = iformless.IInputProcessor(binding.typedValue).process(context, boundTo, data.get(binding.name, ['']))
+- except formless.InputError, e:
++ except formless.InputError as e:
+ result[binding.name] = data.get(binding.name, [''])
+ raise formless.ValidateError({binding.name: e.reason}, e.reason, result)
+
+ if autoConfigure:
+ try:
+ return self.original.configure(boundTo, result)
+- except formless.InputError, e:
++ except formless.InputError as e:
+ result[binding.name] = data.get(binding.name, [''])
+ raise formless.ValidateError({binding.name: e.reason}, e.reason, result)
+ return result
+@@ -150,7 +150,7 @@ class ProcessTyped(components.Adapter):
+ """
+ typed = self.original
+ val = data[0]
+- if typed.unicode:
++ if typed.str:
+ try:
+ val = val.decode(getPOSTCharset(context), 'replace')
+ except LookupError:
+@@ -164,7 +164,7 @@ class ProcessTyped(components.Adapter):
+ return typed.null
+ try:
+ return typed.coerce(val, boundTo)
+- except TypeError, e:
++ except TypeError as e:
+ warnings.warn('Typed.coerce takes two values now, the value to coerce and the configurable in whose context the coerce is taking place. %s %s' % (typed.__class__, typed))
+ return typed.coerce(val)
+
+@@ -190,7 +190,7 @@ class ProcessPassword(components.Adapter):
+ else:
+ return typed.null
+ val = data[0]
+- if typed.unicode:
++ if typed.str:
+ try:
+ val = val.decode(getPOSTCharset(context), 'replace')
+ except LookupError:
+--- formless/webform.py.orig 2015-10-20 22:44:09 UTC
++++ formless/webform.py
+@@ -4,8 +4,8 @@
+ # See LICENSE for details.
+
+
+-from __future__ import generators
+
++
+ import warnings
+ from zope.interface import implements, Interface
+
+@@ -66,7 +66,7 @@ class BaseInputRenderer(components.Adapter):
+ return context.tag
+
+ def input(self, context, slot, data, name, value):
+- raise NotImplementedError, "Implement in subclass"
++ raise NotImplementedError("Implement in subclass")
+
+ class PasswordRenderer(BaseInputRenderer):
+ def input(self, context, slot, data, name, value):
+@@ -437,7 +437,7 @@ def renderForms(configurableKey='', bindingNames=None,
+ if bindingDefaults is None:
+ available = configurable.getBindingNames(context)
+ else:
+- available = bindingDefaults.iterkeys()
++ available = iter(bindingDefaults.keys())
+
+ def _callback(binding):
+ renderer = iformless.IBindingRenderer(binding, defaultBindingRenderer)
+--- nevow/_flat.py.orig 2016-05-08 19:28:50 UTC
++++ nevow/_flat.py
+@@ -61,7 +61,7 @@ class FlattenerError(Exception):
+ @return: A string representation of C{obj}.
+ @rtype: L{str}
+ """
+- if isinstance(obj, (str, unicode)):
++ if isinstance(obj, str):
+ # It's somewhat unlikely that there will ever be a str in the roots
+ # list. However, something like a MemoryError during a str.replace
+ # call (eg, replacing " with ") could possibly cause this.
+@@ -175,7 +175,7 @@ def _ctxForRequest(request, slotData, renderFactory, i
+ ctx.remember(request, IRequest)
+ for slotGroup in slotData:
+ if slotGroup is not None:
+- for k, v in slotGroup.items():
++ for k, v in list(slotGroup.items()):
+ ctx.fillSlots(k, v)
+ if renderFactory is not None:
+ ctx.remember(_OldRendererFactory(renderFactory), IRendererFactory)
+@@ -224,7 +224,7 @@ def _flatten(request, write, root, slotData, renderFac
+ @return: An iterator which yields C{str}, L{Deferred}, and more iterators
+ of the same type.
+ """
+- if isinstance(root, unicode):
++ if isinstance(root, str):
+ root = root.encode('utf-8')
+ elif isinstance(root, WovenContext):
+ # WovenContext is supported via the getFlattener case, but that is a
+@@ -268,13 +268,13 @@ def _flatten(request, write, root, slotData, renderFac
+ False, True)
+ else:
+ write('<')
+- if isinstance(root.tagName, unicode):
++ if isinstance(root.tagName, str):
+ tagName = root.tagName.encode('ascii')
+ else:
+ tagName = str(root.tagName)
+ write(tagName)
+- for k, v in sorted(root.attributes.iteritems()):
+- if isinstance(k, unicode):
++ for k, v in sorted(root.attributes.items()):
++ if isinstance(k, str):
+ k = k.encode('ascii')
+ write(" " + k + "=\"")
+ yield _flatten(request, write, v, slotData,
+@@ -310,7 +310,7 @@ def _flatten(request, write, root, slotData, renderFac
+ write(root.num)
+ write(';')
+ elif isinstance(root, xml):
+- if isinstance(root.content, unicode):
++ if isinstance(root.content, str):
+ write(root.content.encode('utf-8'))
+ else:
+ write(root.content)
+@@ -409,10 +409,10 @@ def flatten(request, write, root, inAttribute, inXML):
+ # In Python 2.5, after an exception, a generator's gi_frame is
+ # None.
+ frame = stack[-1].gi_frame
+- element = stack[-1].next()
++ element = next(stack[-1])
+ except StopIteration:
+ stack.pop()
+- except Exception, e:
++ except Exception as e:
+ stack.pop()
+ roots = []
+ for generator in stack:
+@@ -423,7 +423,8 @@ def flatten(request, write, root, inAttribute, inXML):
+ if type(element) is str:
+ write(element)
+ elif isinstance(element, Deferred):
+- def cbx((original, toFlatten)):
++ def cbx(xxx_todo_changeme):
++ (original, toFlatten) = xxx_todo_changeme
+ stack.append(toFlatten)
+ return original
+ yield element.addCallback(cbx)
+@@ -456,7 +457,7 @@ def _flattensome(state, write, schedule, result):
+ """
+ while True:
+ try:
+- element = state.next()
++ element = next(state)
+ except StopIteration:
+ result.callback(None)
+ except:
+--- nevow/accessors.py.orig 2015-10-20 22:44:09 UTC
++++ nevow/accessors.py
+@@ -48,7 +48,7 @@ class DirectiveAccessor(tpc.Adapter):
+ data = context.locate(IData)
+ container = IContainer(data, None)
+ if container is None:
+- raise NoAccessor, "%r does not implement IContainer, and there is no registered adapter." % data
++ raise NoAccessor("%r does not implement IContainer, and there is no registered adapter." % data)
+ child = container.child(context, self.original.name)
+ return child
+
+--- nevow/athena.py.orig 2016-05-08 19:28:50 UTC
++++ nevow/athena.py
+@@ -1,6 +1,6 @@
+ # -*- test-case-name: nevow.test.test_athena -*-
+
+-import itertools, os, re, warnings, StringIO
++import itertools, os, re, warnings, io
+
+ from zope.interface import implements
+
+@@ -49,7 +49,7 @@ class LivePageError(Exception):
+ """
+ Base exception for LivePage errors.
+ """
+- jsClass = u'Divmod.Error'
++ jsClass = 'Divmod.Error'
+
+
+
+@@ -58,7 +58,7 @@ class NoSuchMethod(LivePageError):
+ Raised when an attempt is made to invoke a method which is not defined or
+ exposed.
+ """
+- jsClass = u'Nevow.Athena.NoSuchMethod'
++ jsClass = 'Nevow.Athena.NoSuchMethod'
+
+ def __init__(self, objectID, methodName):
+ self.objectID = objectID
+@@ -186,7 +186,7 @@ class AthenaModule(object):
+ Calculate our dependencies given the path to our source.
+ """
+ depgen = self._extractImports(file(jsFile, 'rU'))
+- return self.packageDeps + dict.fromkeys(depgen).keys()
++ return self.packageDeps + list(dict.fromkeys(depgen).keys())
+
+
+ def dependencies(self):
+@@ -300,7 +300,7 @@ def _collectPackageBelow(baseDir, extension):
+ path = os.path.join(root, dir, '__init__.' + extension)
+ if not os.path.exists(path):
+ path = EMPTY
+- mapping[unicode(name, 'ascii')] = path
++ mapping[str(name, 'ascii')] = path
+ _revMap[os.path.join(root, dir)] = name + '.'
+
+ for fn in filenames:
+@@ -315,7 +315,7 @@ def _collectPackageBelow(baseDir, extension):
+
+ name = stem + fn[:-(len(extension) + 1)]
+ path = os.path.join(root, fn)
+- mapping[unicode(name, 'ascii')] = path
++ mapping[str(name, 'ascii')] = path
+ return mapping
+
+
+@@ -540,11 +540,11 @@ def getJSFailure(exc, modules):
+ """
+ Convert a serialized client-side exception to a Failure.
+ """
+- text = '%s: %s' % (exc[u'name'], exc[u'message'])
++ text = '%s: %s' % (exc['name'], exc['message'])
+
+ frames = []
+- if u'stack' in exc:
+- frames = parseStack(exc[u'stack'])
++ if 'stack' in exc:
++ frames = parseStack(exc['stack'])
+
+ return failure.Failure(JSException(text), exc_tb=buildTraceback(frames, modules))
+
+@@ -618,8 +618,8 @@ class ConnectionLost(Exception):
+ pass
+
+
+-CLOSE = u'close'
+-UNLOAD = u'unload'
++CLOSE = 'close'
++UNLOAD = 'unload'
+
+ class ReliableMessageDelivery(object):
+ """
+@@ -775,8 +775,8 @@ class ReliableMessageDelivery(object):
+
+
+ def _unregisterDeferredAsOutputChannel(self, deferred):
+- for i in xrange(len(self.outputs)):
+- if self.outputs[i][0].im_self is deferred:
++ for i in range(len(self.outputs)):
++ if self.outputs[i][0].__self__ is deferred:
+ output, timeout = self.outputs.pop(i)
+ timeout.cancel()
+ break
+@@ -1007,7 +1007,7 @@ class LivePage(rend.Page, _HasJSClass, _HasCSSModule):
+ @ivar _localObjectIDCounter: A callable that will return a new
+ locally-unique object ID each time it is called.
+ """
+- jsClass = u'Nevow.Athena.PageWidget'
++ jsClass = 'Nevow.Athena.PageWidget'
+ cssModule = None
+
+ factory = LivePageFactory()
+@@ -1140,7 +1140,7 @@ class LivePage(rend.Page, _HasJSClass, _HasCSSModule):
+ if self.cssModuleRoot is None:
+ self.cssModuleRoot = location.child(self.clientID).child('cssmodule')
+
+- self._requestIDCounter = itertools.count().next
++ self._requestIDCounter = itertools.count().__next__
+
+ self._messageDeliverer = ReliableMessageDelivery(
+ self,
+@@ -1151,7 +1151,7 @@ class LivePage(rend.Page, _HasJSClass, _HasCSSModule):
+ connectionMade=self._connectionMade)
+ self._remoteCalls = {}
+ self._localObjects = {}
+- self._localObjectIDCounter = itertools.count().next
++ self._localObjectIDCounter = itertools.count().__next__
+
+ self.addLocalObject(self)
+
+@@ -1252,7 +1252,7 @@ class LivePage(rend.Page, _HasJSClass, _HasCSSModule):
+ """
+ Invoke connectionMade on all attached widgets.
+ """
+- for widget in self._localObjects.values():
++ for widget in list(self._localObjects.values()):
+ widget.connectionMade()
+ self._didConnect = True
+
+@@ -1274,10 +1274,10 @@ class LivePage(rend.Page, _HasJSClass, _HasCSSModule):
+ d.errback(reason)
+ calls = self._remoteCalls
+ self._remoteCalls = {}
+- for (reqID, resD) in calls.iteritems():
++ for (reqID, resD) in calls.items():
+ resD.errback(reason)
+ if self._didConnect:
+- for widget in self._localObjects.values():
++ for widget in list(self._localObjects.values()):
+ widget.connectionLost(reason)
+ self.factory.removeClient(self.clientID)
+
+@@ -1316,8 +1316,8 @@ class LivePage(rend.Page, _HasJSClass, _HasCSSModule):
+
+
+ def callRemote(self, methodName, *args):
+- requestID = u's2c%i' % (self._requestIDCounter(),)
+- message = (u'call', (unicode(methodName, 'ascii'), requestID, args))
++ requestID = 's2c%i' % (self._requestIDCounter(),)
++ message = ('call', (str(methodName, 'ascii'), requestID, args))
+ resultD = defer.Deferred()
+ self._remoteCalls[requestID] = resultD
+ self.addMessage(message)
+@@ -1439,12 +1439,13 @@ class LivePage(rend.Page, _HasJSClass, _HasCSSModule):
+ raise AttributeError(methodName)
+
+
+- def liveTransportMessageReceived(self, ctx, (action, args)):
++ def liveTransportMessageReceived(self, ctx, xxx_todo_changeme):
+ """
+ A message was received from the reliable transport layer. Process it by
+ dispatching it first to myself, then later to application code if
+ applicable.
+ """
++ (action, args) = xxx_todo_changeme
+ method = getattr(self, 'action_' + action)
+ method(ctx, *args)
+
+@@ -1472,11 +1473,11 @@ class LivePage(rend.Page, _HasJSClass, _HasCSSModule):
+ result.value.args)
+ else:
+ result = (
+- u'Divmod.Error',
+- [u'%s: %s' % (
++ 'Divmod.Error',
++ ['%s: %s' % (
+ result.type.__name__.decode('ascii'),
+ result.getErrorMessage().decode('ascii'))])
+- message = (u'respond', (unicode(requestId), success, result))
++ message = ('respond', (str(requestId), success, result))
+ self.addMessage(message)
+ result.addBoth(_cbCall)
+
+@@ -1517,7 +1518,7 @@ def _rewriteEventHandlerToAttribute(tag):
+ """
+ if isinstance(tag, stan.Tag):
+ extraAttributes = {}
+- for i in xrange(len(tag.children) - 1, -1, -1):
++ for i in range(len(tag.children) - 1, -1, -1):
+ if isinstance(tag.children[i], stan.Tag) and tag.children[i].tagName == 'athena:handler':
+ info = tag.children.pop(i)
+ name = info.attributes['event'].encode('ascii')
+@@ -1565,7 +1566,7 @@ def _rewriteAthenaId(tag):
+ if headers is not None:
+ ids = headers.split()
+ headers = [_mangleId(headerId) for headerId in ids]
+- for n in xrange(len(headers) - 1, 0, -1):
++ for n in range(len(headers) - 1, 0, -1):
+ headers.insert(n, ' ')
+ tag.attributes['headers'] = headers
+ return tag
+@@ -1580,7 +1581,7 @@ def rewriteAthenaIds(root):
+
+
+ class _LiveMixin(_HasJSClass, _HasCSSModule):
+- jsClass = u'Nevow.Athena.Widget'
++ jsClass = 'Nevow.Athena.Widget'
+ cssModule = None
+
+ preprocessors = [rewriteEventHandlerNodes, rewriteAthenaIds]
+@@ -1633,7 +1634,7 @@ class _LiveMixin(_HasJSClass, _HasCSSModule):
+ C{self.page}, add this object to the page and fill the I{athena:id}
+ slot with this object's Athena identifier.
+ """
+- assert isinstance(self.jsClass, unicode), "jsClass must be a unicode string"
++ assert isinstance(self.jsClass, str), "jsClass must be a unicode string"
+
+ if self.page is None:
+ raise OrphanedFragment(self)
+@@ -1681,7 +1682,7 @@ class _LiveMixin(_HasJSClass, _HasCSSModule):
+ # different module from whence nevow.athena and nevow.testutil could
+ # import it. -exarkun
+ from nevow.testutil import FakeRequest
+- s = StringIO.StringIO()
++ s = io.StringIO()
+ for _ in _flat.flatten(FakeRequest(), s.write, what, False, False):
+ pass
+ return s.getvalue()
+@@ -1713,15 +1714,15 @@ class _LiveMixin(_HasJSClass, _HasCSSModule):
+ del children[0]
+
+ self._structuredCache = {
+- u'requiredModules': [(name, flat.flatten(url).decode('utf-8'))
++ 'requiredModules': [(name, flat.flatten(url).decode('utf-8'))
+ for (name, url) in requiredModules],
+- u'requiredCSSModules': [flat.flatten(url).decode('utf-8')
++ 'requiredCSSModules': [flat.flatten(url).decode('utf-8')
+ for url in requiredCSSModules],
+- u'class': self.jsClass,
+- u'id': self._athenaID,
+- u'initArguments': tuple(self.getInitialArguments()),
+- u'markup': markup,
+- u'children': children}
++ 'class': self.jsClass,
++ 'id': self._athenaID,
++ 'initArguments': tuple(self.getInitialArguments()),
++ 'markup': markup,
++ 'children': children}
+ return self._structuredCache
+
+
+@@ -1741,9 +1742,9 @@ class _LiveMixin(_HasJSClass, _HasCSSModule):
+ # This will only be set if _structured() is being run.
+ if context.get('children') is not None:
+ context.get('children').append({
+- u'class': self.jsClass,
+- u'id': self._athenaID,
+- u'initArguments': self.getInitialArguments()})
++ 'class': self.jsClass,
++ 'id': self._athenaID,
++ 'initArguments': self.getInitialArguments()})
+ context.get('requiredModules').extend(requiredModules)
+ context.get('requiredCSSModules').extend(requiredCSSModules)
+ return tag
+@@ -1792,7 +1793,7 @@ class _LiveMixin(_HasJSClass, _HasCSSModule):
+ return self.page.callRemote(
+ "Nevow.Athena.callByAthenaID",
+ self._athenaID,
+- unicode(methodName, 'ascii'),
++ str(methodName, 'ascii'),
+ varargs)
+
+
+@@ -1998,7 +1999,7 @@ class IntrospectionFragment(LiveFragment):
+ the state of a live page.
+ """
+
+- jsClass = u'Nevow.Athena.IntrospectionWidget'
++ jsClass = 'Nevow.Athena.IntrospectionWidget'
+
+ docFactory = loaders.stan(
+ tags.span(render=tags.directive('liveFragment'))[
+--- nevow/canvas.py.orig 2015-10-20 22:44:09 UTC
++++ nevow/canvas.py
+@@ -11,7 +11,7 @@ from nevow.flat import flatten
+ from nevow.stan import Proto, Tag
+ from itertools import count
+
+-cn = count().next
++cn = count().__next__
+ cookie = lambda: str(cn())
+
+ _hookup = {}
+@@ -193,7 +193,7 @@ class GroupBase(object):
+ l[[a(v=x) for x in colors]],
+ l[[a(v=x) for x in alphas]],
+ l[[a(v=x) for x in ratios]],
+- d[[i(k=k, v=v) for (k, v) in matrix.items()]])
++ d[[i(k=k, v=v) for (k, v) in list(matrix.items())]])
+
+ def text(self, text, x, y, height, width):
+ """Place the given text on the canvas using the given x, y, height and width.
+@@ -212,7 +212,7 @@ class GroupBase(object):
+ cook = cookie()
+ I = Image(cook, self)
+ self.call('image', cook, where)
+- print "IMAGE", where
++ print("IMAGE", where)
+ return I
+
+ def sound(self, where, stream=True):
+@@ -354,18 +354,18 @@ class CanvasSocket(GroupBase):
+
+ def handle_onMouseUp(self, info):
+ if self.delegate.onMouseUp:
+- self.delegate.onMouseUp(self, *map(int, map(float, info.split())))
++ self.delegate.onMouseUp(self, *list(map(int, list(map(float, info.split())))))
+
+ def handle_onMouseDown(self, info):
+ if self.delegate.onMouseDown:
+- self.delegate.onMouseDown(self, *map(int, map(float, info.split())))
++ self.delegate.onMouseDown(self, *list(map(int, list(map(float, info.split())))))
+
+ def handle_onMouseMove(self, info):
+ if self.delegate.onMouseMove:
+- self.delegate.onMouseMove(self, *map(int, map(float, info.split())))
++ self.delegate.onMouseMove(self, *list(map(int, list(map(float, info.split())))))
+
+ def handle_diagnostic(self, info):
+- print "Trace", info
++ print("Trace", info)
+
+ canvasServerMessage = loaders.stan(tags.html["This server dispatches for nevow canvas events."])
+
+--- nevow/context.py.orig 2015-10-20 22:44:09 UTC
++++ nevow/context.py
+@@ -2,8 +2,8 @@
+ # Copyright (c) 2004 Divmod.
+ # See LICENSE for details.
+
+-from __future__ import generators
+
++
+ import warnings
+
+ from nevow import stan
+@@ -109,7 +109,7 @@ class WebContext(object):
+
+ contextParent = currentContext.parent
+ if contextParent is None:
+- raise KeyError, "Interface %s was not remembered." % key
++ raise KeyError("Interface %s was not remembered." % key)
+
+ currentContext = contextParent
+
+@@ -151,7 +151,7 @@ class WebContext(object):
+ if data is not Unset:
+ return data
+ if currentContext.parent is None:
+- raise KeyError, "Slot named '%s' was not filled." % name
++ raise KeyError("Slot named '%s' was not filled." % name)
+ currentContext = currentContext.parent
+
+ def clone(self, deep=True, cloneTags=True):
+--- nevow/dirlist.py.orig 2015-10-20 22:44:09 UTC
++++ nevow/dirlist.py
+@@ -5,7 +5,7 @@
+
+ # system imports
+ import os
+-import urllib
++import urllib.request, urllib.parse, urllib.error
+ import stat
+
+ # twisted imports
+@@ -49,7 +49,7 @@ class DirectoryLister(rend.Page):
+ files = []; dirs = []
+
+ for path in directory:
+- url = urllib.quote(path, '/')
++ url = urllib.parse.quote(path, '/')
+ if os.path.isdir(os.path.join(self.path, path)):
+ url = url + '/'
+ dirs.append({
+@@ -65,7 +65,7 @@ class DirectoryLister(rend.Page):
+ self.contentTypes, self.contentEncodings, self.defaultType)
+ try:
+ filesize = os.stat(os.path.join(self.path, path))[stat.ST_SIZE]
+- except OSError, x:
++ except OSError as x:
+ if x.errno != 2 and x.errno != 13:
+ raise x
+ else:
+@@ -80,7 +80,7 @@ class DirectoryLister(rend.Page):
+
+ def data_header(self, context, data):
+ request = context.locate(inevow.IRequest)
+- return "Directory listing for %s" % urllib.unquote(request.uri)
++ return "Directory listing for %s" % urllib.parse.unquote(request.uri)
+
+ def render_tableLink(self, context, data):
+ return tags.a(href=data['link'])[data['linktext']]
+--- nevow/entities.py.orig 2015-10-20 22:44:09 UTC
++++ nevow/entities.py
+@@ -10,7 +10,8 @@ import types
+
+ __by_number = {}
+
+-def makeEntity((name, num, description)):
++def makeEntity(xxx_todo_changeme):
++ (name, num, description) = xxx_todo_changeme
+ from nevow.stan import Entity
+ e = Entity(name, num, description)
+ __by_number[types.IntType(num)] = e
+--- nevow/events.py.orig 2015-10-20 22:44:09 UTC
++++ nevow/events.py
+@@ -16,7 +16,7 @@ class EventNotification:
+ Returns a token which should be passed to unsubscribe when done.
+ """
+ if DEBUG:
+- print "SUBSCRIBE", self, identifier, subscriber
++ print("SUBSCRIBE", self, identifier, subscriber)
+ self._subscribers.setdefault(identifier, []).append(subscriber)
+ return identifier, subscriber
+
+@@ -24,7 +24,7 @@ class EventNotification:
+ """Unsubscribe the given token from events.
+ """
+ if DEBUG:
+- print "UNSUBSCRIBE", token
++ print("UNSUBSCRIBE", token)
+ identifier, reference = token
+ self._subscribers[identifier].remove(reference)
+
+@@ -32,14 +32,14 @@ class EventNotification:
+ """Notify the listeners on a given identifier that an event has occurred.
+ """
+ if DEBUG:
+- print "PUBLISH", self, identifier,
++ print("PUBLISH", self, identifier, end=' ')
+ subscribers = self._subscribers.get(identifier, [])
+ for sub in subscribers:
+ sub(*args)
+ if DEBUG:
+- print "NOTIFY SUBSCRIBER", sub
++ print("NOTIFY SUBSCRIBER", sub)
+ if DEBUG:
+- print "done"
++ print("done")
+
+ def nextId(self):
+ self._currentId += 1
+--- nevow/flat/flatstan.py.orig 2016-01-26 23:52:18 UTC
++++ nevow/flat/flatstan.py
+@@ -1,10 +1,10 @@
+ # Copyright (c) 2004 Divmod.
+ # See LICENSE for details.
+
+-from __future__ import generators
+
+-import urllib, warnings
+
++import urllib.request, urllib.parse, urllib.error, warnings
++
+ from twisted.python import log, failure
+
+ from nevow import util
+@@ -38,7 +38,7 @@ def TagSerializer(original, context, contextIsMine=Fal
+ visible = bool(original.tagName)
+
+ if visible and context.isAttrib:
+- raise RuntimeError, "Tried to render tag '%s' in an tag attribute context." % (original.tagName)
++ raise RuntimeError("Tried to render tag '%s' in an tag attribute context." % (original.tagName))
+
+ if context.precompile and original.macro:
+ toBeRenderedBy = original.macro
+@@ -53,7 +53,7 @@ def TagSerializer(original, context, contextIsMine=Fal
+ ## TODO: Do we really need to bypass precompiling for *all* specials?
+ ## Perhaps just render?
+ if context.precompile and (
+- [x for x in original._specials.values()
++ [x for x in list(original._specials.values())
+ if x is not None and x is not Unset]
+ or original.slotData):
+ ## The tags inside this one get a "fresh" parent chain, because
+@@ -111,7 +111,7 @@ def TagSerializer(original, context, contextIsMine=Fal
+ yield '<%s' % original.tagName
+ if original.attributes:
+ attribContext = WovenContext(parent=context, precompile=context.precompile, isAttrib=True)
+- for (k, v) in sorted(original.attributes.iteritems()):
++ for (k, v) in sorted(original.attributes.items()):
+ if v is None:
+ continue
+ yield ' %s="' % k
+@@ -155,7 +155,7 @@ def StringSerializer(original, context):
+ if context.inURL:
+ # The magic string "-_.!*'()" also appears in url.py. Thinking about
+ # changing this? Change that, too.
+- return urllib.quote(original, safe="-_.!*'()")
++ return urllib.parse.quote(original, safe="-_.!*'()")
+ ## quote it
+ if context.inJS:
+ original = _jsSingleQuoteQuote(original)
+@@ -235,7 +235,7 @@ def FunctionSerializer(original, context, nocontextfun
+ else:
+ result = original(context, data)
+ except StopIteration:
+- raise RuntimeError, "User function %r raised StopIteration." % original
++ raise RuntimeError("User function %r raised StopIteration." % original)
+ return serialize(result, context)
+
+
+--- nevow/guard.py.orig 2016-02-17 12:51:40 UTC
++++ nevow/guard.py
+@@ -16,7 +16,7 @@ try:
+ from hashlib import md5
+ except ImportError:
+ from md5 import md5
+-import StringIO
++import io
+
+ from zope.interface import implements
+
+@@ -68,7 +68,7 @@ class GuardSession(components.Componentized):
+ # XXX TODO: need to actually sort avatars by login order!
+ if len(self.portals) != 1:
+ raise RuntimeError("Ambiguous request for current avatar.")
+- return self.portals.values()[0][0]
++ return list(self.portals.values())[0][0]
+
+ def resourceForPortal(self, port):
+ return self.portals.get(port)
+@@ -86,7 +86,7 @@ class GuardSession(components.Componentized):
+ raise RuntimeError("Ambiguous request for current avatar.")
+ self.setResourceForPortal(
+ rsrc,
+- self.portals.keys()[0],
++ list(self.portals.keys())[0],
+ logout)
+
+ def setResourceForPortal(self, rsrc, port, logout):
+@@ -148,7 +148,7 @@ class GuardSession(components.Componentized):
+ del self.guard.sessions[self.uid]
+
+ # Logout of all portals
+- for portal in self.portals.keys():
++ for portal in list(self.portals.keys()):
+ self.portalLogout(portal)
+
+ for c in self.expireCallbacks:
+@@ -170,7 +170,7 @@ class GuardSession(components.Componentized):
+ self.checkExpiredID = None
+ # If I haven't been touched in 15 minutes:
+ if time.time() - self.lastModified > self.lifetime / 2:
+- if self.guard.sessions.has_key(self.uid):
++ if self.uid in self.guard.sessions:
+ self.expire()
+ else:
+ log.msg("no session to expire: %s" % str(self.uid))
+@@ -180,7 +180,7 @@ class GuardSession(components.Componentized):
+ self.checkExpired)
+ def __getstate__(self):
+ d = self.__dict__.copy()
+- if d.has_key('checkExpiredID'):
++ if 'checkExpiredID' in d:
+ del d['checkExpiredID']
+ return d
+
+@@ -196,7 +196,7 @@ def urlToChild(ctx, *ar, **kw):
+ u = u.child(stan.xml(segment))
+ if inevow.IRequest(ctx).method == 'POST':
+ u = u.clear()
+- for k,v in kw.items():
++ for k,v in list(kw.items()):
+ u = u.replace(k, v)
+
+ return u
+@@ -272,7 +272,8 @@ class SessionWrapper:
+ def renderHTTP(self, ctx):
+ request = inevow.IRequest(ctx)
+ d = defer.maybeDeferred(self._delegate, ctx, [])
+- def _cb((resource, segments), ctx):
++ def _cb(xxx_todo_changeme1, ctx):
++ (resource, segments) = xxx_todo_changeme1
+ assert not segments
+ res = inevow.IResource(resource)
+ return res.renderHTTP(ctx)
+@@ -425,7 +426,7 @@ class SessionWrapper:
+ if spoof and hasattr(session, 'args'):
+ request.args = session.args
+ request.fields = session.fields
+- request.content = StringIO.StringIO()
++ request.content = io.StringIO()
+ request.content.close()
+ request.method = session.method
+ request.requestHeaders = session._requestHeaders
+@@ -450,9 +451,10 @@ class SessionWrapper:
+
+ if authCommand == LOGIN_AVATAR:
+ subSegments = segments[1:]
+- def unmangleURL((res,segs)):
++ def unmangleURL(xxx_todo_changeme):
+ # Tell the session that we just logged in so that it will
+ # remember form values for us.
++ (res,segs) = xxx_todo_changeme
+ session.justLoggedIn = True
+ # Then, generate a redirect back to where we're supposed to be
+ # by looking at the root of the site and calculating the path
+@@ -533,7 +535,8 @@ class SessionWrapper:
+ self._cbLoginSuccess, session, segments
+ )
+
+- def _cbLoginSuccess(self, (iface, res, logout), session, segments):
++ def _cbLoginSuccess(self, xxx_todo_changeme2, session, segments):
++ (iface, res, logout) = xxx_todo_changeme2
+ session.setResourceForPortal(res, self.portal, logout)
+ return res, segments
+
+--- nevow/json.py.orig 2016-05-08 19:28:50 UTC
++++ nevow/json.py
+@@ -43,12 +43,12 @@ class StringTokenizer(object):
+ SLASH = "\\"
+
+ IT = iter(s)
+- bits = [IT.next()]
++ bits = [next(IT)]
+ for char in IT:
+ bits.append(char)
+ if char == SLASH:
+ try:
+- bits.append(IT.next())
++ bits.append(next(IT))
+ except StopIteration:
+ return None
+ if char == '"':
+@@ -82,9 +82,9 @@ class WhitespaceToken(object):
+
+ def jsonlong(s):
+ if 'e' in s:
+- m, e = map(long, s.split('e', 1))
++ m, e = list(map(int, s.split('e', 1)))
+ else:
+- m, e = long(s), 0
++ m, e = int(s), 0
+ return m * 10 ** e
+
*** 3269 LINES SKIPPED ***