git: e2f07d2ed388 - main - net/py-suds-jurko: Fix build with py-setuptools 58.0.0+

From: Po-Chuan Hsieh <sunpoet_at_FreeBSD.org>
Date: Mon, 25 Oct 2021 16:02:56 UTC
The branch main has been updated by sunpoet:

URL: https://cgit.FreeBSD.org/ports/commit/?id=e2f07d2ed3886e5176133deb6a446f01167f23da

commit e2f07d2ed3886e5176133deb6a446f01167f23da
Author:     Po-Chuan Hsieh <sunpoet@FreeBSD.org>
AuthorDate: 2021-10-25 15:09:17 +0000
Commit:     Po-Chuan Hsieh <sunpoet@FreeBSD.org>
CommitDate: 2021-10-25 15:57:34 +0000

    net/py-suds-jurko: Fix build with py-setuptools 58.0.0+
    
    - Bump PORTREVISION for package change
    
    ===>  Configuring for py38-suds-jurko-0.6_1
    error in suds-jurko setup command: use_2to3 is invalid.
    *** Error code 1
    
    Stop.
    make: stopped in /usr/ports/net/py-suds-jurko
    
    Reference:      https://github.com/pypa/setuptools/blob/main/CHANGES.rst
---
 net/py-suds-jurko/Makefile             |   25 +-
 net/py-suds-jurko/files/patch-2to3     | 1952 ++++++++++++++++++++++++++++++++
 net/py-suds-jurko/files/patch-setup.py |   20 +
 3 files changed, 1974 insertions(+), 23 deletions(-)

diff --git a/net/py-suds-jurko/Makefile b/net/py-suds-jurko/Makefile
index 34d36af5bfc9..5178c657a084 100644
--- a/net/py-suds-jurko/Makefile
+++ b/net/py-suds-jurko/Makefile
@@ -2,7 +2,7 @@
 
 PORTNAME=	suds-jurko
 PORTVERSION=	0.6
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	net python
 MASTER_SITES=	CHEESESHOP
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -20,27 +20,6 @@ USE_PYTHON=	autoplist concurrent distutils
 
 NO_ARCH=	yes
 
-post-patch:
-	# Move the tests into the main package so
-	# they are processed by 2to3 so we can test Python 3
-	@${MV} ${WRKSRC}/tests ${WRKSRC}/suds/tests
-	# Compensate for the package/module name change
-	@${REINPLACE_CMD} -e 's|import tests|import suds.tests|g' \
-		${WRKSRC}/suds/tests/test_argument_parser.py \
-		${WRKSRC}/suds/tests/test_date_time.py \
-		${WRKSRC}/suds/tests/test_input_parameters.py \
-		${WRKSRC}/suds/tests/test_reply_handling.py \
-		${WRKSRC}/suds/tests/test_request_construction.py \
-		${WRKSRC}/suds/tests/test_suds.py \
-		${WRKSRC}/suds/tests/test_timezone.py
-	@${REINPLACE_CMD} -e 's|tests.|suds.tests.|g' \
-		${WRKSRC}/suds/tests/conftest.py \
-		${WRKSRC}/suds/tests/test_reply_handling.py \
-		${WRKSRC}/suds/tests/test_suds.py \
-		${WRKSRC}/suds/tests/test_request_construction.py \
-		${WRKSRC}/suds/tests/test_input_parameters.py \
-		${WRKSRC}/suds/tests/test_argument_parser.py
-
 # lambda: foo needed due to wanting to exclude parametrized tests
 # https://github.com/pytest-dev/pytest/issues/5881
 # https://github.com/pytest-dev/pytest/issues/6177
@@ -59,6 +38,6 @@ do-test:
 		and not (lambda: locals)()()['test_choice_containing_an_empty_sequence[test_args_required0]'] \
 		and not (lambda: locals)()()['test_choice_explicitly_marked_as_optional[choice0]'] \
 		and not test_sending_unicode_data" \
-		build/lib/suds/tests
+		build/lib/tests
 
 .include <bsd.port.mk>
diff --git a/net/py-suds-jurko/files/patch-2to3 b/net/py-suds-jurko/files/patch-2to3
new file mode 100644
index 000000000000..d220b27c4300
--- /dev/null
+++ b/net/py-suds-jurko/files/patch-2to3
@@ -0,0 +1,1952 @@
+--- suds/bindings/binding.py.orig	2021-09-20 17:08:56 UTC
++++ suds/bindings/binding.py
+@@ -88,7 +88,7 @@ class Binding:
+         @return: A collection of parameter definitions
+         @rtype: [I{pdef},..]
+         """
+-        raise Exception, 'not implemented'
++        raise Exception('not implemented')
+ 
+     def get_message(self, method, args, kwargs):
+         """
+@@ -286,7 +286,7 @@ class Binding:
+         @return: The XML content for the <body/>
+         @rtype: [L{Element},..]
+         """
+-        raise Exception, 'not implemented'
++        raise Exception('not implemented')
+ 
+     def headercontent(self, method):
+         """
+@@ -339,7 +339,7 @@ class Binding:
+         @return: The body content.
+         @rtype: [L{Element},...]
+         """
+-        raise Exception, 'not implemented'
++        raise Exception('not implemented')
+ 
+     def body(self, content):
+         """
+--- suds/client.py.orig	2021-09-20 17:08:56 UTC
++++ suds/client.py
+@@ -37,12 +37,12 @@ from suds.transport import TransportError, Request
+ from suds.transport.https import HttpAuthenticated
+ from suds.umx.basic import Basic as UmxBasic
+ from suds.wsdl import Definitions
+-import sudsobject
++from . import sudsobject
+ 
+-from cookielib import CookieJar
++from http.cookiejar import CookieJar
+ from copy import deepcopy
+-import httplib
+-from urlparse import urlparse
++import http.client
++from urllib.parse import urlparse
+ 
+ from logging import getLogger
+ log = getLogger(__name__)
+@@ -181,7 +181,7 @@ class Client(UnicodeMixin):
+         if ( suds.__build__ ):
+             s.append('  build: %s' % suds.__build__)
+         for sd in self.sd:
+-            s.append('\n\n%s' % unicode(sd))
++            s.append('\n\n%s' % str(sd))
+         return ''.join(s)
+ 
+ 
+@@ -223,7 +223,7 @@ class Factory:
+         else:
+             try:
+                 result = self.builder.build(type)
+-            except Exception, e:
++            except Exception as e:
+                 log.error("create '%s' failed", name, exc_info=True)
+                 raise BuildError(name, e)
+         timer.stop()
+@@ -312,20 +312,20 @@ class ServiceSelector:
+         """
+         service = None
+         if not len(self.__services):
+-            raise Exception, 'No services defined'
++            raise Exception('No services defined')
+         if isinstance(name, int):
+             try:
+                 service = self.__services[name]
+                 name = service.name
+             except IndexError:
+-                raise ServiceNotFound, 'at [%d]' % name
++                raise ServiceNotFound('at [%d]' % name)
+         else:
+             for s in self.__services:
+                 if name == s.name:
+                     service = s
+                     break
+         if service is None:
+-            raise ServiceNotFound, name
++            raise ServiceNotFound(name)
+         return PortSelector(self.__client, service.ports, name)
+ 
+     def __ds(self):
+@@ -413,13 +413,13 @@ class PortSelector:
+         """
+         port = None
+         if not len(self.__ports):
+-            raise Exception, 'No ports defined: %s' % self.__qn
++            raise Exception('No ports defined: %s' % self.__qn)
+         if isinstance(name, int):
+             qn = '%s[%d]' % (self.__qn, name)
+             try:
+                 port = self.__ports[name]
+             except IndexError:
+-                raise PortNotFound, qn
++                raise PortNotFound(qn)
+         else:
+             qn = '.'.join((self.__qn, name))
+             for p in self.__ports:
+@@ -427,7 +427,7 @@ class PortSelector:
+                     port = p
+                     break
+         if port is None:
+-            raise PortNotFound, qn
++            raise PortNotFound(qn)
+         qn = '.'.join((self.__qn, port.name))
+         return MethodSelector(self.__client, port.methods, qn)
+ 
+@@ -488,7 +488,7 @@ class MethodSelector:
+         m = self.__methods.get(name)
+         if m is None:
+             qn = '.'.join((self.__qn, name))
+-            raise MethodNotFound, qn
++            raise MethodNotFound(qn)
+         return Method(self.__client, m)
+ 
+ 
+@@ -519,10 +519,10 @@ class Method:
+         client = clientclass(self.client, self.method)
+         try:
+             return client.invoke(args, kwargs)
+-        except WebFault, e:
++        except WebFault as e:
+             if self.faults():
+                 raise
+-            return (httplib.INTERNAL_SERVER_ERROR, e)
++            return (http.client.INTERNAL_SERVER_ERROR, e)
+ 
+     def faults(self):
+         """ get faults option """
+@@ -613,7 +613,7 @@ class SoapClient:
+             reply = self.options.transport.send(request)
+             timer.stop()
+             metrics.log.debug('waited %s on server reply', timer)
+-        except TransportError, e:
++        except TransportError as e:
+             content = e.fp and e.fp.read() or ''
+             return self.process_reply(reply=content, status=e.httpcode,
+                 description=tostr(e), original_soapenv=original_soapenv)
+@@ -623,12 +623,12 @@ class SoapClient:
+     def process_reply(self, reply, status=None, description=None,
+         original_soapenv=None):
+         if status is None:
+-            status = httplib.OK
+-        if status in (httplib.ACCEPTED, httplib.NO_CONTENT):
++            status = http.client.OK
++        if status in (http.client.ACCEPTED, http.client.NO_CONTENT):
+             return
+         failed = True
+         try:
+-            if status == httplib.OK:
++            if status == http.client.OK:
+                 log.debug('HTTP succeeded:\n%s', reply)
+             else:
+                 log.debug('HTTP failed - %d - %s:\n%s', status, description,
+@@ -657,19 +657,19 @@ class SoapClient:
+             #   An INSTANCE MUST use a "500 Internal Server Error" HTTP status
+             # code if the response message is a SOAP Fault.
+             replyroot = None
+-            if status in (httplib.OK, httplib.INTERNAL_SERVER_ERROR):
++            if status in (http.client.OK, http.client.INTERNAL_SERVER_ERROR):
+                 replyroot = _parse(reply)
+                 plugins.message.parsed(reply=replyroot)
+                 fault = self.get_fault(replyroot)
+                 if fault:
+-                    if status != httplib.INTERNAL_SERVER_ERROR:
++                    if status != http.client.INTERNAL_SERVER_ERROR:
+                         log.warn("Web service reported a SOAP processing "
+                             "fault using an unexpected HTTP status code %d. "
+                             "Reporting as an internal server error.", status)
+                     if self.options.faults:
+                         raise WebFault(fault, replyroot)
+-                    return (httplib.INTERNAL_SERVER_ERROR, fault)
+-            if status != httplib.OK:
++                    return (http.client.INTERNAL_SERVER_ERROR, fault)
++            if status != http.client.OK:
+                 if self.options.faults:
+                     # (todo)
+                     #   Use a more specific exception class here.
+@@ -688,7 +688,7 @@ class SoapClient:
+             failed = False
+             if self.options.faults:
+                 return result
+-            return (httplib.OK, result)
++            return (http.client.OK, result)
+         finally:
+             if failed and original_soapenv:
+                 log.error(original_soapenv)
+@@ -717,7 +717,7 @@ class SoapClient:
+         @rtype: dict
+         """
+         action = self.method.soap.action
+-        if isinstance(action, unicode):
++        if isinstance(action, str):
+             action = action.encode('utf-8')
+         stock = {'Content-Type':'text/xml; charset=utf-8', 'SOAPAction':action}
+         result = dict(stock, **self.options.headers)
+@@ -742,7 +742,7 @@ class SimClient(SoapClient):
+     @classmethod
+     def simulation(cls, kwargs):
+         """ get whether loopback has been specified in the I{kwargs}. """
+-        return kwargs.has_key(SimClient.injkey)
++        return SimClient.injkey in kwargs
+ 
+     def invoke(self, args, kwargs):
+         """
+--- suds/mx/__init__.py.orig	2021-09-20 17:08:56 UTC
++++ suds/mx/__init__.py
+@@ -43,7 +43,7 @@ class Content(Object):
+         Object.__init__(self)
+         self.tag = tag
+         self.value = value
+-        for k,v in kwargs.items():
++        for k,v in list(kwargs.items()):
+             setattr(self, k, v)
+ 
+     def __getattr__(self, name):
+@@ -52,8 +52,7 @@ class Content(Object):
+                 v = None
+                 setattr(self, name, v)
+             else:
+-                raise AttributeError, \
+-                    'Content has no attribute %s' % name
++                raise AttributeError('Content has no attribute %s' % name)
+         else:
+             v = self.__dict__[name]
+         return v
+--- suds/mx/literal.py.orig	2021-09-20 17:08:56 UTC
++++ suds/mx/literal.py
+@@ -131,9 +131,8 @@ class Typed(Core):
+         if current == content.type:
+             self.resolver.pop()
+         else:
+-            raise Exception, \
+-                'content (end) mismatch: top=(%s) cont=(%s)' % \
+-                (current, content)
++            raise Exception('content (end) mismatch: top=(%s) cont=(%s)' % \
++                (current, content))
+ 
+     def node(self, content):
+         #
+--- suds/plugin.py.orig	2021-09-20 17:08:56 UTC
++++ suds/plugin.py
+@@ -205,7 +205,7 @@ class PluginContainer:
+                     plugins.append(p)
+             return PluginDomain(ctx, plugins)
+         else:
+-            raise Exception, 'plugin domain (%s), invalid' % name
++            raise Exception('plugin domain (%s), invalid' % name)
+ 
+ 
+ class PluginDomain:
+@@ -252,6 +252,6 @@ class Method:
+                 method = getattr(plugin, self.name, None)
+                 if method and callable(method):
+                     method(ctx)
+-            except Exception, pe:
++            except Exception as pe:
+                 log.exception(pe)
+         return ctx
+--- suds/properties.py.orig	2021-09-20 17:08:56 UTC
++++ suds/properties.py
+@@ -67,23 +67,23 @@ class Link(object):
+         """
+         if pA in pB.links or \
+            pB in pA.links:
+-            raise Exception, 'Already linked'
++            raise Exception('Already linked')
+         dA = pA.domains()
+         dB = pB.domains()
+         for d in dA:
+             if d in dB:
+-                raise Exception, 'Duplicate domain "%s" found' % d
++                raise Exception('Duplicate domain "%s" found' % d)
+         for d in dB:
+             if d in dA:
+-                raise Exception, 'Duplicate domain "%s" found' % d
+-        kA = pA.keys()
+-        kB = pB.keys()
++                raise Exception('Duplicate domain "%s" found' % d)
++        kA = list(pA.keys())
++        kB = list(pB.keys())
+         for k in kA:
+             if k in kB:
+-                raise Exception, 'Duplicate key %s found' % k
++                raise Exception('Duplicate key %s found' % k)
+         for k in kB:
+             if k in kA:
+-                raise Exception, 'Duplicate key %s found' % k
++                raise Exception('Duplicate key %s found' % k)
+         return self
+ 
+     def teardown(self):
+@@ -177,7 +177,7 @@ class Definition:
+         if len(self.classes) and \
+             not isinstance(value, self.classes):
+                 msg = '"%s" must be: %s' % (self.name, self.classes)
+-                raise AttributeError,msg
++                raise AttributeError(msg)
+ 
+ 
+     def __repr__(self):
+@@ -251,7 +251,7 @@ class Properties:
+         """
+         if isinstance(other, Properties):
+             other = other.defined
+-        for n,v in other.items():
++        for n,v in list(other.items()):
+             self.set(n, v)
+         return self
+ 
+@@ -372,7 +372,7 @@ class Properties:
+             history = []
+         history.append(self)
+         keys = set()
+-        keys.update(self.definitions.keys())
++        keys.update(list(self.definitions.keys()))
+         for x in self.links:
+             if x in history:
+                 continue
+@@ -408,7 +408,7 @@ class Properties:
+         @return: self
+         @rtype: L{Properties}
+         """
+-        for d in self.definitions.values():
++        for d in list(self.definitions.values()):
+             self.defined[d.name] = d.default
+         return self
+ 
+@@ -434,10 +434,10 @@ class Properties:
+     def str(self, history):
+         s = []
+         s.append('Definitions:')
+-        for d in self.definitions.values():
++        for d in list(self.definitions.values()):
+             s.append('\t%s' % repr(d))
+         s.append('Content:')
+-        for d in self.defined.items():
++        for d in list(self.defined.items()):
+             s.append('\t%s' % str(d))
+         if self not in history:
+             history.append(self)
+--- suds/servicedefinition.py.orig	2021-09-20 17:08:56 UTC
++++ suds/servicedefinition.py
+@@ -80,7 +80,7 @@ class ServiceDefinition(UnicodeMixin):
+         timer.start()
+         for port in self.service.ports:
+             p = self.findport(port)
+-            for op in port.binding.operations.values():
++            for op in list(port.binding.operations.values()):
+                 m = p[0].method(op.name)
+                 binding = m.binding.input
+                 method = (m.name, binding.param_defs(m))
+@@ -138,7 +138,7 @@ class ServiceDefinition(UnicodeMixin):
+ 
+     def publictypes(self):
+         """Get all public types."""
+-        for t in self.wsdl.schema.types.values():
++        for t in list(self.wsdl.schema.types.values()):
+             if t in self.params: continue
+             if t in self.types: continue
+             item = (t, t)
+@@ -152,7 +152,7 @@ class ServiceDefinition(UnicodeMixin):
+         WSDL document.
+         """
+         used = [ns[0] for ns in self.prefixes]
+-        used += [ns[0] for ns in self.wsdl.root.nsprefixes.items()]
++        used += [ns[0] for ns in list(self.wsdl.root.nsprefixes.items())]
+         for n in range(0,1024):
+             p = 'ns%d'%n
+             if p not in used:
+@@ -235,6 +235,6 @@ class ServiceDefinition(UnicodeMixin):
+     def __unicode__(self):
+         try:
+             return self.description()
+-        except Exception, e:
++        except Exception as e:
+             log.exception(e)
+         return tostr(e)
+--- suds/store.py.orig	2021-09-20 17:08:56 UTC
++++ suds/store.py
+@@ -566,7 +566,7 @@ class DocumentStore:
+         protocol, location = self.__split(url)
+         content = self.__find(location)
+         if protocol == 'suds' and content is None:
+-            raise Exception, 'location "%s" not in document store' % location
++            raise Exception('location "%s" not in document store' % location)
+         return content
+ 
+     def __find(self, location):
+--- suds/sudsobject.py.orig	2021-09-20 17:08:56 UTC
++++ suds/sudsobject.py
+@@ -110,7 +110,7 @@ class Factory:
+             inst = subclass()
+         else:
+             inst = Object()
+-        for a in dict.items():
++        for a in list(dict.items()):
+             setattr(inst, a[0], a[1])
+         return inst
+ 
+@@ -146,7 +146,7 @@ class Object(UnicodeMixin):
+                 self.__keylist__.remove(name)
+         except:
+             cls = self.__class__.__name__
+-            raise AttributeError, "%s has no attribute '%s'" % (cls, name)
++            raise AttributeError("%s has no attribute '%s'" % (cls, name))
+ 
+     def __getitem__(self, name):
+         if isinstance(name, int):
+@@ -179,7 +179,7 @@ class Iter:
+         self.keylist = self.__keylist(sobject)
+         self.index = 0
+ 
+-    def next(self):
++    def __next__(self):
+         keylist = self.keylist
+         nkeys = len(self.keylist)
+         while self.index < nkeys:
+@@ -271,7 +271,7 @@ class Printer:
+             if len(object) == 0:
+                 return '<empty>'
+             return self.print_collection(object, h, n+2)
+-        if isinstance(object, basestring):
++        if isinstance(object, str):
+             return '"%s"' % tostr(object)
+         return '%s' % tostr(object)
+ 
+@@ -325,7 +325,7 @@ class Printer:
+             s.append('\n')
+             s.append(self.indent(n))
+         s.append('{')
+-        for item in d.items():
++        for item in list(d.items()):
+             s.append('\n')
+             s.append(self.indent(n+1))
+             if isinstance(item[1], (list,tuple)):
+--- suds/transport/http.py.orig	2021-09-20 17:08:56 UTC
++++ suds/transport/http.py
+@@ -22,12 +22,12 @@ from suds.properties import Unskin
+ from suds.transport import *
+ 
+ import base64
+-from cookielib import CookieJar
+-import httplib
++from http.cookiejar import CookieJar
++import http.client
+ import socket
+ import sys
+-import urllib2
+-from urlparse import urlparse
++import urllib.request, urllib.error, urllib.parse
++from urllib.parse import urlparse
+ 
+ from logging import getLogger
+ log = getLogger(__name__)
+@@ -62,10 +62,10 @@ class HttpTransport(Transport):
+         try:
+             url = self.__get_request_url(request)
+             log.debug('opening (%s)', url)
+-            u2request = urllib2.Request(url)
++            u2request = urllib.request.Request(url)
+             self.proxy = self.options.proxy
+             return self.u2open(u2request)
+-        except urllib2.HTTPError, e:
++        except urllib.error.HTTPError as e:
+             raise TransportError(str(e), e.code, e.fp)
+ 
+     def send(self, request):
+@@ -74,7 +74,7 @@ class HttpTransport(Transport):
+         msg = request.message
+         headers = request.headers
+         try:
+-            u2request = urllib2.Request(url, msg, headers)
++            u2request = urllib.request.Request(url, msg, headers)
+             self.addcookies(u2request)
+             self.proxy = self.options.proxy
+             request.headers.update(u2request.headers)
+@@ -85,10 +85,10 @@ class HttpTransport(Transport):
+                 headers = fp.headers.dict
+             else:
+                 headers = fp.headers
+-            result = Reply(httplib.OK, headers, fp.read())
++            result = Reply(http.client.OK, headers, fp.read())
+             log.debug('received:\n%s', result)
+-        except urllib2.HTTPError, e:
+-            if e.code in (httplib.ACCEPTED, httplib.NO_CONTENT):
++        except urllib.error.HTTPError as e:
++            if e.code in (http.client.ACCEPTED, http.client.NO_CONTENT):
+                 result = None
+             else:
+                 raise TransportError(e.msg, e.code, e.fp)
+@@ -140,7 +140,7 @@ class HttpTransport(Transport):
+ 
+         """
+         if self.urlopener is None:
+-            return urllib2.build_opener(*self.u2handlers())
++            return urllib.request.build_opener(*self.u2handlers())
+         return self.urlopener
+ 
+     def u2handlers(self):
+@@ -152,7 +152,7 @@ class HttpTransport(Transport):
+ 
+         """
+         handlers = []
+-        handlers.append(urllib2.ProxyHandler(self.proxy))
++        handlers.append(urllib.request.ProxyHandler(self.proxy))
+         return handlers
+ 
+     def u2ver(self):
+@@ -165,7 +165,7 @@ class HttpTransport(Transport):
+         try:
+             part = urllib2.__version__.split('.', 1)
+             return float('.'.join(part))
+-        except Exception, e:
++        except Exception as e:
+             log.exception(e)
+             return 0
+ 
+--- suds/umx/__init__.py.orig	2021-09-20 17:08:56 UTC
++++ suds/umx/__init__.py
+@@ -40,7 +40,7 @@ class Content(Object):
+         self.node = node
+         self.data = None
+         self.text = None
+-        for k,v in kwargs.items():
++        for k,v in list(kwargs.items()):
+             setattr(self, k, v)
+ 
+     def __getattr__(self, name):
+@@ -49,8 +49,7 @@ class Content(Object):
+                 v = None
+                 setattr(self, name, v)
+             else:
+-                raise AttributeError, \
+-                    'Content has no attribute %s' % name
++                raise AttributeError('Content has no attribute %s' % name)
+         else:
+             v = self.__dict__[name]
+         return v
+--- suds/wsdl.py.orig	2021-09-20 17:08:56 UTC
++++ suds/wsdl.py
+@@ -31,8 +31,8 @@ from suds.sudsobject import Object, Facade, Metadata
+ from suds.reader import DocumentReader
+ 
+ import re
+-import soaparray
+-from urlparse import urljoin
++from . import soaparray
++from urllib.parse import urljoin
+ 
+ from logging import getLogger
+ log = getLogger(__name__)
+@@ -232,7 +232,7 @@ class Definitions(WObject):
+         for p in service.ports:
+             binding = p.binding
+             ptype = p.binding.type
+-            operations = p.binding.type.operations.values()
++            operations = list(p.binding.type.operations.values())
+             for name in [op.name for op in operations]:
+                 m = Facade('Method')
+                 m.name = name
+@@ -249,8 +249,8 @@ class Definitions(WObject):
+ 
+     def set_wrapped(self):
+         """ set (wrapped|bare) flag on messages """
+-        for b in self.bindings.values():
+-            for op in b.operations.values():
++        for b in list(self.bindings.values()):
++            for op in list(b.operations.values()):
+                 for body in (op.soap.input.body, op.soap.output.body):
+                     body.wrapped = False
+                     if not self.options.unwrap:
+@@ -482,7 +482,7 @@ class PortType(NamedObject):
+         @param definitions: A definitions object.
+         @type definitions: L{Definitions}
+         """
+-        for op in self.operations.values():
++        for op in list(self.operations.values()):
+             if op.input is None:
+                 op.input = Message(Element('no-input'), definitions)
+             else:
+@@ -505,7 +505,7 @@ class PortType(NamedObject):
+                 qref = qualify(f.message, self.root, definitions.tns)
+                 msg = definitions.messages.get(qref)
+                 if msg is None:
+-                    raise Exception, "msg '%s', not-found" % f.message
++                    raise Exception("msg '%s', not-found" % f.message)
+                 f.message = msg
+ 
+     def operation(self, name):
+@@ -519,7 +519,7 @@ class PortType(NamedObject):
+         """
+         try:
+             return self.operations[name]
+-        except Exception, e:
++        except Exception as e:
+             raise MethodNotFound(name)
+ 
+     def __gt__(self, other):
+@@ -654,7 +654,7 @@ class Binding(NamedObject):
+         @type definitions: L{Definitions}
+         """
+         self.resolveport(definitions)
+-        for op in self.operations.values():
++        for op in list(self.operations.values()):
+             self.resolvesoapbody(definitions, op)
+             self.resolveheaders(definitions, op)
+             self.resolvefaults(definitions, op)
+@@ -683,8 +683,7 @@ class Binding(NamedObject):
+         """
+         ptop = self.type.operation(op.name)
+         if ptop is None:
+-            raise Exception, \
+-                "operation '%s' not defined in portType" % op.name
++            raise Exception("operation '%s' not defined in portType" % op.name)
+         soap = op.soap
+         parts = soap.input.body.parts
+         if len(parts):
+@@ -720,15 +719,14 @@ class Binding(NamedObject):
+             ref = qualify(mn, self.root, definitions.tns)
+             message = definitions.messages.get(ref)
+             if message is None:
+-                raise Exception, "message'%s', not-found" % mn
++                raise Exception("message'%s', not-found" % mn)
+             pn = header.part
+             for p in message.parts:
+                 if p.name == pn:
+                     header.part = p
+                     break
+             if pn == header.part:
+-                raise Exception, \
+-                    "message '%s' has not part named '%s'" % (ref, pn)
++                raise Exception("message '%s' has not part named '%s'" % (ref, pn))
+ 
+     def resolvefaults(self, definitions, op):
+         """
+@@ -741,8 +739,7 @@ class Binding(NamedObject):
+         """
+         ptop = self.type.operation(op.name)
+         if ptop is None:
+-            raise Exception, \
+-                "operation '%s' not defined in portType" % op.name
++            raise Exception("operation '%s' not defined in portType" % op.name)
+         soap = op.soap
+         for fault in soap.faults:
+             for f in ptop.faults:
+@@ -751,8 +748,7 @@ class Binding(NamedObject):
+                     continue
+             if hasattr(fault, 'parts'):
+                 continue
+-            raise Exception, \
+-                "fault '%s' not defined in portType '%s'" % (fault.name, self.type.name)
++            raise Exception("fault '%s' not defined in portType '%s'" % (fault.name, self.type.name))
+ 
+     def operation(self, name):
+         """
+@@ -854,7 +850,7 @@ class Service(NamedObject):
+         @type names: [str,..]
+         """
+         for p in self.ports:
+-            for m in p.methods.values():
++            for m in list(p.methods.values()):
+                 if names is None or m.name in names:
+                     m.location = url
+ 
+--- suds/xsd/deplist.py.orig	2021-09-20 17:08:56 UTC
++++ suds/xsd/deplist.py
+@@ -77,7 +77,7 @@ class DepList:
+             while len(self.stack):
+                 try:
+                     top = self.top()
+-                    ref = top[1].next()
++                    ref = next(top[1])
+                     refd = self.index.get(ref)
+                     if refd is None:
+                         log.debug('"%s" not found, skipped', Repr(ref))
+@@ -137,4 +137,4 @@ if __name__ == '__main__':
+     x = ('x', ())
+     L = DepList()
+     L.add(c, e, d, b, f, a, x)
+-    print [x[0] for x in L.sort()]
++    print([x[0] for x in L.sort()])
+--- suds/xsd/query.py.orig	2021-09-20 17:08:56 UTC
++++ suds/xsd/query.py
+@@ -54,7 +54,7 @@ class Query(Object):
+         @return: The item matching the search criteria.
+         @rtype: L{sxbase.SchemaObject}
+         """
+-        raise Exception, 'not-implemented by subclass'
++        raise Exception('not-implemented by subclass')
+ 
+     def filter(self, result):
+         """
+--- suds/xsd/sxbasic.py.orig	2021-09-20 17:08:56 UTC
++++ suds/xsd/sxbasic.py
+@@ -26,7 +26,7 @@ from suds.xsd.query import *
+ from suds.sax import Namespace
+ from suds.transport import TransportError
+ from suds.reader import DocumentReader
+-from urlparse import urljoin
++from urllib.parse import urljoin
+ 
+ from logging import getLogger
+ log = getLogger(__name__)
+@@ -667,7 +667,7 @@ class Include(SchemaObject):
+             root.set(TNS, tns)
+         else:
+             if self.schema.tns[1] != tns:
+-                raise Exception, '%s mismatch' % TNS
++                raise Exception('%s mismatch' % TNS)
+ 
+ 
+     def description(self):
+--- tests/external/axis1.py.orig	2021-09-20 17:08:56 UTC
++++ tests/external/axis1.py
+@@ -36,34 +36,34 @@ credentials = dict(username='jortel', password='abc123
+ class MyInitPlugin(InitPlugin):
+ 
+     def initialized(self, context):
+-        print 'PLUGIN (init): initialized: ctx=%s' % context.__dict__
++        print('PLUGIN (init): initialized: ctx=%s' % context.__dict__)
+ 
+ 
+ class MyDocumentPlugin(DocumentPlugin):
+ 
+     def loaded(self, context):
+-        print 'PLUGIN (document): loaded: ctx=%s' % context.__dict__
++        print('PLUGIN (document): loaded: ctx=%s' % context.__dict__)
+ 
+     def parsed(self, context):
+-        print 'PLUGIN (document): parsed: ctx=%s' % context.__dict__
++        print('PLUGIN (document): parsed: ctx=%s' % context.__dict__)
+ 
+ 
+ class MyMessagePlugin(MessagePlugin):
+ 
+     def marshalled(self, context):
+-        print 'PLUGIN (message): marshalled: ctx=%s' % context.__dict__
++        print('PLUGIN (message): marshalled: ctx=%s' % context.__dict__)
+ 
+     def sending(self, context):
+-        print 'PLUGIN (message): sending: ctx=%s' % context.__dict__
++        print('PLUGIN (message): sending: ctx=%s' % context.__dict__)
+ 
+     def received(self, context):
+-        print 'PLUGIN (message): received: ctx=%s' % context.__dict__
++        print('PLUGIN (message): received: ctx=%s' % context.__dict__)
+ 
+     def parsed(self, context):
+-        print 'PLUGIN (message): parsed: ctx=%s' % context.__dict__
++        print('PLUGIN (message): parsed: ctx=%s' % context.__dict__)
+ 
+     def unmarshalled(self, context):
+-        print 'PLUGIN: (massage): unmarshalled: ctx=%s' % context.__dict__
++        print('PLUGIN: (massage): unmarshalled: ctx=%s' % context.__dict__)
+ 
+ 
+ myplugins = (
+@@ -75,27 +75,27 @@ myplugins = (
+ 
+ def start(url):
+     global errors
+-    print '\n________________________________________________________________\n'
+-    print 'Test @ ( %s )\nerrors = %d\n' % (url, errors)
++    print('\n________________________________________________________________\n')
++    print('Test @ ( %s )\nerrors = %d\n' % (url, errors))
+ 
+ try:
+     url = 'http://localhost:8081/axis/services/basic-rpc-encoded?wsdl'
+     start(url)
+     t = HttpAuthenticated(**credentials)
+     client = Client(url, transport=t, cache=None, plugins=myplugins)
+-    print client
++    print(client)
+     #
+     # create a name object using the wsdl
+     #
+-    print 'create name'
++    print('create name')
+     name = client.factory.create('ns0:Name')
+-    name.first = u'jeff'+unichr(1234)
++    name.first = 'jeff'+chr(1234)
+     name.last = 'ortel'
+-    print name
++    print(name)
+     #
+     # create a phone object using the wsdl
+     #
+-    print 'create phone'
++    print('create phone')
+     phoneA = client.factory.create('ns0:Phone')
+     phoneA.npa = 410
+     phoneA.nxx = 555
+@@ -119,18 +119,18 @@ try:
+     # create a person object using the wsdl
+     #
+     person = client.factory.create('ns0:Person')
+-    print '{empty} person=\n%s' % person
++    print('{empty} person=\n%s' % person)
+     person.name = name
+     person.age = 43
+     person.phone = [phoneA,phoneB,phoneC]
+     person.pets = [dog]
+-    print 'person=\n%s' % person
++    print('person=\n%s' % person)
+     #
+     # add the person (using the webservice)
+     #
+-    print 'addPersion()'
++    print('addPersion()')
+     result = client.service.addPerson(person)
+-    print '\nreply(\n%s\n)\n' % str(result)
++    print('\nreply(\n%s\n)\n' % str(result))
+ 
+     #
+     # Async
+@@ -159,22 +159,22 @@ try:
+     ap.age = person.age
+     ap.phone = person.phone
+     ap.pets = person.pets
+-    print 'AnotherPerson\n%s' % ap
++    print('AnotherPerson\n%s' % ap)
+     #
+     # update the person's name (using the webservice)
+     #
+-    print 'updatePersion()'
++    print('updatePersion()')
+     result = client.service.updatePerson(ap, newname)
+-    print '\nreply(\n%s\n)\n' % str(result)
++    print('\nreply(\n%s\n)\n' % str(result))
+     result = client.service.updatePerson(ap, None)
+-    print '\nreply(\n%s\n)\n' % str(result)
+-except WebFault, f:
++    print('\nreply(\n%s\n)\n' % str(result))
++except WebFault as f:
+     errors += 1
+-    print f
+-    print f.fault
+-except Exception, e:
++    print(f)
++    print(f.fault)
++except Exception as e:
+     errors += 1
+-    print e
++    print(e)
+     tb.print_exc()
+ 
+ try:
+@@ -182,19 +182,19 @@ try:
+     start(url)
+     t = HttpAuthenticated(**credentials)
+     client = Client(url, transport=t, cache=None)
+-    print client
++    print(client)
+     #
+     # create a name object as dict
+     #
+-    print 'create name'
++    print('create name')
+     name = {}
+     name['first'] = 'Elmer'
+     name['last'] = 'Fudd'
+-    print name
++    print(name)
+     #
+     # create a phone as dict
+     #
+-    print 'create phone'
++    print('create phone')
+     phoneA = {}
+     phoneA['npa'] = 410
+     phoneA['nxx'] = 555
+@@ -219,133 +219,133 @@ try:
+     # create a person as dict
+     #
+     person = {}
+-    print '{empty} person=\n%s' % person
++    print('{empty} person=\n%s' % person)
+     person['name'] = name
+     person['age'] = 43
+     person['phone'] = [phoneA,phoneB, phoneC]
+     person['pets'] = [dog]
+-    print 'person=\n%s' % person
++    print('person=\n%s' % person)
+     #
+     # add the person (using the webservice)
+     #
+-    print 'addPersion()'
++    print('addPersion()')
+     result = client.service.addPerson(person)
+-    print '\nreply(\n%s\n)\n' % str(result)
+-except WebFault, f:
++    print('\nreply(\n%s\n)\n' % str(result))
++except WebFault as f:
+     errors += 1
+-    print f
*** 1074 LINES SKIPPED ***