From nobody Fri Mar 25 13:50:14 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 EE5FE1A33F3A; Fri, 25 Mar 2022 13:50:16 +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 4KQ3Ph0TF8z3QxN; Fri, 25 Mar 2022 13:50:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648216216; 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=LjCwk49SEcwFl+uDIrgZ4DpE2f85UM5vvmWzRjNVaDI=; b=mCJfhp/tFFxdJ00ebQBO24DT46D0ioyOMyL6JLGVbnqO6Qop/BxJ8/EwCbfeLj1/9WDDEo s4AfnF2f1Zcp0NzB5RmaMp39CwQuS5h4hXo11PODK5iKA5K9TZaYMQycs2hop2gpcX8jOP xi8HtGfHA5YNcx7iBsuyNNmTdgfaZbHP+xpDJO38o8iB72pyAPWDJyWbpAFVGHtlJT5BRt qbHnMY/ViJq5cj9Sk2etdIzKPm9T5Adp+PxYzut9SqDt1oRh5caWMoGguvpFYRMwD3BuhY BZdYeRob5pRXEpZmF91VyTlNxPcX3k+E2YTJ8xfJPemJJbkmuKAlTy3xaAp6/Q== 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 0E4FF5950; Fri, 25 Mar 2022 13:50:15 +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 22PDoEjL033465; Fri, 25 Mar 2022 13:50:14 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22PDoEW8033451; Fri, 25 Mar 2022 13:50:14 GMT (envelope-from git) Date: Fri, 25 Mar 2022 13:50:14 GMT Message-Id: <202203251350.22PDoEW8033451@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: 7e3893dcbb58 - main - devel/py-testoob: 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: 7e3893dcbb5817683ec6cb20d0e13a453bc05ff7 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648216216; 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=LjCwk49SEcwFl+uDIrgZ4DpE2f85UM5vvmWzRjNVaDI=; b=wzUdWsIbc6Y35Z78sxh/4vFod//0VzCzKDDwAVkpkmbrWwI8BeU7TWBPCS+b5sYJe/UC6e MFSQxTNZax4O0R0wRX+252cYIrH7TRMQCZT6ugJCsJ8ZZYE9O7w6ueDmjLfSsLtFL0jSyk V77AfBmaQZfHfrWeNxS/DYILCkbf+4cgy3xTDbbWDgfJSXmFueC9baV2gouFdotozr4jLT 1KVExLOMyEx+omnph70jzKy0aLzg3y2ennC5invKbDp2Zw9gUXonM9UyYLdPLPC9YNkLzp oJkDGOle2ltnasbJpssBq6NVzif61IhSA+98RaFeXFf04JK7b5fv+XzAhO/DiA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1648216216; a=rsa-sha256; cv=none; b=K1BYLrhoHELx6SzjmtKU3jWlQ2LR680sGRlDfnK93GvwMxRaaqF/j/04PohSsUWxoxdeoF 5x/xvKsUFwspX6H1VvY6sjPtKwXIUsdXmwZVFDJUa9lIjJFm9vBFlGCK4ZOUZ9gMXYD9AQ BCVu+mMH135xpLWLe32tRTZOMcn3za8UAmnaQNJStZ44alCUxS9WUawpv50zPLMxiU1JCJ Hzliru8+LVIrg57tg8K5qkLgR3Uc3c5HgSVZsR6FQsEvwTtGBYvmCMFA6sFxKcj/+R9P/H vPOpIdl1tTcWytFUo/2kiW06bWjoGqpKavP1mvjXnufA1cPXIO42jJOpMBCYTg== 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=7e3893dcbb5817683ec6cb20d0e13a453bc05ff7 commit 7e3893dcbb5817683ec6cb20d0e13a453bc05ff7 Author: Po-Chuan Hsieh AuthorDate: 2022-03-25 13:32:25 +0000 Commit: Po-Chuan Hsieh CommitDate: 2022-03-25 13:38:12 +0000 devel/py-testoob: Fix build with setuptools 58.0.0+ With hat: python --- devel/py-testoob/Makefile | 2 +- devel/py-testoob/files/patch-2to3 | 1689 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1690 insertions(+), 1 deletion(-) diff --git a/devel/py-testoob/Makefile b/devel/py-testoob/Makefile index b0783cdc5231..0f181e61f91c 100644 --- a/devel/py-testoob/Makefile +++ b/devel/py-testoob/Makefile @@ -18,7 +18,7 @@ OPTIONS_DEFINE= TWISTED TWISTED_DESC= enable running in threads NO_ARCH= yes -USES= python:3.6+ tar:bzip2 +USES= dos2unix python:3.6+ tar:bzip2 USE_PYTHON= autoplist distutils TWISTED_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}twisted>=0:devel/py-twisted@${PY_FLAVOR} diff --git a/devel/py-testoob/files/patch-2to3 b/devel/py-testoob/files/patch-2to3 new file mode 100644 index 000000000000..3efb8ad30356 --- /dev/null +++ b/devel/py-testoob/files/patch-2to3 @@ -0,0 +1,1689 @@ +--- src/testoob/asserter.py.orig 2022-03-18 18:45:28 UTC ++++ src/testoob/asserter.py +@@ -32,7 +32,7 @@ class Asserter: + # Prevent recursion (accures in testoob tests, when ran with testoob :-) ). + if getattr(Class, method_name).__name__ == "_assert_reporting_func": + return +- variables = eval("Class.%s" % method_name).func_code.co_varnames ++ variables = eval("Class.%s" % method_name).__code__.co_varnames + setattr(Class, "_real_function_%s" % method_name, eval("Class.%s" % method_name)) + method = eval("Class._real_function_%s" % method_name) + def _assert_reporting_func(*args, **kwargs): +@@ -45,7 +45,7 @@ class Asserter: + num_free_args -= 1 + additional_args = args[num_free_args:] + additional_args + # Can't be a dictionary, because the order matters. +- varList = zip(variables[1:], (args[1:num_free_args] + additional_args)) ++ varList = list(zip(variables[1:], (args[1:num_free_args] + additional_args))) + # Here is some evil did to find the function which called me. + test = sys._getframe().f_back.f_locals["self"] + # If we run something that has no reporter, it should just run +@@ -54,7 +54,7 @@ class Asserter: + return method(*args, **kwargs) + try: + method(*args, **kwargs) +- except Exception, e: ++ except Exception as e: + self._reporters[test].addAssert(test, method_name, varList, e) + raise + self._reporters[test].addAssert(test, method_name, varList, None) +--- src/testoob/commandline/__init__.py.orig 2022-03-18 18:45:28 UTC ++++ src/testoob/commandline/__init__.py +@@ -17,8 +17,8 @@ def module_list(): + + def load_options(): + for module in module_list(): +- exec "import %s" % module ++ exec("import %s" % module) + + load_options() + +-import parsing ++from . import parsing +--- src/testoob/compatibility/itertools.py.orig 2022-03-18 18:45:28 UTC ++++ src/testoob/compatibility/itertools.py +@@ -20,8 +20,8 @@ takewhile(pred, seq) --> seq[0], seq[1], until pred fa + dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails + groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v) + """ +-from __future__ import generators + ++ + __all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter', + 'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap', + 'takewhile', 'tee'] +@@ -48,14 +48,14 @@ class chain: + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + try: +- next_elt = self._cur_iterable_iter.next() ++ next_elt = next(self._cur_iterable_iter) + except StopIteration: + # The current list's iterator is exhausted, switch to next one +- self._cur_iterable_iter = iter(self._iterables_iter.next()) ++ self._cur_iterable_iter = iter(next(self._iterables_iter)) + try: +- next_elt = self._cur_iterable_iter.next() ++ next_elt = next(self._cur_iterable_iter) + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % \ +@@ -92,7 +92,7 @@ class count: + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + self.times += 1 + return self.times + +@@ -125,15 +125,15 @@ class cycle: + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + # XXX Could probably be improved + try: +- next_elt = self._cur_iter.next() ++ next_elt = next(self._cur_iter) + if self._must_save: + self._saved.append(next_elt) + except StopIteration: + self._cur_iter = iter(self._saved) +- next_elt = self._cur_iter.next() ++ next_elt = next(self._cur_iter) + self._must_save = False + except AttributeError: + # CPython raises a TypeError when next() is not defined +@@ -167,9 +167,9 @@ class dropwhile: + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + try: +- value = self._iter.next() ++ value = next(self._iter) + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % \ +@@ -177,7 +177,7 @@ class dropwhile: + if self._dropped: + return value + while self._predicate(value): +- value = self._iter.next() ++ value = next(self._iter) + self._dropped = True + return value + +@@ -205,15 +205,15 @@ class groupby: + key = lambda x: x + self.keyfunc = key + self.it = iter(iterable) +- self.tgtkey = self.currkey = self.currvalue = xrange(0) ++ self.tgtkey = self.currkey = self.currvalue = range(0) + + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + while self.currkey == self.tgtkey: + try: +- self.currvalue = self.it.next() # Exit on StopIteration ++ self.currvalue = next(self.it) # Exit on StopIteration + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % \ +@@ -225,7 +225,7 @@ class groupby: + def _grouper(self, tgtkey): + while self.currkey == tgtkey: + yield self.currvalue +- self.currvalue = self.it.next() # Exit on StopIteration ++ self.currvalue = next(self.it) # Exit on StopIteration + self.currkey = self.keyfunc(self.currvalue) + + +@@ -257,9 +257,9 @@ class ifilter(_ifilter_base): + if predicate(x): + yield x + """ +- def next(self): ++ def __next__(self): + try: +- next_elt = self._iter.next() ++ next_elt = next(self._iter) + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % \ +@@ -267,7 +267,7 @@ class ifilter(_ifilter_base): + while True: + if self._predicate(next_elt): + return next_elt +- next_elt = self._iter.next() ++ next_elt = next(self._iter) + + class ifilterfalse(_ifilter_base): + """Make an iterator that filters elements from iterable returning +@@ -283,9 +283,9 @@ class ifilterfalse(_ifilter_base): + if not predicate(x): + yield x + """ +- def next(self): ++ def __next__(self): + try: +- next_elt = self._iter.next() ++ next_elt = next(self._iter) + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % \ +@@ -293,7 +293,7 @@ class ifilterfalse(_ifilter_base): + while True: + if not self._predicate(next_elt): + return next_elt +- next_elt = self._iter.next() ++ next_elt = next(self._iter) + + + +@@ -322,14 +322,14 @@ class imap: + """ + def __init__(self, function, iterable, *other_iterables): + self._func = function +- self._iters = map(iter, (iterable, ) + other_iterables) ++ self._iters = list(map(iter, (iterable, ) + other_iterables)) + + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + try: +- args = [it.next() for it in self._iters] ++ args = [next(it) for it in self._iters] + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % \ +@@ -357,15 +357,15 @@ class islice: + def __init__(self, iterable, *args): + s = slice(*args) + self.start, self.stop, self.step = s.start or 0, s.stop, s.step +- if not isinstance(self.start, (int, long)): ++ if not isinstance(self.start, int): + raise ValueError("Start argument must be an integer") +- if self.stop is not None and not isinstance(self.stop, (int,long)): ++ if self.stop is not None and not isinstance(self.stop, int): + raise ValueError("Stop argument must be an integer or None") + if self.step is None: + self.step = 1 + if self.start<0 or (self.stop is not None and self.stop<0 + ) or self.step<=0: +- raise ValueError, "indices for islice() must be positive" ++ raise ValueError("indices for islice() must be positive") + self.it = iter(iterable) + self.donext = None + self.cnt = 0 +@@ -373,10 +373,10 @@ class islice: + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + if self.donext is None: + try: +- self.donext = self.it.next ++ self.donext = self.it.__next__ + except AttributeError: + raise TypeError + while self.cnt < self.start: +@@ -403,17 +403,17 @@ class izip: + yield tuple(result) + """ + def __init__(self, *iterables): +- self._iterators = map(iter, iterables) ++ self._iterators = list(map(iter, iterables)) + self._result = [None] * len(self._iterators) + + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + if not self._iterators: + raise StopIteration() + try: +- return tuple([i.next() for i in self._iterators]) ++ return tuple([next(i) for i in self._iterators]) + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % (i)) +@@ -439,7 +439,7 @@ class repeat: + def __init__(self, obj, times=None): + self._obj = obj + if times is not None: +- xrange(times) # Raise a TypeError ++ range(times) # Raise a TypeError + if times < 0: + times = 0 + self._times = times +@@ -447,7 +447,7 @@ class repeat: + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + # next() *need* to decrement self._times when consumed + if self._times is not None: + if self._times <= 0: +@@ -489,10 +489,10 @@ class starmap: + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + # CPython raises a TypeError when the iterator doesn't return a tuple + try: +- t = self._iter.next() ++ t = next(self._iter) + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % self._iter) +@@ -522,9 +522,9 @@ class takewhile: + def __iter__(self): + return self + +- def next(self): ++ def __next__(self): + try: +- value = self._iter.next() ++ value = next(self._iter) + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % \ +@@ -544,7 +544,7 @@ class TeeData(object): + # iterates until 'i' if not done yet + while i>= len(self.data): + try: +- self.data.append( self._iter.next() ) ++ self.data.append( next(self._iter) ) + except AttributeError: + # CPython raises a TypeError when next() is not defined + raise TypeError('%s has no next() method' % self._iter) +@@ -565,7 +565,7 @@ class TeeObject(object): + self.tee_data = TeeData(iter(iterable)) + self.pos = 0 + +- def next(self): ++ def __next__(self): + data = self.tee_data[self.pos] + self.pos += 1 + return data +@@ -603,6 +603,6 @@ def tee(iterable, n=2): + if isinstance(iterable, TeeObject): + # a,b = tee(range(10)) ; c,d = tee(a) ; self.assert_(a is c) + return tuple([iterable] + +- [TeeObject(tee_data=iterable.tee_data) for i in xrange(n-1)]) ++ [TeeObject(tee_data=iterable.tee_data) for i in range(n-1)]) + tee_data = TeeData(iter(iterable)) +- return tuple([TeeObject(tee_data=tee_data) for i in xrange(n)]) ++ return tuple([TeeObject(tee_data=tee_data) for i in range(n)]) +--- src/testoob/compatibility/optparse.py.orig 2022-03-18 18:45:28 UTC ++++ src/testoob/compatibility/optparse.py +@@ -70,7 +70,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH D + + import sys, os + import types +-import textwrap ++from . import textwrap + + class OptParseError (Exception): + def __init__ (self, msg): +@@ -161,10 +161,10 @@ class HelpFormatter: + self.level -= 1 + + def format_usage (self, usage): +- raise NotImplementedError, "subclasses must implement" ++ raise NotImplementedError("subclasses must implement") + + def format_heading (self, heading): +- raise NotImplementedError, "subclasses must implement" ++ raise NotImplementedError("subclasses must implement") + + def format_description (self, description): + desc_width = self.width - self.current_indent +@@ -280,7 +280,7 @@ class TitledHelpFormatter (HelpFormatter): + + + _builtin_cvt = { "int" : (int, "integer"), +- "long" : (long, "long integer"), ++ "long" : (int, "long integer"), + "float" : (float, "floating-point"), + "complex" : (complex, "complex") } + +@@ -434,7 +434,7 @@ class Option: + # Filter out None because early versions of Optik had exactly + # one short option and one long option, either of which + # could be None. +- opts = filter(None, opts) ++ opts = [_f for _f in opts if _f] + if not opts: + raise TypeError("at least one option string must be supplied") + return opts +@@ -462,7 +462,7 @@ class Option: + + def _set_attrs (self, attrs): + for attr in self.ATTRS: +- if attrs.has_key(attr): ++ if attr in attrs: + setattr(self, attr, attrs[attr]) + del attrs[attr] + else: +@@ -472,7 +472,7 @@ class Option: + setattr(self, attr, None) + if attrs: + raise OptionError( +- "invalid keyword arguments: %s" % ", ".join(attrs.keys()), ++ "invalid keyword arguments: %s" % ", ".join(list(attrs.keys())), + self) + + +@@ -507,7 +507,7 @@ class Option: + if self.choices is None: + raise OptionError( + "must supply a list of choices for type 'choice'", self) +- elif type(self.choices) not in (types.TupleType, types.ListType): ++ elif type(self.choices) not in (tuple, list): + raise OptionError( + "choices must be a list of strings ('%s' supplied)" + % str(type(self.choices)).split("'")[1], self) +@@ -547,12 +547,12 @@ class Option: + raise OptionError( + "callback not callable: %r" % self.callback, self) + if (self.callback_args is not None and +- type(self.callback_args) is not types.TupleType): ++ type(self.callback_args) is not tuple): + raise OptionError( + "callback_args, if supplied, must be a tuple: not %r" + % self.callback_args, self) + if (self.callback_kwargs is not None and +- type(self.callback_kwargs) is not types.DictType): ++ type(self.callback_kwargs) is not dict): + raise OptionError( + "callback_kwargs, if supplied, must be a dict: not %r" + % self.callback_kwargs, self) +@@ -636,7 +636,7 @@ class Option: + parser.print_version() + sys.exit(0) + else: +- raise RuntimeError, "unknown action %r" % self.action ++ raise RuntimeError("unknown action %r" % self.action) + + return 1 + +@@ -662,7 +662,7 @@ class Values: + + def __init__ (self, defaults=None): + if defaults: +- for (attr, val) in defaults.items(): ++ for (attr, val) in list(defaults.items()): + setattr(self, attr, val) + + def __repr__ (self): +@@ -677,7 +677,7 @@ class Values: + are silently ignored. + """ + for attr in dir(self): +- if dict.has_key(attr): ++ if attr in dict: + dval = dict[attr] + if dval is not None: + setattr(self, attr, dval) +@@ -696,7 +696,7 @@ class Values: + elif mode == "loose": + self._update_loose(dict) + else: +- raise ValueError, "invalid update mode: %r" % mode ++ raise ValueError("invalid update mode: %r" % mode) + + def read_module (self, modname, mode="careful"): + __import__(modname) +@@ -705,7 +705,7 @@ class Values: + + def read_file (self, filename, mode="careful"): + vars = {} +- execfile(filename, vars) ++ exec(compile(open(filename, "rb").read(), filename, 'exec'), vars) + self._update(vars, mode) + + def ensure_value (self, attr, value): +@@ -775,7 +775,7 @@ class OptionContainer: + + def set_conflict_handler (self, handler): + if handler not in ("ignore", "error", "resolve"): +- raise ValueError, "invalid conflict_resolution value %r" % handler ++ raise ValueError("invalid conflict_resolution value %r" % handler) + self.conflict_handler = handler + + def set_description (self, description): +@@ -787,10 +787,10 @@ class OptionContainer: + def _check_conflict (self, option): + conflict_opts = [] + for opt in option._short_opts: +- if self._short_opt.has_key(opt): ++ if opt in self._short_opt: + conflict_opts.append((opt, self._short_opt[opt])) + for opt in option._long_opts: +- if self._long_opt.has_key(opt): ++ if opt in self._long_opt: + conflict_opts.append((opt, self._long_opt[opt])) + + if conflict_opts: +@@ -817,14 +817,14 @@ class OptionContainer: + """add_option(Option) + add_option(opt_str, ..., kwarg=val, ...) + """ +- if type(args[0]) is types.StringType: ++ if type(args[0]) is bytes: + option = self.option_class(*args, **kwargs) + elif len(args) == 1 and not kwargs: + option = args[0] + if not isinstance(option, Option): +- raise TypeError, "not an Option instance: %r" % option ++ raise TypeError("not an Option instance: %r" % option) + else: +- raise TypeError, "invalid arguments" ++ raise TypeError("invalid arguments") + + self._check_conflict(option) + +@@ -838,7 +838,7 @@ class OptionContainer: + if option.dest is not None: # option has a dest, we need a default + if option.default is not NO_DEFAULT: + self.defaults[option.dest] = option.default +- elif not self.defaults.has_key(option.dest): ++ elif option.dest not in self.defaults: + self.defaults[option.dest] = None + + return option +@@ -854,8 +854,8 @@ class OptionContainer: + self._long_opt.get(opt_str)) + + def has_option (self, opt_str): +- return (self._short_opt.has_key(opt_str) or +- self._long_opt.has_key(opt_str)) ++ return (opt_str in self._short_opt or ++ opt_str in self._long_opt) + + def remove_option (self, opt_str): + option = self._short_opt.get(opt_str) +@@ -1065,16 +1065,16 @@ class OptionParser (OptionContainer): + + def add_option_group (self, *args, **kwargs): + # XXX lots of overlap with OptionContainer.add_option() +- if type(args[0]) is types.StringType: ++ if type(args[0]) is bytes: + group = OptionGroup(self, *args, **kwargs) + elif len(args) == 1 and not kwargs: + group = args[0] + if not isinstance(group, OptionGroup): +- raise TypeError, "not an OptionGroup instance: %r" % group ++ raise TypeError("not an OptionGroup instance: %r" % group) + if group.parser is not self: +- raise ValueError, "invalid OptionGroup (wrong parser)" ++ raise ValueError("invalid OptionGroup (wrong parser)") + else: +- raise TypeError, "invalid arguments" ++ raise TypeError("invalid arguments") + + self.option_groups.append(group) + return group +@@ -1128,7 +1128,7 @@ class OptionParser (OptionContainer): + + try: + stop = self._process_args(largs, rargs, values) +- except (BadOptionError, OptionValueError), err: ++ except (BadOptionError, OptionValueError) as err: + self.error(err.msg) + + args = largs + rargs +@@ -1313,7 +1313,7 @@ class OptionParser (OptionContainer): + or not defined. + """ + if self.usage: +- print >>file, self.get_usage() ++ print(self.get_usage(), file=file) + + def get_version (self): + if self.version: +@@ -1330,7 +1330,7 @@ class OptionParser (OptionContainer): + name. Does nothing if self.version is empty or undefined. + """ + if self.version: +- print >>file, self.get_version() ++ print(self.get_version(), file=file) + + def format_option_help (self, formatter=None): + if formatter is None: +@@ -1381,11 +1381,11 @@ def _match_abbrev (s, wordmap): + 'words', raise BadOptionError. + """ + # Is there an exact match? +- if wordmap.has_key(s): ++ if s in wordmap: + return s + else: + # Isolate all words with s as a prefix. +- possibilities = [word for word in wordmap.keys() ++ possibilities = [word for word in list(wordmap.keys()) + if word.startswith(s)] + # No exact match, so there had better be just one possibility. + if len(possibilities) == 1: +--- src/testoob/compatibility/sets.py.orig 2022-03-18 18:45:28 UTC ++++ src/testoob/compatibility/sets.py +@@ -54,9 +54,9 @@ what's tested is actually `z in y'. + # - Raymond Hettinger added a number of speedups and other + # improvements. + +-from __future__ import generators ++ + try: +- from itertools import ifilter, ifilterfalse ++ from .itertools import ifilter, ifilterfalse + except ImportError: + # Code to make the module run under Py2.2 + def ifilter(predicate, iterable): +@@ -73,10 +73,6 @@ except ImportError: + for x in iterable: + if not predicate(x): + yield x +- try: +- True, False +- except NameError: +- True, False = (0==0, 0!=0) + + __all__ = ['BaseSet', 'Set', 'ImmutableSet'] + +@@ -91,7 +87,7 @@ class BaseSet(object): + """This is an abstract class.""" + # Don't call this from a concrete subclass! + if self.__class__ is BaseSet: +- raise TypeError, ("BaseSet is an abstract class. " ++ raise TypeError("BaseSet is an abstract class. " + "Use Set or ImmutableSet.") + + # Standard protocols: __len__, __repr__, __str__, __iter__ +@@ -111,7 +107,7 @@ class BaseSet(object): + __str__ = __repr__ + + def _repr(self, sorted=False): +- elements = self._data.keys() ++ elements = list(self._data.keys()) + if sorted: + elements.sort() + return '%s(%r)' % (self.__class__.__name__, elements) +@@ -121,7 +117,7 @@ class BaseSet(object): + + This is the keys iterator for the underlying dict. + """ +- return self._data.iterkeys() ++ return iter(self._data.keys()) + + # Three-way comparison is not supported. However, because __eq__ is + # tried before __cmp__, if Set x == Set y, x.__eq__(y) returns True and +@@ -129,7 +125,7 @@ class BaseSet(object): + # case). + + def __cmp__(self, other): +- raise TypeError, "can't compare sets using cmp()" ++ raise TypeError("can't compare sets using cmp()") + + # Equality comparisons using the underlying dicts. Mixed-type comparisons + # are allowed here, where Set == z for non-Set z always returns False, +@@ -231,7 +227,7 @@ class BaseSet(object): + little, big = self, other + else: + little, big = other, self +- common = ifilter(big._data.has_key, little) ++ common = filter(big._data.has_key, little) + return self.__class__(common) + + def __xor__(self, other): +@@ -256,9 +252,9 @@ class BaseSet(object): + otherdata = other._data + except AttributeError: + otherdata = Set(other)._data +- for elt in ifilterfalse(otherdata.has_key, selfdata): ++ for elt in filterfalse(otherdata.has_key, selfdata): + data[elt] = value +- for elt in ifilterfalse(selfdata.has_key, otherdata): ++ for elt in filterfalse(selfdata.has_key, otherdata): + data[elt] = value + return result + +@@ -283,7 +279,7 @@ class BaseSet(object): + except AttributeError: + otherdata = Set(other)._data + value = True +- for elt in ifilterfalse(otherdata.has_key, self): ++ for elt in filterfalse(otherdata.has_key, self): + data[elt] = value + return result + +@@ -309,7 +305,7 @@ class BaseSet(object): + self._binary_sanity_check(other) + if len(self) > len(other): # Fast check for obvious cases + return False +- for elt in ifilterfalse(other._data.has_key, self): ++ for elt in filterfalse(other._data.has_key, self): + return False + return True + +@@ -318,7 +314,7 @@ class BaseSet(object): + self._binary_sanity_check(other) + if len(self) < len(other): # Fast check for obvious cases + return False +- for elt in ifilterfalse(self._data.has_key, other): ++ for elt in filterfalse(self._data.has_key, other): + return False + return True + +@@ -340,7 +336,7 @@ class BaseSet(object): + # Check that the other argument to a binary operation is also + # a set, raising a TypeError otherwise. + if not isinstance(other, BaseSet): +- raise TypeError, "Binary operation only permitted between sets" ++ raise TypeError("Binary operation only permitted between sets") + + def _compute_hash(self): + # Calculate hash code for a set by xor'ing the hash codes of +@@ -438,7 +434,7 @@ class Set(BaseSet): + def __hash__(self): + """A Set cannot be hashed.""" + # We inherit object.__hash__, so we must deny this explicitly +- raise TypeError, "Can't hash a Set, only an ImmutableSet." ++ raise TypeError("Can't hash a Set, only an ImmutableSet.") + + # In-place union, intersection, differences. + # Subtle: The xyz_update() functions deliberately return None, +@@ -501,7 +497,7 @@ class Set(BaseSet): + other = Set(other) + if self is other: + self.clear() +- for elt in ifilter(data.has_key, other): ++ for elt in filter(data.has_key, other): + del data[elt] + + # Python dict-like mass mutations: update, clear +--- src/testoob/compatibility/subprocess.py.orig 2022-03-18 18:45:28 UTC ++++ src/testoob/compatibility/subprocess.py +@@ -403,13 +403,6 @@ try: + except: + MAXFD = 256 + +-# True/False does not exist on 2.2.0 +-try: +- False +-except NameError: +- False = 0 +- True = 1 +- + _active = [] + + def _cleanup(): +@@ -600,7 +593,7 @@ class Popen(object): + # Detach and turn into fd + p2cwrite = p2cwrite.Detach() + p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0) +- elif type(stdin) == types.IntType: ++ elif type(stdin) == int: + p2cread = msvcrt.get_osfhandle(stdin) + else: + # Assuming file-like object +@@ -614,7 +607,7 @@ class Popen(object): + # Detach and turn into fd + c2pread = c2pread.Detach() + c2pread = msvcrt.open_osfhandle(c2pread, 0) +- elif type(stdout) == types.IntType: ++ elif type(stdout) == int: + c2pwrite = msvcrt.get_osfhandle(stdout) + else: + # Assuming file-like object +@@ -630,7 +623,7 @@ class Popen(object): + errread = msvcrt.open_osfhandle(errread, 0) + elif stderr == STDOUT: + errwrite = c2pwrite +- elif type(stderr) == types.IntType: ++ elif type(stderr) == int: + errwrite = msvcrt.get_osfhandle(stderr) + else: + # Assuming file-like object +@@ -673,13 +666,13 @@ class Popen(object): + errread, errwrite): + """Execute program (MS Windows version)""" + +- if not isinstance(args, types.StringTypes): ++ if not isinstance(args, (str,)): + args = list2cmdline(args) + + if shell: + comspec = os.environ.get("COMSPEC", "cmd.exe") + args = comspec + " /c " + args +- if (GetVersion() >= 0x80000000L or ++ if (GetVersion() >= 0x80000000 or + os.path.basename(comspec).lower() == "command.com"): + # Win9x, or using command.com on NT. We need to + # use the w9xpopen intermediate program. For more +@@ -716,7 +709,7 @@ class Popen(object): + env, + cwd, + startupinfo) +- except pywintypes.error, e: ++ except pywintypes.error as e: + # Translate pywintypes.error to WindowsError, which is + # a subclass of OSError. FIXME: We should really + # translate errno using _sys_errlist (or simliar), but +@@ -835,7 +828,7 @@ class Popen(object): + pass + elif stdin == PIPE: + p2cread, p2cwrite = os.pipe() +- elif type(stdin) == types.IntType: ++ elif type(stdin) == int: + p2cread = stdin + else: + # Assuming file-like object +@@ -845,7 +838,7 @@ class Popen(object): + pass + elif stdout == PIPE: + c2pread, c2pwrite = os.pipe() +- elif type(stdout) == types.IntType: ++ elif type(stdout) == int: + c2pwrite = stdout + else: + # Assuming file-like object +@@ -857,7 +850,7 @@ class Popen(object): + errread, errwrite = os.pipe() + elif stderr == STDOUT: + errwrite = c2pwrite +- elif type(stderr) == types.IntType: ++ elif type(stderr) == int: + errwrite = stderr + else: + # Assuming file-like object +@@ -896,7 +889,7 @@ class Popen(object): + errread, errwrite): + """Execute program (POSIX version)""" + +- if isinstance(args, types.StringTypes): ++ if isinstance(args, (str,)): + args = [args] + + if shell: +@@ -1100,8 +1093,8 @@ def _demo_posix(): + # Example 1: Simple redirection: Get process list + # + plist = Popen(["ps"], stdout=PIPE).communicate()[0] +- print "Process list:" +- print plist ++ print("Process list:") ++ print(plist) + + # + # Example 2: Change uid before executing child +@@ -1113,42 +1106,42 @@ def _demo_posix(): + # + # Example 3: Connecting several subprocesses + # +- print "Looking for 'hda'..." ++ print("Looking for 'hda'...") + p1 = Popen(["dmesg"], stdout=PIPE) + p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) +- print repr(p2.communicate()[0]) ++ print(repr(p2.communicate()[0])) + + # + # Example 4: Catch execution error + # +- print +- print "Trying a weird file..." ++ print() ++ print("Trying a weird file...") + try: +- print Popen(["/this/path/does/not/exist"]).communicate() +- except OSError, e: ++ print(Popen(["/this/path/does/not/exist"]).communicate()) ++ except OSError as e: + if e.errno == errno.ENOENT: +- print "The file didn't exist. I thought so..." +- print "Child traceback:" +- print e.child_traceback ++ print("The file didn't exist. I thought so...") ++ print("Child traceback:") ++ print(e.child_traceback) + else: +- print "Error", e.errno ++ print("Error", e.errno) + else: +- print >>sys.stderr, "Gosh. No error." ++ print("Gosh. No error.", file=sys.stderr) + + + def _demo_windows(): + # + # Example 1: Connecting several subprocesses + # +- print "Looking for 'PROMPT' in set output..." ++ print("Looking for 'PROMPT' in set output...") + p1 = Popen("set", stdout=PIPE, shell=True) + p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE) +- print repr(p2.communicate()[0]) ++ print(repr(p2.communicate()[0])) + + # + # Example 2: Simple execution of program + # +- print "Executing calc..." ++ print("Executing calc...") + p = Popen("calc") + p.wait() + +--- src/testoob/compatibility/textwrap.py.orig 2022-03-18 18:45:28 UTC ++++ src/testoob/compatibility/textwrap.py +@@ -10,14 +10,6 @@ __revision__ = "$Id: textwrap.py,v 1.32.8.2 2004/05/13 + + import string, re + +-# Do the right thing with boolean values for all known Python versions +-# (so this module can be copied to projects that don't depend on Python +-# 2.3, e.g. Optik and Docutils). +-try: +- True, False +-except NameError: +- (True, False) = (1, 0) +- + __all__ = ['TextWrapper', 'wrap', 'fill'] + + # Hardcode the recognized whitespace characters to the US-ASCII +@@ -69,7 +61,7 @@ class TextWrapper: + whitespace_trans = string.maketrans(_whitespace, ' ' * len(_whitespace)) + + unicode_whitespace_trans = {} +- uspace = ord(u' ') ++ uspace = ord(' ') + for x in map(ord, _whitespace): + unicode_whitespace_trans[x] = uspace + +@@ -123,7 +115,7 @@ class TextWrapper: + if self.replace_whitespace: + if isinstance(text, str): + text = text.translate(self.whitespace_trans) +- elif isinstance(text, unicode): ++ elif isinstance(text, str): + text = text.translate(self.unicode_whitespace_trans) + return text + +@@ -140,7 +132,7 @@ class TextWrapper: + 'use', ' ', 'the', ' ', '-b', ' ', 'option!' + """ + chunks = self.wordsep_re.split(text) +- chunks = filter(None, chunks) ++ chunks = [_f for _f in chunks if _f] + return chunks + + def _fix_sentence_endings(self, chunks): +--- src/testoob/compatibility/trace.py.orig 2022-03-18 18:45:28 UTC ++++ src/testoob/compatibility/trace.py +@@ -59,7 +59,7 @@ import types + import gc + + try: +- import cPickle ++ import pickle + pickle = cPickle + except ImportError: + import pickle +@@ -116,11 +116,11 @@ class Ignore: + self._mods = modules or [] + self._dirs = dirs or [] *** 739 LINES SKIPPED ***