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