Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-invocations for 
openSUSE:Factory checked in at 2023-01-04 18:09:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-invocations (Old)
 and      /work/SRC/openSUSE:Factory/.python-invocations.new.1563 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-invocations"

Wed Jan  4 18:09:55 2023 rev:11 rq:1046403 version:3.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-invocations/python-invocations.changes    
2022-10-01 17:42:59.705652522 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-invocations.new.1563/python-invocations.changes
  2023-01-04 18:09:57.516319508 +0100
@@ -1,0 +2,12 @@
+Tue Jan  3 05:02:34 UTC 2023 - Steve Kowalik <steven.kowa...@suse.com>
+
+- Update to 3.0.0:
+  * The dual_wheels, alt_python, and check_desc arguments/config options for
+    the invocations.packaging.release module have been removed.
+  * The invocations.travis module has been removed.
+  * Drop Python 2 (and 3.5) support. We now support Python 3.6+ only.
+- Refreshed invocations-no-bundled.patch.
+- Dropped invocations-py3.patch, not required.
+- Dropped python-invocations-no-mock.patch, merged upstream.
+
+-------------------------------------------------------------------

Old:
----
  invocations-2.6.1.tar.gz
  invocations-py3.patch
  python-invocations-no-mock.patch

New:
----
  invocations-3.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-invocations.spec ++++++
--- /var/tmp/diff_new_pack.XtPWFz/_old  2023-01-04 18:09:58.256323870 +0100
+++ /var/tmp/diff_new_pack.XtPWFz/_new  2023-01-04 18:09:58.264323917 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-invocations
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,24 +16,19 @@
 #
 
 
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
-%bcond_without python2
 Name:           python-invocations
-Version:        2.6.1
+Version:        3.0.0
 Release:        0
 Summary:        Reusable Invoke tasks
 License:        BSD-2-Clause
 URL:            https://github.com/pyinvoke/invocations
 Source:         
https://github.com/pyinvoke/invocations/archive/%{version}.tar.gz#/invocations-%{version}.tar.gz
 Patch0:         invocations-no-bundled.patch
-Patch1:         invocations-py3.patch
-# https://github.com/pyinvoke/invocations/issues/31
-Patch2:         python-invocations-no-mock.patch
 BuildRequires:  %{python_module blessings >= 1.6}
-BuildRequires:  %{python_module invoke >= 1.6}
+BuildRequires:  %{python_module invoke >= 1.7.2}
 BuildRequires:  %{python_module lexicon}
 BuildRequires:  %{python_module pytest-relaxed}
-BuildRequires:  %{python_module releases >= 1.2}
+BuildRequires:  %{python_module releases >= 1.6}
 BuildRequires:  %{python_module semantic_version >= 2.4}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  %{python_module six}
@@ -44,9 +39,9 @@
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 Requires:       python-blessings >= 1.6
-Requires:       python-invoke >= 1.6
+Requires:       python-invoke >= 1.7.2
 Requires:       python-lexicon
-Requires:       python-releases >= 1.2
+Requires:       python-releases >= 1.6
 Requires:       python-semantic_version >= 2.4
 Requires:       python-six
 Requires:       python-tabulate >= 0.7.5
@@ -54,12 +49,6 @@
 Requires:       python-twine >= 1.15
 Requires:       python-wheel >= 0.24.0
 BuildArch:      noarch
-%if %{with python2}
-BuildRequires:  python-enum34
-%endif
-%ifpython2
-Requires:       python-enum34
-%endif
 %python_subpackages
 
 %description

++++++ invocations-2.6.1.tar.gz -> invocations-3.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/.circleci/config.yml 
new/invocations-3.0.0/.circleci/config.yml
--- old/invocations-2.6.1/.circleci/config.yml  2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/.circleci/config.yml  2022-12-31 23:12:06.000000000 
+0100
@@ -11,18 +11,18 @@
       - orb/format:
           name: Style check
       - orb/coverage:
-          name: Test 3.6 (w/ coverage)
+          name: Test
       - orb/test-release:
           name: Release test
       - orb/test:
           name: Test << matrix.version >>
           # It's not worth testing on other interpreters if the baseline one
           # failed. Can't run >4 jobs at a time anyhow!
-          requires: ["Test 3.6 (w/ coverage)"]
+          requires: ["Test"]
           matrix:
             parameters:
-              version: ["3.7", "3.8", "3.9"]
+              version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
       - orb/docs:
           name: "Docs"
-          requires: ["Test 3.6 (w/ coverage)"]
+          requires: ["Test"]
           task: "docs --nitpick"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/dev-requirements.txt 
new/invocations-3.0.0/dev-requirements.txt
--- old/invocations-2.6.1/dev-requirements.txt  2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/dev-requirements.txt  2022-12-31 23:12:06.000000000 
+0100
@@ -1,8 +1,11 @@
 # For testing
-pytest-relaxed>=1,<2
+pytest-relaxed @ git+https://github.com/bitprophet/pytest-relaxed@main
+# TODO: NUKEME vvv
+invoke @ git+https://github.com/pyinvoke/invoke@main
+releases @ git+https://github.com/bitprophet/releases@main
+# TODO: NUKEME ^^^
 pytest-cov==2.4.0
 pytest-mock==3.2.0
-mock==1.0.1
 watchdog==0.8.3
 coverage==4.4.2
 codecov==2.1.11
@@ -10,11 +13,8 @@
 black==19.10b0
 # Linting
 flake8==3.6.0
-# For docs (explicit, even tho we currently commutatively require these
-# anyways, how meta)
-# NOTE: sphinx is busted for our releases tree in 1.6+
-sphinx<1.7
-alabaster==0.7.12
+# Modern setuptools, eg automatic license file detection
+setuptools>=56
 
 # Self, for runtime/task dependencies
 -e .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/docs/changelog.rst 
new/invocations-3.0.0/docs/changelog.rst
--- old/invocations-2.6.1/docs/changelog.rst    2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/docs/changelog.rst    2022-12-31 23:12:06.000000000 
+0100
@@ -2,6 +2,33 @@
 Changelog
 =========
 
+- :release:`3.0.0 <2022-12-31>`
+- :support:`-` Various fixes and doc updates re: the `~invocations.autodoc`
+  module's compatibility with modern Sphinx versions.
+- :support:`-` The ``dual_wheels``, ``alt_python``, and ``check_desc``
+  arguments/config options for the ``invocations.packaging.release`` module
+  have been removed.
+
+  .. warning:: This is a backwards-incompatible change.
+
+  .. note::
+      If you were using ``check_desc``, note that the release tasks have been
+      using ``twine check`` for a few releases now, as a default part of
+      execution, and will continue doing so; ``check_desc`` only impacted the
+      use of the older ``setup.py check`` command.
+
+- :support:`-` The ``invocations.travis`` module has been removed. If you
+  relied upon it, we may accept PRs to make the newer ``invocations.ci`` module
+  more generic.
+
+  .. warning:: This is a backwards-incompatible change.
+
+- :support:`-` Drop Python 2 (and 3.5) support. We now support Python
+  3.6+ only. This naturally includes a number of dependency updates (direct and
+  indirect) as well.
+
+  .. warning:: This is a backwards-incompatible change.
+
 - :release:`2.6.1 <2022-06-26>`
 - :support:`- backported` Remove upper bounds pinning on many deps; this makes
   it easier for related projects to test upgrades, run CI, etc. In general,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/docs/conf.py 
new/invocations-3.0.0/docs/conf.py
--- old/invocations-2.6.1/docs/conf.py  2022-06-26 22:39:36.000000000 +0200
+++ new/invocations-3.0.0/docs/conf.py  2022-12-31 23:12:06.000000000 +0100
@@ -19,9 +19,8 @@
 exclude_patterns = ["_build"]
 default_role = "obj"
 
-project = u"Invocations"
-year = datetime.now().year
-copyright = u"%d Jeff Forcier" % year
+project = "Invocations"
+copyright = f"{datetime.now().year} Jeff Forcier"
 
 # Ensure project directory is on PYTHONPATH for version, autodoc access
 sys.path.insert(0, abspath(join(getcwd(), "..")))
@@ -42,7 +41,13 @@
 }
 
 # Other extension configs
-autodoc_default_flags = ["members", "special-members"]
+autodoc_default_options = {
+    "members": True,
+    "special-members": True,
+}
+# Without this, as of Sphinx 4-ish? our autodoc plugin goes boom because its
+# parent class (in sphinx itself!) isn't in our reference tree & the ref fails
+autodoc_inherit_docstrings = False
 releases_github_path = "pyinvoke/invocations"
 
 # Intersphinx
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/_version.py 
new/invocations-3.0.0/invocations/_version.py
--- old/invocations-2.6.1/invocations/_version.py       2022-06-26 
22:39:36.000000000 +0200
+++ new/invocations-3.0.0/invocations/_version.py       2022-12-31 
23:12:06.000000000 +0100
@@ -1,2 +1,2 @@
-__version_info__ = (2, 6, 1)
+__version_info__ = (3, 0, 0)
 __version__ = ".".join(map(str, __version_info__))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/autodoc.py 
new/invocations-3.0.0/invocations/autodoc.py
--- old/invocations-2.6.1/invocations/autodoc.py        2022-06-26 
22:39:36.000000000 +0200
+++ new/invocations-3.0.0/invocations/autodoc.py        2022-12-31 
23:12:06.000000000 +0100
@@ -18,8 +18,8 @@
 
 To use:
 
-- Add ``"sphinx.ext.autodoc"`` and ``"invocations.autodoc"`` to your Sphinx
-  ``conf.py``'s ``extensions`` list.
+- Add ``"invocations.autodoc"`` to your Sphinx ``conf.py``'s ``extensions``
+  list.
 - Use Sphinx autodoc's ``automodule`` directive normally, aiming it at your
   tasks module(s), e.g. ``.. automodule:: myproject.tasks`` in some ``.rst``
   document of your choosing.
@@ -27,11 +27,11 @@
     - As noted above, this only works for modules that are importable, like any
       other Sphinx autodoc use case.
     - Unless you want to opt-in which module members get documented, use
-      ``:members:`` or add ``"members"`` to your ``conf.py``'s
-      ``autodoc_default_flags``.
+      ``:members:`` or add ``"members": True`` to your ``conf.py``'s
+      ``autodoc_default_options``.
     - By default, only tasks with docstrings will be picked up, unless you also
       give the ``:undoc-members:`` flag or add ``:undoc-members:`` / add
-      ``"undoc-members"`` to ``autodoc_default_flags``.
+      ``"undoc-members": True`` to ``autodoc_default_options``.
     - Please see the `autodoc`_ docs for details on these settings and more!
 
 - Build your docs, and you should see your tasks showing up as documented
@@ -41,8 +41,9 @@
 .. _autodoc: http://www.sphinx-doc.org/en/master/ext/autodoc.html
 """
 
+import inspect
+
 from invoke import Task
-from sphinx.util.inspect import getargspec  # Improved over raw stdlib
 
 # For sane mock patching. Meh.
 from sphinx.ext import autodoc
@@ -67,7 +68,7 @@
         # after which point "call tasks as raw functions" may be less common.
         # TODO: also, it may become moot-ish if we turn this all into emission
         # of custom domain objects and/or make the CLI arguments the focus
-        return autodoc.formatargspec(function, *getargspec(function))
+        return autodoc.stringify_signature(inspect.signature(function))
 
     def document_members(self, all_members=False):
         # Neuter this so superclass bits don't introspect & spit out autodoc
@@ -76,15 +77,5 @@
 
 
 def setup(app):
-    # NOTE: the "correct", forward compatible call to make here is
-    # app.add_autodocumenter() - because as of Sphinx 1.7, the inner API we are
-    # manipulating here got changed around a bunch (but the outer
-    # API of add_autodocumenter() remained the same, on purpose).
-    # Unfortunately, in both cases add_autodocumenter() both registers the
-    # documenter AND adds an `auto<type>` directive - meaning it's not possible
-    # to register a "acts kinda like another" Documenter or you double-define
-    # e.g. autofunction, which Sphinx warns about and also presumably kills
-    # real function documenting.
-    # NOTE: sooo for now, since a bunch of our other shit breaks on Sphinx 1.7,
-    # we are just explicitly calling autodoc's add_documenter. Sadface.
-    autodoc.add_documenter(TaskDocumenter)
+    app.setup_extension("sphinx.ext.autodoc")
+    app.add_autodocumenter(TaskDocumenter)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/checks.py 
new/invocations-3.0.0/invocations/checks.py
--- old/invocations-2.6.1/invocations/checks.py 2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/invocations/checks.py 2022-12-31 23:12:06.000000000 
+0100
@@ -4,8 +4,6 @@
 .. versionadded:: 1.2
 """
 
-from __future__ import unicode_literals
-
 from invoke import task
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/ci.py 
new/invocations-3.0.0/invocations/ci.py
--- old/invocations-2.6.1/invocations/ci.py     2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/invocations/ci.py     2022-12-31 23:12:06.000000000 
+0100
@@ -87,7 +87,7 @@
     ssh_dir = "{}/.ssh".format(home)
     for cmd in ("mkdir {0}", "chmod 0700 {0}"):
         sudo_run(c, cmd.format(ssh_dir, user))
-    sudo_run(c, 'ssh-keygen -t rsa -f {}/id_rsa -N \'\''.format(ssh_dir))
+    sudo_run(c, "ssh-keygen -t rsa -f {}/id_rsa -N ''".format(ssh_dir))
     sudo_run(c, f"cp {ssh_dir}/id_rsa.pub {ssh_dir}/authorized_keys")
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/console.py 
new/invocations-3.0.0/invocations/console.py
--- old/invocations-2.6.1/invocations/console.py        2022-06-26 
22:39:36.000000000 +0200
+++ new/invocations-3.0.0/invocations/console.py        2022-12-31 
23:12:06.000000000 +0100
@@ -2,8 +2,6 @@
 Text console UI helpers and patterns, e.g. 'Y/n' prompts and the like.
 """
 
-from __future__ import unicode_literals, print_function
-
 import sys
 
 from invoke.vendor.six.moves import input
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/packaging/release.py 
new/invocations-3.0.0/invocations/packaging/release.py
--- old/invocations-2.6.1/invocations/packaging/release.py      2022-06-26 
22:39:36.000000000 +0200
+++ new/invocations-3.0.0/invocations/packaging/release.py      2022-12-31 
23:12:06.000000000 +0100
@@ -8,21 +8,18 @@
   conventions (``__version_info__`` tuple and ``__version__`` string).
 """
 
-from __future__ import unicode_literals, print_function
-
 import getpass
 import itertools
 import logging
 import os
 import re
 import sys
+import venv
 from functools import partial
 from glob import glob
+from io import StringIO
 from shutil import rmtree
 
-from invoke.vendor.six import StringIO
-
-from invoke.vendor.six import text_type, binary_type, PY2
 from invoke.vendor.lexicon import Lexicon
 
 from blessings import Terminal
@@ -481,7 +478,7 @@
     release = None
     # And requires scanning changelog, for bugfix lines
     if release_type is Release.BUGFIX:
-        versions = [text_type(x) for x in _versions_from_changelog(changelog)]
+        versions = [str(x) for x in _versions_from_changelog(changelog)]
         release = [x for x in versions if x.startswith(bucket)][-1]
     return release, issues
 
@@ -568,14 +565,12 @@
     # edit (eg within prepare()). Otherwise we'll always only see what was
     # on-disk at first import.
     # NOTE: must do both the top level package and the version module! Unclear
-    # why. May be due to the specific import strategy; def try using the
-    # cleaner options available under Python 3 when we drop 2.
+    # why. May be due to the specific import strategy
+    # TODO 3.0: def try using the cleaner options available under Python 3 when
+    # we drop 2.
     sys.modules.pop("{}.{}".format(package_name, version_module), None)
     sys.modules.pop(package_name, None)
-    # NOTE: have to explicitly give it a bytestr (Python 2) or unicode (Python
-    # 3) because https://bugs.python.org/issue21720 HOORAY
-    cast = binary_type if PY2 else text_type
-    package = __import__(package_name, fromlist=[cast(version_module)])
+    package = __import__(package_name, fromlist=[str(version_module)])
     # TODO: explode nicely if it lacks a _version/etc, or a __version__
     # TODO: make this a Version()?
     return getattr(package, version_module).__version__
@@ -684,9 +679,6 @@
     sign=False,
     dry_run=False,
     directory=None,
-    dual_wheels=False,
-    alt_python=None,
-    check_desc=False,
 ):
     """
     Publish code to PyPI or index of choice. Wraps ``build`` and ``publish``.
@@ -728,32 +720,6 @@
 
         Defaults to a temporary directory which is cleaned up after the run
         finishes.
-
-    :param bool dual_wheels:
-        When ``True``, builds individual wheels for Python 2 and Python 3.
-
-        Useful for situations where you can't build universal wheels, but still
-        want to distribute for both interpreter versions.
-
-        Requires that you have a useful ``python3`` (or ``python2``, if you're
-        on Python 3 already) binary in your ``$PATH``. Also requires that this
-        other python have the ``wheel`` package installed in its
-        ``site-packages``; usually this will mean the global site-packages for
-        that interpreter.
-
-        See also the ``alt_python`` argument.
-
-    :param str alt_python:
-        Path to the 'alternate' Python interpreter to use when
-        ``dual_wheels=True``.
-
-        When ``None`` (the default) will be ``python3`` or ``python2``,
-        depending on the currently active interpreter.
-
-    :param bool check_desc:
-        Whether to run ``setup.py check -r -s`` (uses ``readme_renderer``)
-        before trying to publish - catches long_description bugs. Default:
-        ``False``.
     """
     # Don't hide by default, this step likes to be verbose most of the time.
     c.config.run.hide = False
@@ -768,28 +734,12 @@
         index = config["index"]
     if sign is False and "sign" in config:
         sign = config["sign"]
-    if dual_wheels is False and "dual_wheels" in config:
-        dual_wheels = config["dual_wheels"]
-    if check_desc is False and "check_desc" in config:
-        check_desc = config["check_desc"]
-    # Initial sanity check, if needed. Will die usefully.
-    # TODO: remove next backwards incompat release, twine check replaces it
-    if check_desc:
-        c.run("python setup.py check -r -s")
     # Build, into controlled temp dir (avoids attempting to re-upload old
     # files)
     with tmpdir(skip_cleanup=dry_run, explicit=directory) as tmp:
         # Build default archives
         builder = partial(build, c, sdist=sdist, wheel=wheel, directory=tmp)
         builder()
-        # Build opposing interpreter archive, if necessary
-        # TODO: delete dual wheels when dropping Py2 support
-        if dual_wheels:
-            if not alt_python:
-                alt_python = "python2"
-                if sys.version_info[0] == 2:
-                    alt_python = "python3"
-            builder(sdist=False, wheel=True, python=alt_python)
         # Rebuild with env (mostly for Fabric 2)
         # TODO: code smell; implies this really wants to be class/hook based?
         # TODO: or at least invert sometime so it's easier to say "do random
@@ -828,13 +778,6 @@
 
     Uses the `venv` module to build temporary virtualenvs.
     """
-    # TODO: streamline all this in 3.0 when we drop all Py2 support both here
-    # and in downstream repos
-    if PY2:
-        print("WARNING: skipping installation test due to no venv on Python 2")
-        return
-    import venv
-
     # TODO: wants contextmanager or similar for only altering a setting within
     # a given scope or block - this may pollute subsequent subroutine calls
     if verbose:
@@ -846,10 +789,6 @@
     if not archives:
         raise Exit("No archive files found in {}!".format(directory))
     for archive in archives:
-        # Skip Python 2 wheels that aren't universal (we're dropping that
-        # entirely soon)
-        if "py2" in archive and "py3" not in archive:
-            continue
         with tmpdir() as tmp:
             # Make temp venv
             builder.create(tmp)
@@ -930,7 +869,7 @@
     parts = ["twine", "upload"]
     if index:
         parts.append("--repository {}".format(index))
-    paths = archives[:]
+    paths = archives.copy()
     if sign and not dry_run:
         paths.append(os.path.join(directory, "dist", "*.asc"))
     parts.extend(paths)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/packaging/vendorize.py 
new/invocations-3.0.0/invocations/packaging/vendorize.py
--- old/invocations-2.6.1/invocations/packaging/vendorize.py    2022-06-26 
22:39:36.000000000 +0200
+++ new/invocations-3.0.0/invocations/packaging/vendorize.py    2022-12-31 
23:12:06.000000000 +0100
@@ -1,8 +1,8 @@
 """
 Tasks for importing external code into a vendor subdirectory.
 """
-import os
-from glob import glob
+from os import chdir
+from pathlib import Path
 from shutil import copy, copytree, rmtree
 
 from invoke import task
@@ -30,13 +30,13 @@
     #       in the checkout, obtain SHA from that branch
     #       set real_version to that value
     else:
-        cwd = os.getcwd()
-        print("Moving into temp dir %s" % tmp)
-        os.chdir(tmp)
+        cwd = Path.cwd()
+        print(f"Moving into temp dir {tmp}")
+        chdir(tmp)
         try:
             # Nab from index. Skip wheels; we want to unpack an sdist.
             flags = "--download=. --build=build --no-use-wheel"
-            cmd = "pip install %s %s==%s" % (flags, package, version)
+            cmd = f"pip install {flags} {package}=={version}"
             c.run(cmd)
             # Identify basename
             # TODO: glob is bad here because pip install --download gets all
@@ -49,14 +49,15 @@
                 ("tar.gz", "tar xzvf"),
             ):
                 globexpr = "*.{}".format(extension)
-                globs = glob(globexpr)
+                globs = cwd.glob(globexpr)
                 if globs:
                     break
-            archive = os.path.basename(globs[0])
+            archive = globs[0].name
+            # TODO: weird how there's no "mega-.stem" in Pathlib, o well
             source, _, _ = archive.rpartition(".{}".format(extension))
             c.run("{} {}".format(opener, globexpr))
         finally:
-            os.chdir(cwd)
+            chdir(cwd)
     return real_version, source
 
 
@@ -97,23 +98,23 @@
     """
     with tmpdir() as tmp:
         package = package or distribution
-        target = os.path.join(vendor_dir, package)
+        target = Path(vendor_dir) / package
         # Unpack source
         real_version, source = _unpack(c, tmp, distribution, version, git_url)
-        abs_source = os.path.join(tmp, source)
-        source_package = os.path.join(abs_source, package)
+        abs_source = tmp / source
+        source_package = abs_source / package
         # Ensure source package exists
-        if not os.path.exists(source_package):
-            rel_package = os.path.join(source, package)
-            raise ValueError("Source package %s doesn't exist!" % rel_package)
+        if not source_package.exists():
+            rel_package = source_package.relative_to(Path.cwd())
+            raise ValueError(f"Source package {rel_package} doesn't exist!")
         # Nuke target if exists
-        if os.path.exists(target):
-            print("Removing pre-existing vendorized folder %s" % target)
+        if target.exists():
+            print(f"Removing pre-existing vendorized folder {target}")
             rmtree(target)
         # Perform the copy
-        print("Copying %s => %s" % (source_package, target))
+        print(f"Copying {source_package} => {target}")
         copytree(source_package, target)
         # Explicit license if needed
         if license:
-            copy(os.path.join(abs_source, license), target)
+            copy(abs_source / license, target)
         # git commit -a -m "Update $package to $version ($real_version if 
different)" # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/testing.py 
new/invocations-3.0.0/invocations/testing.py
--- old/invocations-2.6.1/invocations/testing.py        2022-06-26 
22:39:36.000000000 +0200
+++ new/invocations-3.0.0/invocations/testing.py        2022-12-31 
23:12:06.000000000 +0100
@@ -24,7 +24,7 @@
     """
     runner = runner or "spec"
     # Allow selecting specific submodule
-    specific_module = " --tests=tests/%s.py" % module
+    specific_module = f" --tests=tests/{module}.py"
     args = specific_module if module else ""
     if opts:
         args += " " + opts
@@ -33,7 +33,7 @@
     # Allow client to configure some other Nose-related things.
     logformat = c.config.get("tests", {}).get("logformat", None)
     if logformat is not None:
-        args += " --logging-format='{}'".format(logformat)
+        args += f" --logging-format='{logformat}'"
     # Use pty by default so the spec/nose/Python process buffers "correctly"
     c.run(runner + args, pty=pty)
 
@@ -46,7 +46,7 @@
     opts = opts or ""
     override = " --tests=integration/"
     if module:
-        override += "{}.py".format(module)
+        override += f"{module}.py"
     opts += override
     test(c, runner=runner, opts=opts, pty=pty)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/invocations/travis.py 
new/invocations-3.0.0/invocations/travis.py
--- old/invocations-2.6.1/invocations/travis.py 2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/invocations/travis.py 1970-01-01 01:00:00.000000000 
+0100
@@ -1,191 +0,0 @@
-"""
-Tasks intended for use under Travis-CI, as opposed to run by humans.
-
-To run these, you probably need to define some or all of the following
-somewhere in your config setup:
-
-- ``travis.sudo.user``: A username to create & grant passworded sudo to.
-- ``travis.sudo.password``: Their password.
-"""
-
-from __future__ import print_function
-
-import os
-import sys
-
-from invoke import task
-
-from .packaging.release import publish
-from . import checks
-
-
-PYTHON = os.environ.get("TRAVIS_PYTHON_VERSION", "")
-
-
-@task
-def make_sudouser(c):
-    """
-    Create a passworded sudo-capable user.
-
-    Used by other tasks to execute the test suite so sudo tests work.
-    """
-    user = c.travis.sudo.user
-    password = c.travis.sudo.password
-    # --create-home because we need a place to put conf files, keys etc
-    # --groups travis because we must be in the Travis group to access the
-    # (created by Travis for us) virtualenv and other contents within
-    # /home/travis.
-    c.sudo("useradd {} --create-home --groups travis".format(user))
-    # Password 'mypass' also arbitrary
-    c.run("echo {}:{} | sudo chpasswd".format(user, password))
-    # Set up new (glob-sourced) sudoers conf file for our user; easier than
-    # attempting to mutate or overwrite main sudoers conf.
-    conf = "/etc/sudoers.d/passworded"
-    cmd = "echo '{}   ALL=(ALL:ALL) PASSWD:ALL' > {}".format(user, conf)
-    c.sudo('sh -c "{}"'.format(cmd))
-    # Grant travis group write access to /home/travis as some integration tests
-    # may try writing conf files there. (TODO: shouldn't running the tests via
-    # 'sudo -H' mean that's no longer necessary?)
-    c.sudo("chmod g+w /home/travis")
-
-
-# TODO: good place to depend on make_sudouser but only if it doesn't seem to
-# have been run already (not just in this session but ever)
-@task
-def make_sshable(c):
-    """
-    Set up passwordless SSH keypair & authorized_hosts access to localhost.
-    """
-    user = c.travis.sudo.user
-    home = "~{}".format(user)
-    # Run sudo() as the new sudo user; means less chown'ing, etc.
-    c.config.sudo.user = user
-    ssh_dir = "{}/.ssh".format(home)
-    # TODO: worth wrapping in 'sh -c' and using '&&' instead of doing this?
-    # TODO: uhh isn't this fucking broken
-    for cmd in ("mkdir {0}", "chmod 0700 {0}"):
-        c.sudo(cmd.format(ssh_dir, user))
-    c.sudo('ssh-keygen -f {}/id_rsa -N ""'.format(ssh_dir))
-    c.sudo("cp {}/{{id_rsa.pub,authorized_keys}}".format(ssh_dir))
-
-
-@task
-def sudo_run(c, command):
-    """
-    Run some command under Travis-oriented sudo subshell/virtualenv.
-
-    :param str command:
-        Command string to run, e.g. ``inv coverage``, ``inv integration``, etc.
-        (Does not necessarily need to be an Invoke task, but...)
-    """
-    # NOTE: explicit shell wrapper because sourcing the venv works best here;
-    # test tasks currently use their own subshell to call e.g. 'pytest --blah',
-    # so the tactic of '$VIRTUAL_ENV/bin/inv coverage' doesn't help - only that
-    # intermediate process knows about the venv!
-    cmd = "source $VIRTUAL_ENV/bin/activate && {}".format(command)
-    c.sudo('bash -c "{}"'.format(cmd), user=c.travis.sudo.user)
-
-
-@task
-def sudo_coverage(c):
-    """
-    Execute the local ``coverage`` task as the configured Travis sudo user.
-
-    Ensures the virtualenv is sourced and that coverage is run in a mode
-    suitable for headless/API consumtion (e.g. no HTML report, etc.)
-    """
-    # TODO: deprecate in favor of just using sudo-run
-    sudo_run(c, command="inv coverage")
-
-
-@task
-def test_installation(c, package, sanity):
-    """
-    Test a non-editable pip install of source checkout.
-
-    Catches high level setup.py bugs.
-
-    :param str package: Package name to uninstall.
-    :param str sanity: Sanity-check command string to run.
-    """
-    c.run("pip uninstall -y {}".format(package))
-    c.run("pip install .")
-    if sanity:
-        c.run(sanity)
-    # TODO: merge with test_packaging below somehow, e.g. a subroutine
-
-
-@task
-def test_packaging(c, package, sanity, alt_python=None):
-    """
-    Execute a wipe-build-install-test cycle for a given packaging config.
-
-    Ideally, tests everything but actual upload to package index.
-
-    When possible, leverages in-process calls to other packaging tasks.
-
-    :param str package: Package name to uninstall before testing installation.
-    :param str sanity: Sanity-check command string to run.
-    :param str alt_python:
-        Path to alternate virtualenv's Python interpreter. If given, will also
-        enable a "2 vs 3" mode during wheel installation testing, which will
-        select only the interpreter-family-appropriate wheel (going by
-        ``$TRAVIS_PYTHON_VERSION``.)
-    """
-    # Use an explicit directory for building so we can reference after
-    path = "tmp"
-    # Echo on please
-    c.config.run.echo = True
-    # Ensure no GPG signing is attempted.
-    c.packaging.sign = False
-    # Publish in dry-run context, to explicit (non-tmp) directory.
-    publish(c, dry_run=True, directory=path, alt_python=alt_python)
-    # Various permutations of nuke->install->sanity test, as needed
-    # TODO: normalize sdist so it's actually a config option, rn is kwarg-only
-    globs = ["*.tar.gz"]
-    if c.packaging.wheel:
-        if alt_python:
-            # TODO: the original .travis.yml was structured with logic this
-            # way; I don't recall if it was purposeful or if an 'if/else' would
-            # suffice instead.
-            # TODO: shouldn't we just be able to use internal Python hints
-            # about this now anyways (eg `sys.version`)? Will that work for
-            # pypy and pypy3?
-            if PYTHON.startswith("3") or PYTHON == "pypy3":
-                globs.append("*py3*.whl")
-            if PYTHON.startswith("2") or PYTHON == "pypy":
-                globs.append("*py2*.whl")
-        else:
-            globs.append("*.whl")
-    for glob in globs:
-        c.run("pip uninstall -y {}".format(package), warn=True)
-        c.run("pip install tmp/dist/{}".format(glob))
-        c.run(sanity)
-
-
-@task
-def blacken(c):
-    """
-    Install and execute ``black`` under appropriate circumstances, with diffs.
-
-    Installs and runs ``black`` under Python 3.6 (the first version it
-    supports). Since this sort of CI based task only needs to run once per
-    commit (formatting is not going to change between interpreters) this seems
-    like a worthwhile tradeoff.
-
-    This task uses black's ``--check`` and ``--fail`` flags, so not only will
-    the build fail if it does not conform, but contributors can see exactly
-    what they need to change. This is intended as a hedge against the fact that
-    not all contributors will be using Python 3.6+.
-    """
-    if not PYTHON.startswith("3.6"):
-        msg = "Not blackening, since Python {} != Python 3.6".format(PYTHON)
-        print(msg, file=sys.stderr)
-        return
-    # Install, allowing config override of hardcoded default version
-    config = c.config.get("travis", {}).get("black", {})
-    version = config.get("version", "18.5b0")
-    c.run("pip install black=={}".format(version))
-    # Execute our blacken task, with diff + check, which will both error
-    # and emit diffs.
-    checks.blacken(c, check=True, diff=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/setup.cfg 
new/invocations-3.0.0/setup.cfg
--- old/invocations-2.6.1/setup.cfg     2022-06-26 22:39:36.000000000 +0200
+++ new/invocations-3.0.0/setup.cfg     1970-01-01 01:00:00.000000000 +0100
@@ -1,5 +0,0 @@
-[wheel]
-universal = 1
-
-[metadata]
-license_file = LICENSE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/setup.py 
new/invocations-3.0.0/setup.py
--- old/invocations-2.6.1/setup.py      2022-06-26 22:39:36.000000000 +0200
+++ new/invocations-3.0.0/setup.py      2022-12-31 23:12:06.000000000 +0100
@@ -10,14 +10,13 @@
 
 requirements = [
     # Core dependency
-    "invoke>=1.6",
+    "invoke>=1.7.2",
     # Dependencies for various subpackages.
     # NOTE: these used to be all optional (only complained about at import
     # time if missing), but that got hairy fast, and these are all
     # pure-Python packages, so it shouldn't be a huge burden for users to
     # obtain them.
     "blessings>=1.6",
-    "enum34>=1.1,<2; python_version < '3'",
     "releases>=1.6",
     "semantic_version>=2.4,<2.7",
     "tabulate==0.7.5",
@@ -42,6 +41,7 @@
         "Issues": "https://github.com/pyinvoke/invocations/issues";,
     },
     # Release requirements. See dev-requirements.txt for dev version reqs.
+    python_requires=">=3.6",
     install_requires=requirements,
     packages=find_packages(),
     classifiers=[
@@ -55,14 +55,13 @@
         "Operating System :: MacOS :: MacOS X",
         "Operating System :: Microsoft :: Windows",
         "Programming Language :: Python",
-        "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 2.7",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
+        "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3.11",
         "Topic :: Software Development",
         "Topic :: Software Development :: Build Tools",
         "Topic :: Software Development :: Libraries",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/tests/autodoc/_support/conf.py 
new/invocations-3.0.0/tests/autodoc/_support/conf.py
--- old/invocations-2.6.1/tests/autodoc/_support/conf.py        2022-06-26 
22:39:36.000000000 +0200
+++ new/invocations-3.0.0/tests/autodoc/_support/conf.py        2022-12-31 
23:12:06.000000000 +0100
@@ -6,5 +6,5 @@
 sys.path.insert(0, dirname(__file__))
 
 master_doc = "index"
-extensions = ["sphinx.ext.autodoc", "invocations.autodoc"]
-autodoc_default_flags = ["members"]
+extensions = ["invocations.autodoc"]
+autodoc_default_options = dict(members=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/tests/autodoc/base.py 
new/invocations-3.0.0/tests/autodoc/base.py
--- old/invocations-2.6.1/tests/autodoc/base.py 2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/tests/autodoc/base.py 2022-12-31 23:12:06.000000000 
+0100
@@ -2,10 +2,10 @@
 import re
 import shutil
 
-from mock import Mock, patch
+from unittest.mock import Mock
 
 from invoke import Context
-from invocations.autodoc import setup, TaskDocumenter
+from invocations.autodoc import setup as our_setup, TaskDocumenter
 
 
 def _build():
@@ -35,10 +35,11 @@
     def teardown_class(self):
         shutil.rmtree(self.build_dir, ignore_errors=True)
 
-    @patch("sphinx.ext.autodoc.add_documenter")
-    def setup_adds_TaskDocumenter_as_documenter(self, add_documenter):
-        setup(Mock())
-        add_documenter.assert_called_once_with(TaskDocumenter)
+    def setup_requires_autodoc_and_adds_autodocumenter(self):
+        app = Mock()
+        our_setup(app)
+        app.setup_extension.assert_called_once_with("sphinx.ext.autodoc")
+        app.add_autodocumenter.assert_called_once_with(TaskDocumenter)
 
     def module_docstring_unmodified(self):
         # Just a sanity test, really.
@@ -47,11 +48,13 @@
     def regular_functions_only_appear_once(self):
         # Paranoid sanity check re: our
         # very-much-like-FunctionDocumenter-documenter not accidentally loading
-        # up non-task objects. SHRUG.
-        # TODO: incredibly stupid "is HTML string literal" test because too
-        # lazy to whip up something with BeautifulSoup et al.
-        for sentinel in (">not_a_task", ">I am a regular function"):
-            assert len(re.findall(sentinel, self.api_docs)) == 1
+        # up non-task objects (and thus having them autodoc'd twice: once
+        # regularly and once incorrectly 'as tasks'). SHRUG.
+        # NOTE: as of Sphinx 5.2, ToC now shows name of object too, so we test
+        # for the identifier and the docstring separately (and expect the 1st
+        # twice)
+        assert len(re.findall(">not_a_task", self.api_docs)) == 2
+        assert len(re.findall(">I am a regular function", self.api_docs)) == 1
 
     def undocumented_members_do_not_appear_by_default(self):
         # This really just tests basic Sphinx/autodoc stuff for now...meh
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/tests/console.py 
new/invocations-3.0.0/tests/console.py
--- old/invocations-2.6.1/tests/console.py      2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/tests/console.py      2022-12-31 23:12:06.000000000 
+0100
@@ -1,8 +1,6 @@
-from __future__ import unicode_literals
-
 import sys
 
-from mock import patch
+from unittest.mock import patch
 from pytest_relaxed import trap
 
 from invocations.console import confirm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/tests/environment.py 
new/invocations-3.0.0/tests/environment.py
--- old/invocations-2.6.1/tests/environment.py  2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/tests/environment.py  2022-12-31 23:12:06.000000000 
+0100
@@ -1,4 +1,4 @@
-from mock import patch
+from unittest.mock import patch
 from pytest import mark
 
 from invocations.environment import in_ci
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/tests/packaging/release.py 
new/invocations-3.0.0/tests/packaging/release.py
--- old/invocations-2.6.1/tests/packaging/release.py    2022-06-26 
22:39:36.000000000 +0200
+++ new/invocations-3.0.0/tests/packaging/release.py    2022-12-31 
23:12:06.000000000 +0100
@@ -1,15 +1,12 @@
-from __future__ import unicode_literals, print_function
-
 from contextlib import contextmanager
 from os import path
 import re
 import sys
 
-from invoke.vendor.six import PY2
 from invoke.vendor.lexicon import Lexicon
 from invoke import MockContext, Result, Config, Exit
 from docutils.utils import Reporter
-from mock import Mock, patch, call
+from unittest.mock import Mock, patch, call
 import pytest
 from pytest import skip
 from pytest_relaxed import trap, raises
@@ -33,7 +30,7 @@
     publish,
     status,
     upload,
-    test_install,
+    test_install as install_test_task,  # to avoid pytest treating as test func
     ns as release_ns,
 )
 
@@ -171,7 +168,7 @@
         assert load_version(c) == expected
 
     # NOTE: these all also happen to test the Python bug re: a unicode value
-    # given to `__import__(xxx, fromlist=[u'onoz'])`. No real point making
+    # given to `__import__(xxx, fromlist=['onoz'])`. No real point making
     # another one.
 
     def defaults_to_underscore_version(self):
@@ -308,11 +305,7 @@
             return real_import(*args, **kwargs)
         return Mock(_version=Mock(__version__=self._version))
 
-    # Because I can't very well patch six.moves.builtins itself, can I? =/
-    builtins = "__builtin__" if PY2 else "builtins"
-    import_patcher = patch(
-        "{}.__import__".format(builtins), side_effect=fake_import
-    )
+    import_patcher = patch("builtins.__import__", side_effect=fake_import)
 
     with import_patcher:
         yield context
@@ -378,7 +371,7 @@
             err = "Expected:\n\n{}\n\nGot:\n\n{}".format(regex, output)
             err += "\n\nRepr edition...\n\n"
             err += "Expected:\n\n{!r}\n\nGot:\n\n{!r}".format(regex, output)
-            assert re.match(regex, output), err
+            assert re.match(regex, output) is not None, err
 
         @trap  # just for cleaner test output
         def returns_lexica_for_reuse(self):
@@ -874,49 +867,49 @@
 
 
 class build_:
-    sdist_flags = "sdist -d dist"
-    wheel_flags = "build -b build bdist_wheel -d dist"
-    both_flags = "sdist -d dist build -b build bdist_wheel -d dist"
-    oh_dir = "sdist -d {0} build -b {1} bdist_wheel -d {0}".format(
+    _sdist_flags = "sdist -d dist"
+    _wheel_flags = "build -b build bdist_wheel -d dist"
+    _both_flags = "sdist -d dist build -b build bdist_wheel -d dist"
+    _oh_dir = "sdist -d {0} build -b {1} bdist_wheel -d {0}".format(
         path.join("dir", "dist"), path.join("dir", "build")
     )
 
     class sdist:
         def indicates_sdist_builds(self):
-            with _expect_setuppy(self.both_flags) as c:
+            with _expect_setuppy(self._both_flags) as c:
                 build(c, sdist=True)
 
         def on_by_default(self):
-            with _expect_setuppy(self.both_flags) as c:
+            with _expect_setuppy(self._both_flags) as c:
                 build(c)
 
         def can_be_disabled_via_config(self):
             config = Config(dict(packaging=dict(sdist=False)))
-            with _expect_setuppy(self.wheel_flags, config=config) as c:
+            with _expect_setuppy(self._wheel_flags, config=config) as c:
                 build(c)
 
         def kwarg_wins_over_config(self):
             config = Config(dict(packaging=dict(sdist=True)))
-            with _expect_setuppy(self.wheel_flags, config=config) as c:
+            with _expect_setuppy(self._wheel_flags, config=config) as c:
                 build(c, sdist=False)
 
     class wheel:
         def indicates_explicit_build_and_wheel(self):
-            with _expect_setuppy(self.wheel_flags) as c:
+            with _expect_setuppy(self._wheel_flags) as c:
                 build(c, sdist=False, wheel=True)
 
         def on_by_default(self):
-            with _expect_setuppy(self.wheel_flags) as c:
+            with _expect_setuppy(self._wheel_flags) as c:
                 build(c, sdist=False)
 
         def can_be_disabled_via_config(self):
             config = Config(dict(packaging=dict(wheel=False)))
-            with _expect_setuppy(self.sdist_flags, config=config) as c:
+            with _expect_setuppy(self._sdist_flags, config=config) as c:
                 build(c)
 
         def kwarg_wins_over_config(self):
             config = Config(dict(packaging=dict(wheel=True)))
-            with _expect_setuppy(self.sdist_flags, config=config) as c:
+            with _expect_setuppy(self._sdist_flags, config=config) as c:
                 build(c, wheel=False)
 
     @raises(Exit)
@@ -925,49 +918,49 @@
 
     class directory:
         def defaults_to_blank_or_cwd(self):
-            with _expect_setuppy(self.both_flags) as c:
+            with _expect_setuppy(self._both_flags) as c:
                 build(c)
 
         def if_given_affects_build_and_dist_dirs(self):
-            with _expect_setuppy(self.oh_dir) as c:
+            with _expect_setuppy(self._oh_dir) as c:
                 build(c, directory="dir")
 
         def may_be_given_via_config(self):
             config = Config(dict(packaging=dict(directory="dir")))
-            with _expect_setuppy(self.oh_dir, config=config) as c:
+            with _expect_setuppy(self._oh_dir, config=config) as c:
                 build(c)
 
         def kwarg_wins_over_config(self):
             config = Config(dict(packaging=dict(directory="NOTdir")))
-            with _expect_setuppy(self.oh_dir, config=config) as c:
+            with _expect_setuppy(self._oh_dir, config=config) as c:
                 build(c, directory="dir")
 
     class python:
         def defaults_to_python(self):
-            with _expect_setuppy(self.both_flags, python="python") as c:
+            with _expect_setuppy(self._both_flags, python="python") as c:
                 build(c, python="python")
 
         def may_be_overridden(self):
-            with _expect_setuppy(self.both_flags, python="fython") as c:
+            with _expect_setuppy(self._both_flags, python="fython") as c:
                 build(c, python="fython")
 
         def can_be_given_via_config(self):
             config = Config(dict(packaging=dict(python="python17")))
             with _expect_setuppy(
-                self.both_flags, config=config, python="python17"
+                self._both_flags, config=config, python="python17"
             ) as c:
                 build(c)
 
         def kwarg_wins_over_config(self):
             config = Config(dict(packaging=dict(python="python17")))
             with _expect_setuppy(
-                self.both_flags, config=config, python="python99"
+                self._both_flags, config=config, python="python99"
             ) as c:
                 build(c, python="python99")
 
     class clean:
         def _expect_with_rmtree(self):
-            return _expect_setuppy(self.both_flags, yield_rmtree=True)
+            return _expect_setuppy(self._both_flags, yield_rmtree=True)
 
         def defaults_to_False_meaning_no_clean(self):
             with self._expect_with_rmtree() as (c, rmtree):
@@ -981,7 +974,7 @@
             rmtree.assert_any_call("build", ignore_errors=True)
 
         def understands_directory_option(self):
-            with _expect_setuppy(self.oh_dir, yield_rmtree=True) as (
+            with _expect_setuppy(self._oh_dir, yield_rmtree=True) as (
                 c,
                 rmtree,
             ):
@@ -996,7 +989,7 @@
         def may_be_configured(self):
             config = Config(dict(packaging=dict(clean=True)))
             with _expect_setuppy(
-                self.both_flags, yield_rmtree=True, config=config
+                self._both_flags, yield_rmtree=True, config=config
             ) as (c, rmtree):
                 build(c)
             rmtree.assert_any_call("dist", ignore_errors=True)
@@ -1005,7 +998,7 @@
         def kwarg_wins_over_config(self):
             config = Config(dict(packaging=dict(clean=True)))
             with _expect_setuppy(
-                self.both_flags, yield_rmtree=True, config=config
+                self._both_flags, yield_rmtree=True, config=config
             ) as (c, rmtree):
                 build(c, clean=False)
             rmtree.assert_any_call("dist", ignore_errors=True)
@@ -1080,7 +1073,7 @@
         c.run.assert_any_call(twine_upload)
 
 
-class Kaboom(Exception):
+class _Kaboom(Exception):
     pass
 
 
@@ -1110,8 +1103,8 @@
 
         def cleans_up_on_error(self, fakepub):
             c, mocks = fakepub
-            mocks.build.side_effect = Kaboom
-            with pytest.raises(Kaboom):
+            mocks.build.side_effect = _Kaboom
+            with pytest.raises(_Kaboom):
                 publish(MockContext(run=True))
             mocks.rmtree.assert_called_once_with(mocks.mkdtemp.return_value)
 
@@ -1200,8 +1193,8 @@
 
         def causes_tmpdir_cleanup_to_be_skipped_on_exception(self, fakepub):
             c, mocks = fakepub
-            mocks.build.side_effect = Kaboom
-            with pytest.raises(Kaboom):
+            mocks.build.side_effect = _Kaboom
+            with pytest.raises(_Kaboom):
                 publish(c, dry_run=True)
             assert not mocks.rmtree.called
 
@@ -1224,7 +1217,7 @@
         c = MockContext(run=True, repeat=True)
         mkdtemp.return_value = "tmpdir"
         get_archives.return_value = ["foo.tgz", "foo.whl"]
-        test_install(c, directory="whatever")
+        install_test_task(c, directory="whatever")
         # Create factory
         builder.assert_called_once_with(with_pip=True)
         # Used helper to get artifacts
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/invocations-2.6.1/tests/pytest_.py 
new/invocations-3.0.0/tests/pytest_.py
--- old/invocations-2.6.1/tests/pytest_.py      2022-06-26 22:39:36.000000000 
+0200
+++ new/invocations-3.0.0/tests/pytest_.py      2022-12-31 23:12:06.000000000 
+0100
@@ -1,8 +1,8 @@
 from contextlib import contextmanager
 
 from invoke import MockContext
-from invocations.pytest import test, coverage
-from mock import Mock, call
+from invocations.pytest import test as _test_task, coverage
+from unittest.mock import Mock, call
 
 
 @contextmanager
@@ -21,41 +21,41 @@
     def defaults_to_verbose_color_and_syscapture_with_pty_True(self):
         # Relies on default flags within expect helper
         with _expect() as c:
-            test(c)
+            _test_task(c)
 
     def can_turn_off_or_change_defaults(self):
         with _expect(flags="--capture=no", kwargs=dict(pty=False)) as c:
-            test(c, verbose=False, color=False, pty=False, capture="no")
+            _test_task(c, verbose=False, color=False, pty=False, capture="no")
 
     def can_passthru_k_x_and_arbitrary_opts(self):
         with _expect(extra_flags="--whatever -man -k 'lmao' -x") as c:
-            test(c, k="lmao", x=True, opts="--whatever -man")
+            _test_task(c, k="lmao", x=True, opts="--whatever -man")
 
     def can_disable_warnings(self):
         with _expect(extra_flags="--disable-warnings") as c:
-            test(c, warnings=False)
+            _test_task(c, warnings=False)
 
 
 class coverage_:
-    FLAGS = "--cov --no-cov-on-fail --cov-report={}"
+    _FLAGS = "--cov --no-cov-on-fail --cov-report={}"
 
     def default_args(self):
-        with _expect(extra_flags=self.FLAGS.format("term")) as c:
+        with _expect(extra_flags=self._FLAGS.format("term")) as c:
             coverage(c)
 
     def report_type(self):
-        with _expect(extra_flags=self.FLAGS.format("xml")) as c:
+        with _expect(extra_flags=self._FLAGS.format("xml")) as c:
             coverage(c, report="xml")
 
     def opts(self):
-        with _expect(extra_flags=self.FLAGS.format("term") + " --meh") as c:
+        with _expect(extra_flags=self._FLAGS.format("term") + " --meh") as c:
             coverage(c, opts="--meh")
 
     def test_function(self):
         c = MockContext()
         faketest = Mock()
         coverage(c, tester=faketest)
-        faketest.assert_called_once_with(c, opts=self.FLAGS.format("term"))
+        faketest.assert_called_once_with(c, opts=self._FLAGS.format("term"))
 
     def open_html_report(self):
         c = MockContext(run=True, repeat=True)

++++++ invocations-no-bundled.patch ++++++
--- /var/tmp/diff_new_pack.XtPWFz/_old  2023-01-04 18:09:58.364324506 +0100
+++ /var/tmp/diff_new_pack.XtPWFz/_new  2023-01-04 18:09:58.368324530 +0100
@@ -1,27 +1,24 @@
-Index: invocations-1.4.0/tests/packaging/release.py
+Index: invocations-3.0.0/tests/packaging/release.py
 ===================================================================
---- invocations-1.4.0.orig/tests/packaging/release.py
-+++ invocations-1.4.0/tests/packaging/release.py
-@@ -5,8 +5,12 @@ from os import path
+--- invocations-3.0.0.orig/tests/packaging/release.py
++++ invocations-3.0.0/tests/packaging/release.py
+@@ -3,7 +3,10 @@ from os import path
  import re
  import sys
  
--from invoke.vendor.six import PY2
 -from invoke.vendor.lexicon import Lexicon
 +try:
-+    from invoke.vendor.six import PY2
 +    from invoke.vendor.lexicon import Lexicon
 +except ImportError:
-+    from six import PY2
 +    from lexicon import Lexicon
  from invoke import MockContext, Result, Config, Exit
  from docutils.utils import Reporter
- from mock import Mock, patch, call
-Index: invocations-1.4.0/invocations/console.py
+ from unittest.mock import Mock, patch, call
+Index: invocations-3.0.0/invocations/console.py
 ===================================================================
---- invocations-1.4.0.orig/invocations/console.py
-+++ invocations-1.4.0/invocations/console.py
-@@ -6,7 +6,10 @@ from __future__ import unicode_literals,
+--- invocations-3.0.0.orig/invocations/console.py
++++ invocations-3.0.0/invocations/console.py
+@@ -4,7 +4,10 @@ Text console UI helpers and patterns, e.
  
  import sys
  
@@ -33,33 +30,10 @@
  
  
  # NOTE: originally cribbed from fab 1's contrib.console.confirm
-Index: invocations-1.4.0/invocations/packaging/release.py
+Index: invocations-3.0.0/invocations/packaging/semantic_version_monkey.py
 ===================================================================
---- invocations-1.4.0.orig/invocations/packaging/release.py
-+++ invocations-1.4.0/invocations/packaging/release.py
-@@ -19,10 +19,14 @@ import sys
- from glob import glob
- from shutil import rmtree
- 
--from invoke.vendor.six import StringIO
--
--from invoke.vendor.six import text_type, binary_type, PY2
--from invoke.vendor.lexicon import Lexicon
-+try:
-+    from invoke.vendor.six import StringIO
-+    from invoke.vendor.six import text_type, binary_type, PY2
-+    from invoke.vendor.lexicon import Lexicon
-+except ImportError:
-+    from six import StringIO
-+    from six import text_type, binary_type, PY2
-+    from lexicon import Lexicon
- 
- from blessings import Terminal
- from docutils.utils import Reporter
-Index: invocations-1.4.0/invocations/packaging/semantic_version_monkey.py
-===================================================================
---- invocations-1.4.0.orig/invocations/packaging/semantic_version_monkey.py
-+++ invocations-1.4.0/invocations/packaging/semantic_version_monkey.py
+--- invocations-3.0.0.orig/invocations/packaging/semantic_version_monkey.py
++++ invocations-3.0.0/invocations/packaging/semantic_version_monkey.py
 @@ -5,7 +5,10 @@ We never like monkey-patching, but for n
  or distributing our own fork.
  """
@@ -72,10 +46,10 @@
  
  from semantic_version import Version
  
-Index: invocations-1.4.0/invocations/testing.py
+Index: invocations-3.0.0/invocations/testing.py
 ===================================================================
---- invocations-1.4.0.orig/invocations/testing.py
-+++ invocations-1.4.0/invocations/testing.py
+--- invocations-3.0.0.orig/invocations/testing.py
++++ invocations-3.0.0/invocations/testing.py
 @@ -1,8 +1,12 @@
  import sys
  import time
@@ -91,4 +65,20 @@
  
  from invoke import task
  from tqdm import tqdm
+Index: invocations-3.0.0/invocations/packaging/release.py
+===================================================================
+--- invocations-3.0.0.orig/invocations/packaging/release.py
++++ invocations-3.0.0/invocations/packaging/release.py
+@@ -20,7 +20,10 @@ from glob import glob
+ from io import StringIO
+ from shutil import rmtree
+ 
+-from invoke.vendor.lexicon import Lexicon
++try:
++    from invoke.vendor.lexicon import Lexicon
++except ImportError:
++    from lexicon import Lexicon
+ 
+ from blessings import Terminal
+ from docutils.utils import Reporter
 

Reply via email to