Remove zope from Certbot (#9161)

* Remove zope and the internal reporter util.

* remove zope references from .pylintrc and pytest.ini

Co-authored-by: Alex Zorin <alex@zorin.id.au>
This commit is contained in:
Adrien Ferrand
2022-09-07 15:09:32 +10:00
committed by GitHub
co-authored by Alex Zorin
parent 529a0e2272
commit 9d736d5c9c
21 changed files with 49 additions and 502 deletions
+2 -7
View File
@@ -283,10 +283,6 @@ ignored-modules=pkg_resources,confargparse,argparse
# (useful for classes with attributes dynamically set).
ignored-classes=Field,Header,JWS,closing
# When zope mode is activated, add a predefined set of Zope acquired attributes
# to generated-members.
zope=yes
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed. Python regular
# expressions are accepted.
@@ -313,9 +309,8 @@ int-import-graph=
[CLASSES]
# List of interface methods to ignore, separated by a comma. This is used for
# instance to not check methods defined in Zope's Interface base class.
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by,implementedBy,providedBy
# List of interface methods to ignore, separated by a comma.
ignore-iface-methods=
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
+1 -14
View File
@@ -10,11 +10,7 @@ from typing import Tuple
from typing import TypeVar
from typing import Union
import zope.component
import zope.interface
from certbot import errors
from certbot import interfaces
from certbot._internal import constants
from certbot._internal.display import completer
from certbot._internal.display import util
@@ -34,6 +30,7 @@ SIDE_FRAME = ("- " * 39) + "-"
"""Display boundary (alternates spaces, so when copy-pasted, markdown doesn't interpret
it as a heading)"""
# This class holds the global state of the display service. Using this class
# eliminates potential gotchas that exist if self.display was just a global
# variable. In particular, in functions `_DISPLAY = <value>` would create a
@@ -50,9 +47,6 @@ _SERVICE = _DisplayService()
T = TypeVar("T")
# This use of IDisplay can be removed when this class is no longer accessible
# through the public API in certbot.display.util.
@zope.interface.implementer(interfaces.IDisplay)
class FileDisplay:
"""File-based display."""
# see https://github.com/certbot/certbot/issues/3915
@@ -410,9 +404,6 @@ class FileDisplay:
return OK, selection
# This use of IDisplay can be removed when this class is no longer accessible
# through the public API in certbot.display.util.
@zope.interface.implementer(interfaces.IDisplay)
class NoninteractiveDisplay:
"""A display utility implementation that never asks for interactive user input"""
@@ -573,8 +564,4 @@ def set_display(display: Union[FileDisplay, NoninteractiveDisplay]) -> None:
:param Union[FileDisplay, NoninteractiveDisplay] display: the display service
"""
# This call is done only for retro-compatibility purposes.
# TODO: Remove this call once zope dependencies are removed from Certbot.
zope.component.provideUtility(display, interfaces.IDisplay)
_SERVICE.display = display
+4 -18
View File
@@ -17,8 +17,6 @@ from typing import Union
import configobj
import josepy as jose
import zope.component
import zope.interface
from acme import client as acme_client
from acme import errors as acme_errors
@@ -38,7 +36,6 @@ from certbot._internal import eff
from certbot._internal import hooks
from certbot._internal import log
from certbot._internal import renewal
from certbot._internal import reporter
from certbot._internal import snap_config
from certbot._internal import storage
from certbot._internal import updater
@@ -1165,15 +1162,14 @@ def plugins_cmd(config: configuration.NamespaceConfig,
return
filtered.init(config)
verified = filtered.verify(ifaces)
logger.debug("Verified plugins: %r", verified)
logger.debug("Filtered plugins: %r", filtered)
if not config.prepare:
notify(str(verified))
notify(str(filtered))
return
verified.prepare()
available = verified.available()
filtered.prepare()
available = filtered.available()
logger.debug("Prepared plugins: %s", available)
notify(str(available))
@@ -1716,10 +1712,6 @@ def main(cli_args: List[str] = None) -> Optional[Union[str, int]]:
args = cli.prepare_and_parse_args(plugins, cli_args)
config = configuration.NamespaceConfig(args)
# This call is done only for retro-compatibility purposes.
# TODO: Remove this call once zope dependencies are removed from Certbot.
zope.component.provideUtility(config, interfaces.IConfig)
# On windows, shell without administrative right cannot create symlinks required by certbot.
# So we check the rights before continuing.
misc.raise_for_non_administrative_windows_rights()
@@ -1732,12 +1724,6 @@ def main(cli_args: List[str] = None) -> Optional[Union[str, int]]:
if config.func != plugins_cmd: # pylint: disable=comparison-with-callable
raise
# These calls are done only for retro-compatibility purposes.
# TODO: Remove these calls once zope dependencies are removed from Certbot.
report = reporter.Reporter(config)
zope.component.provideUtility(report, interfaces.IReporter)
util.atexit_register(report.print_messages)
with make_displayer(config) as displayer:
display_obj.set_display(displayer)
+2 -104
View File
@@ -12,11 +12,8 @@ from typing import Mapping
from typing import Optional
from typing import Type
from typing import Union
import warnings
import pkg_resources
import zope.interface
import zope.interface.verify
from certbot import configuration
from certbot import errors
@@ -115,7 +112,7 @@ class PluginEntryPoint:
def ifaces(self, *ifaces_groups: Iterable[Type]) -> bool:
"""Does plugin implements specified interface groups?"""
return not ifaces_groups or any(
all(_implements(self.plugin_cls, iface)
all(issubclass(self.plugin_cls, iface)
for iface in ifaces)
for ifaces in ifaces_groups)
@@ -133,16 +130,6 @@ class PluginEntryPoint:
self._initialized = self.plugin_cls(config, self.name)
return self._initialized
def verify(self, ifaces: Iterable[Type]) -> bool:
"""Verify that the plugin conforms to the specified interfaces."""
if not self.initialized:
raise ValueError("Plugin is not initialized.")
for iface in ifaces: # zope.interface.providedBy(plugin)
if not _verify(self.init(), self.plugin_cls, iface):
return False
return True
@property
def prepared(self) -> bool:
"""Has the plugin been prepared already?"""
@@ -264,7 +251,7 @@ class PluginsRegistry(Mapping):
plugin2 = other_ep.entry_point.dist.key if other_ep.entry_point.dist else "unknown"
raise Exception("Duplicate plugin name {0} from {1} and {2}.".format(
plugin_ep.name, plugin1, plugin2))
if _provides(plugin_ep.plugin_cls, interfaces.Plugin):
if issubclass(plugin_ep.plugin_cls, interfaces.Plugin):
plugins[plugin_ep.name] = plugin_ep
else: # pragma: no cover
logger.warning(
@@ -299,10 +286,6 @@ class PluginsRegistry(Mapping):
"""Filter plugins based on interfaces."""
return self.filter(lambda p_ep: p_ep.ifaces(*ifaces_groups))
def verify(self, ifaces: Iterable[Type]) -> "PluginsRegistry":
"""Filter plugins based on verification."""
return self.filter(lambda p_ep: p_ep.verify(ifaces))
def prepare(self) -> List[Union[bool, Error]]:
"""Prepare all plugins in the registry."""
return [plugin_ep.prepare() for plugin_ep in self._plugins.values()]
@@ -341,88 +324,3 @@ class PluginsRegistry(Mapping):
if not self._plugins:
return "No plugins"
return "\n\n".join(str(p_ep) for p_ep in self._plugins.values())
_DEPRECATION_PLUGIN = ("Zope interface certbot.interfaces.IPlugin is deprecated, "
"use ABC certbot.interface.Plugin instead.")
_DEPRECATION_AUTHENTICATOR = ("Zope interface certbot.interfaces.IAuthenticator is deprecated, "
"use ABC certbot.interface.Authenticator instead.")
_DEPRECATION_INSTALLER = ("Zope interface certbot.interfaces.IInstaller is deprecated, "
"use ABC certbot.interface.Installer instead.")
_DEPRECATION_FACTORY = ("Zope interface certbot.interfaces.IPluginFactory is deprecated, "
"use ABC certbot.interface.Plugin instead.")
def _provides(target_class: Type[interfaces.Plugin], iface: Type) -> bool:
if issubclass(target_class, iface):
return True
if iface == interfaces.Plugin and interfaces.IPluginFactory.providedBy(target_class):
logging.warning(_DEPRECATION_FACTORY)
warnings.warn(_DEPRECATION_FACTORY, DeprecationWarning)
return True
return False
def _implements(target_class: Type[interfaces.Plugin], iface: Type) -> bool:
if issubclass(target_class, iface):
return True
if iface == interfaces.Plugin and interfaces.IPlugin.implementedBy(target_class):
logging.warning(_DEPRECATION_PLUGIN)
warnings.warn(_DEPRECATION_PLUGIN, DeprecationWarning)
return True
if iface == interfaces.Authenticator and interfaces.IAuthenticator.implementedBy(target_class):
logging.warning(_DEPRECATION_AUTHENTICATOR)
warnings.warn(_DEPRECATION_AUTHENTICATOR, DeprecationWarning)
return True
if iface == interfaces.Installer and interfaces.IInstaller.implementedBy(target_class):
logging.warning(_DEPRECATION_INSTALLER)
warnings.warn(_DEPRECATION_INSTALLER, DeprecationWarning)
return True
return False
def _verify(target_instance: interfaces.Plugin, target_class: Type[interfaces.Plugin],
iface: Type) -> bool:
if issubclass(target_class, iface):
# No need to trigger some verify logic for ABCs: when the object is instantiated,
# an error would be raised if implementation is not done properly.
# So the checks have been done effectively when the plugin has been initialized.
return True
zope_iface: Optional[Type[zope.interface.Interface]] = None
message = ""
if iface == interfaces.Plugin:
zope_iface = interfaces.IPlugin
message = _DEPRECATION_PLUGIN
if iface == interfaces.Authenticator:
zope_iface = interfaces.IAuthenticator
message = _DEPRECATION_AUTHENTICATOR
if iface == interfaces.Installer:
zope_iface = interfaces.IInstaller
message = _DEPRECATION_INSTALLER
if not zope_iface:
raise ValueError(f"Unexpected type: {iface.__name__}")
try:
zope.interface.verify.verifyObject(zope_iface, target_instance)
logging.warning(message)
warnings.warn(message, DeprecationWarning)
return True
except zope.interface.exceptions.BrokenImplementation as error:
if zope_iface.implementedBy(target_class):
logger.debug(
"%s implements %s but object does not verify: %s",
target_class, zope_iface.__name__, error, exc_info=True)
return False
@@ -65,7 +65,6 @@ def get_unprepared_installer(config: configuration.NamespaceConfig,
return None
installers = plugins.filter(lambda p_ep: p_ep.check_name(req_inst))
installers.init(config)
installers = installers.verify((interfaces.Installer,))
if len(installers) > 1:
raise errors.PluginSelectionError(
"Found multiple installers with the name %s, Certbot is unable to "
@@ -116,9 +115,8 @@ def pick_plugin(config: configuration.NamespaceConfig, default: Optional[str],
filtered = plugins.visible().ifaces(ifaces)
filtered.init(config)
verified = filtered.verify(ifaces)
verified.prepare()
prepared = verified.available()
filtered.prepare()
prepared = filtered.available()
if len(prepared) > 1:
logger.debug("Multiple candidate plugins: %s", prepared)
-5
View File
@@ -19,12 +19,10 @@ from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import load_pem_private_key
import zope.component
from certbot import configuration
from certbot import crypto_util
from certbot import errors
from certbot import interfaces
from certbot import util
from certbot._internal import cli
from certbot._internal import client
@@ -460,9 +458,6 @@ def handle_renewal_request(config: configuration.NamespaceConfig) -> None:
if not renewal_candidate:
parse_failures.append(renewal_file)
else:
# This call is done only for retro-compatibility purposes.
# TODO: Remove this call once zope dependencies are removed from Certbot.
zope.component.provideUtility(lineage_config, interfaces.IConfig)
renewal_candidate.ensure_deployed()
from certbot._internal import main
plugins = plugins_disco.PluginsRegistry.find_all()
-94
View File
@@ -1,94 +0,0 @@
"""Collects and displays information to the user."""
import collections
import logging
import queue
import sys
import textwrap
from certbot import configuration
from certbot import util
logger = logging.getLogger(__name__)
class Reporter:
"""Collects and displays information to the user.
:ivar `queue.PriorityQueue` messages: Messages to be displayed to
the user.
"""
HIGH_PRIORITY = 0
"""High priority constant. See `add_message`."""
MEDIUM_PRIORITY = 1
"""Medium priority constant. See `add_message`."""
LOW_PRIORITY = 2
"""Low priority constant. See `add_message`."""
_msg_type = collections.namedtuple('_msg_type', 'priority text on_crash')
def __init__(self, config: configuration.NamespaceConfig) -> None:
self.messages: "queue.PriorityQueue[Reporter._msg_type]" = queue.PriorityQueue()
self.config = config
def add_message(self, msg: str, priority: int, on_crash: bool = True) -> None:
"""Adds msg to the list of messages to be printed.
:param str msg: Message to be displayed to the user.
:param int priority: One of `HIGH_PRIORITY`, `MEDIUM_PRIORITY`,
or `LOW_PRIORITY`.
:param bool on_crash: Whether or not the message should be
printed if the program exits abnormally.
"""
assert self.HIGH_PRIORITY <= priority <= self.LOW_PRIORITY
self.messages.put(self._msg_type(priority, msg, on_crash))
logger.debug("Reporting to user: %s", msg)
def print_messages(self) -> None:
"""Prints messages to the user and clears the message queue.
If there is an unhandled exception, only messages for which
``on_crash`` is ``True`` are printed.
"""
bold_on = False
if not self.messages.empty():
no_exception = sys.exc_info()[0] is None
bold_on = sys.stdout.isatty()
if not self.config.quiet:
if bold_on:
print(util.ANSI_SGR_BOLD)
print('IMPORTANT NOTES:')
first_wrapper = textwrap.TextWrapper(
initial_indent=' - ',
subsequent_indent=(' ' * 3),
break_long_words=False,
break_on_hyphens=False)
next_wrapper = textwrap.TextWrapper(
initial_indent=first_wrapper.subsequent_indent,
subsequent_indent=first_wrapper.subsequent_indent,
break_long_words=False,
break_on_hyphens=False)
while not self.messages.empty():
msg = self.messages.get()
if self.config.quiet:
# In --quiet mode, we only print high priority messages that
# are flagged for crash cases
if not (msg.priority == self.HIGH_PRIORITY and msg.on_crash):
continue
if no_exception or msg.on_crash:
if bold_on and msg.priority > self.HIGH_PRIORITY:
if not self.config.quiet:
sys.stdout.write(util.ANSI_SGR_RESET)
bold_on = False
lines = msg.text.splitlines()
print(first_wrapper.fill(lines[0]))
if len(lines) > 1:
print("\n".join(
next_wrapper.fill(line) for line in lines[1:]))
if bold_on and not self.config.quiet:
sys.stdout.write(util.ANSI_SGR_RESET)
+1 -68
View File
@@ -2,19 +2,13 @@
from abc import ABCMeta
from abc import abstractmethod
from argparse import ArgumentParser
import sys
from types import ModuleType
from typing import Any
from typing import Union
from typing import cast
from typing import Iterable
from typing import List
from typing import Optional
from typing import Type
from typing import TYPE_CHECKING
import warnings
import zope.interface
from typing import Union
from acme.challenges import Challenge
from acme.challenges import ChallengeResponse
@@ -62,18 +56,6 @@ class AccountStorage(metaclass=ABCMeta):
raise NotImplementedError()
class IConfig(zope.interface.Interface): # pylint: disable=inherit-non-class
"""Deprecated, use certbot.configuration.NamespaceConfig instead."""
class IPluginFactory(zope.interface.Interface): # pylint: disable=inherit-non-class
"""Deprecated, use certbot.interfaces.Plugin as ABC instead."""
class IPlugin(zope.interface.Interface): # pylint: disable=inherit-non-class
"""Deprecated, use certbot.interfaces.Plugin as ABC instead."""
class Plugin(metaclass=ABCMeta):
"""Certbot plugin.
@@ -168,10 +150,6 @@ class Plugin(metaclass=ABCMeta):
"""
class IAuthenticator(IPlugin): # pylint: disable=inherit-non-class
"""Deprecated, use certbot.interfaces.Authenticator as ABC instead."""
class Authenticator(Plugin):
"""Generic Certbot Authenticator.
@@ -231,10 +209,6 @@ class Authenticator(Plugin):
"""
class IInstaller(IPlugin): # pylint: disable=inherit-non-class
"""Deprecated, use certbot.interfaces.Installer as ABC instead."""
class Installer(Plugin):
"""Generic Certbot Installer Interface.
@@ -362,14 +336,6 @@ class Installer(Plugin):
"""
class IDisplay(zope.interface.Interface): # pylint: disable=inherit-non-class
"""Deprecated, use your own Display implementation instead."""
class IReporter(zope.interface.Interface): # pylint: disable=inherit-non-class
"""Deprecated, use your own Reporter implementation instead."""
class RenewableCert(metaclass=ABCMeta):
"""Interface to a certificate lineage."""
@@ -499,36 +465,3 @@ class RenewDeployer(metaclass=ABCMeta):
:type lineage: RenewableCert
"""
# This class takes a similar approach to the cryptography project to deprecate attributes
# in public modules. See the _ModuleWithDeprecation class here:
# https://github.com/pyca/cryptography/blob/91105952739442a74582d3e62b3d2111365b0dc7/src/cryptography/utils.py#L129
class _ZopeInterfacesDeprecationModule:
"""
Internal class delegating to a module, and displaying warnings when
attributes related to Zope interfaces are accessed.
"""
def __init__(self, module: ModuleType) -> None:
self.__dict__['_module'] = module
def __getattr__(self, attr: str) -> None:
if attr in ('IConfig', 'IPlugin', 'IPluginFactory', 'IAuthenticator',
'IInstaller', 'IDisplay', 'IReporter'):
warnings.warn('{0} attribute in certbot.interfaces module is deprecated '
'and will be removed soon.'.format(attr),
DeprecationWarning, stacklevel=2)
return getattr(self._module, attr)
def __setattr__(self, attr: str, value: Any) -> None: # pragma: no cover
setattr(self._module, attr, value)
def __delattr__(self, attr: str) -> None: # pragma: no cover
delattr(self._module, attr)
def __dir__(self) -> List[str]: # pragma: no cover
return ['_module'] + dir(self._module)
# Patching ourselves to warn about Zope interfaces deprecation and planned removal.
sys.modules[__name__] = cast(ModuleType, _ZopeInterfacesDeprecationModule(sys.modules[__name__]))
-2
View File
@@ -60,8 +60,6 @@ install_requires = [
# installation on Linux.
'pywin32>=300 ; sys_platform == "win32"',
f'setuptools>={min_setuptools_version}',
'zope.component',
'zope.interface',
]
dev_extras = [
+1 -2
View File
@@ -70,8 +70,7 @@ class HandleAuthorizationsTest(unittest.TestCase):
self.mock_display = mock.Mock()
self.mock_config = mock.Mock(debug_challenges=False)
with mock.patch("zope.component.provideUtility"):
display_obj.set_display(self.mock_display)
display_obj.set_display(self.mock_display)
self.mock_auth = mock.MagicMock(name="Authenticator")
+1 -1
View File
@@ -85,7 +85,7 @@ class ParseTest(unittest.TestCase):
@staticmethod
def parse(*args, **kwargs):
"""Mocks zope.component.getUtility and calls _unmocked_parse."""
"""Mocks certbot._internal.display.obj.get_display and calls _unmocked_parse."""
with test_util.patch_display_util():
return ParseTest._unmocked_parse(*args, **kwargs)
+1 -2
View File
@@ -70,8 +70,7 @@ class RegisterTest(test_util.ConfigTestCase):
self.config.email = "alias@example.com"
self.account_storage = account.AccountMemoryStorage()
self.tos_cb = mock.MagicMock()
with mock.patch("zope.component.provideUtility"):
display_obj.set_display(MagicMock())
display_obj.set_display(MagicMock())
def _call(self):
from certbot._internal.client import register
-2
View File
@@ -2,8 +2,6 @@
import logging
import unittest
import certbot.util
try:
import mock
except ImportError: # pragma: no cover
+4 -8
View File
@@ -1055,9 +1055,7 @@ class MainTest(test_util.ConfigTestCase):
plugins.visible().ifaces.assert_called_once_with(ifaces)
filtered = plugins.visible().ifaces()
self.assertEqual(filtered.init.call_count, 1)
filtered.verify.assert_called_once_with(ifaces)
verified = filtered.verify()
self.assertEqual(stdout.getvalue().strip(), str(verified))
self.assertEqual(stdout.getvalue().strip(), str(filtered))
@mock.patch('certbot._internal.main.plugins_disco')
@mock.patch('certbot._internal.main.cli.HelpfulArgumentParser.determine_help_topics')
@@ -1073,11 +1071,9 @@ class MainTest(test_util.ConfigTestCase):
plugins.visible().ifaces.assert_called_once_with(ifaces)
filtered = plugins.visible().ifaces()
self.assertEqual(filtered.init.call_count, 1)
filtered.verify.assert_called_once_with(ifaces)
verified = filtered.verify()
verified.prepare.assert_called_once_with()
verified.available.assert_called_once_with()
available = verified.available()
filtered.prepare.assert_called_once_with()
filtered.available.assert_called_once_with()
available = filtered.available()
self.assertEqual(stdout.getvalue().strip(), str(available))
def test_certonly_abspath(self):
-32
View File
@@ -5,7 +5,6 @@ from typing import List
import unittest
import pkg_resources
import zope.interface
from certbot import errors
from certbot import interfaces
@@ -129,29 +128,6 @@ class PluginEntryPointTest(unittest.TestCase):
self.assertIs(self.plugin_ep.misconfigured, False)
self.assertIs(self.plugin_ep.available, False)
def test_verify(self):
iface1 = mock.MagicMock(__name__="iface1")
iface2 = mock.MagicMock(__name__="iface2")
iface3 = mock.MagicMock(__name__="iface3")
# pylint: disable=protected-access
self.plugin_ep._initialized = plugin = mock.MagicMock()
exceptions = zope.interface.exceptions
with mock.patch("certbot._internal.plugins.disco._verify") as mock_verify:
mock_verify.exceptions = exceptions
def verify_object(obj, cls, iface): # pylint: disable=missing-docstring
assert obj is plugin
assert iface is iface1 or iface is iface2 or iface is iface3
if iface is iface3:
return False
return True
mock_verify.side_effect = verify_object
self.assertTrue(self.plugin_ep.verify((iface1,)))
self.assertTrue(self.plugin_ep.verify((iface1, iface2)))
self.assertFalse(self.plugin_ep.verify((iface3,)))
self.assertFalse(self.plugin_ep.verify((iface1, iface3)))
def test_prepare(self):
config = mock.MagicMock()
self.plugin_ep.init(config=config)
@@ -264,14 +240,6 @@ class PluginsRegistryTest(unittest.TestCase):
self.plugin_ep.ifaces.return_value = False
self.assertEqual({}, self.reg.ifaces()._plugins)
def test_verify(self):
self.plugin_ep.verify.return_value = True
# pylint: disable=protected-access
self.assertEqual(
self.plugins, self.reg.verify(mock.MagicMock())._plugins)
self.plugin_ep.verify.return_value = False
self.assertEqual({}, self.reg.verify(mock.MagicMock())._plugins)
def test_prepare(self):
self.plugin_ep.prepare.return_value = "baz"
self.assertEqual(["baz"], self.reg.prepare())
+4 -4
View File
@@ -77,7 +77,7 @@ class PickPluginTest(unittest.TestCase):
plugin_ep.init.return_value = "foo"
plugin_ep.misconfigured = False
self.reg.visible().ifaces().verify().available.return_value = {
self.reg.visible().ifaces().available.return_value = {
"bar": plugin_ep}
self.assertEqual("foo", self._call())
@@ -86,14 +86,14 @@ class PickPluginTest(unittest.TestCase):
plugin_ep.init.return_value = "foo"
plugin_ep.misconfigured = True
self.reg.visible().ifaces().verify().available.return_value = {
self.reg.visible().ifaces().available.return_value = {
"bar": plugin_ep}
self.assertIsNone(self._call())
def test_multiple(self):
plugin_ep = mock.MagicMock()
plugin_ep.init.return_value = "foo"
self.reg.visible().ifaces().verify().available.return_value = {
self.reg.visible().ifaces().available.return_value = {
"bar": plugin_ep,
"baz": plugin_ep,
}
@@ -104,7 +104,7 @@ class PickPluginTest(unittest.TestCase):
[plugin_ep, plugin_ep], self.question)
def test_choose_plugin_none(self):
self.reg.visible().ifaces().verify().available.return_value = {
self.reg.visible().ifaces().available.return_value = {
"bar": None,
"baz": None,
}
-89
View File
@@ -1,89 +0,0 @@
"""Tests for certbot._internal.reporter."""
import io
import sys
import unittest
try:
import mock
except ImportError: # pragma: no cover
from unittest import mock
class ReporterTest(unittest.TestCase):
"""Tests for certbot._internal.reporter.Reporter."""
def setUp(self):
from certbot._internal import reporter
self.reporter = reporter.Reporter(mock.MagicMock(quiet=False))
self.old_stdout = sys.stdout
sys.stdout = io.StringIO()
def tearDown(self):
sys.stdout = self.old_stdout
def test_multiline_message(self):
self.reporter.add_message("Line 1\nLine 2", self.reporter.LOW_PRIORITY)
self.reporter.print_messages()
output = sys.stdout.getvalue()
self.assertIn("Line 1\n", output)
self.assertIn("Line 2", output)
def test_tty_print_empty(self):
sys.stdout.isatty = lambda: True
self.test_no_tty_print_empty()
def test_no_tty_print_empty(self):
self.reporter.print_messages()
self.assertEqual(sys.stdout.getvalue(), "")
try:
raise ValueError
except ValueError:
self.reporter.print_messages()
self.assertEqual(sys.stdout.getvalue(), "")
def test_tty_successful_exit(self):
sys.stdout.isatty = lambda: True
self._successful_exit_common()
def test_no_tty_successful_exit(self):
self._successful_exit_common()
def test_tty_unsuccessful_exit(self):
sys.stdout.isatty = lambda: True
self._unsuccessful_exit_common()
def test_no_tty_unsuccessful_exit(self):
self._unsuccessful_exit_common()
def _successful_exit_common(self):
self._add_messages()
self.reporter.print_messages()
output = sys.stdout.getvalue()
self.assertIn("IMPORTANT NOTES:", output)
self.assertIn("High", output)
self.assertIn("Med", output)
self.assertIn("Low", output)
def _unsuccessful_exit_common(self):
self._add_messages()
try:
raise ValueError
except ValueError:
self.reporter.print_messages()
output = sys.stdout.getvalue()
self.assertIn("IMPORTANT NOTES:", output)
self.assertIn("High", output)
self.assertNotIn("Med", output)
self.assertNotIn("Low", output)
def _add_messages(self):
self.reporter.add_message("High", self.reporter.HIGH_PRIORITY)
self.reporter.add_message(
"Med", self.reporter.MEDIUM_PRIORITY, on_crash=False)
self.reporter.add_message(
"Low", self.reporter.LOW_PRIORITY, on_crash=False)
if __name__ == "__main__":
unittest.main() # pragma: no cover
+4 -11
View File
@@ -13,25 +13,18 @@
# The current warnings being ignored are:
# 1) The warning raised when importing certbot.tests.util and the external mock
# library is installed.
# 2) An ImportWarning is raised with older versions of setuptools and
# zope.interface. See
# https://github.com/zopefoundation/zope.interface/issues/68 for more info.
# 3) The deprecation warning raised when importing old Zope interfaces from
# the certbot.interfaces module.
# 4) The deprecation warning raised when importing deprecated attributes from
# 2) The deprecation warning raised when importing deprecated attributes from
# the certbot.display.util module.
# 5) A deprecation warning is raised in dnspython==1.15.0 in the oldest tests for
# 3) A deprecation warning is raised in dnspython==1.15.0 in the oldest tests for
# certbot-dns-rfc2136.
# 6) The vendored version of six in botocore causes ImportWarnings in Python
# 4) The vendored version of six in botocore causes ImportWarnings in Python
# 3.10+. See https://github.com/boto/botocore/issues/2548.
# 7) botocore's default TLS settings raise deprecation warnings in Python
# 5) botocore's default TLS settings raise deprecation warnings in Python
# 3.10+, but their values are sane from a security perspective. See
# https://github.com/boto/botocore/issues/2550.
filterwarnings =
error
ignore:The external mock module:PendingDeprecationWarning
ignore:.*zope. missing __init__:ImportWarning
ignore:.*attribute in certbot.interfaces module is deprecated:DeprecationWarning
ignore:.*attribute in certbot.display.util module is deprecated:DeprecationWarning
ignore:decodestring\(\) is a deprecated alias:DeprecationWarning:dns
ignore:_SixMetaPathImporter.:ImportWarning
+21 -25
View File
@@ -2,9 +2,9 @@
# that script.
apacheconfig==0.3.2
asn1crypto==0.24.0
astroid==2.11.6; python_version >= "3.7"
atomicwrites==1.4.0; sys_platform == "win32" and python_version >= "3.7"
attrs==21.4.0; python_version >= "3.7"
astroid==2.11.7; python_version >= "3.7"
atomicwrites==1.4.1; sys_platform == "win32" and python_version >= "3.7"
attrs==22.1.0; python_version >= "3.7"
bcrypt==3.2.2; python_version >= "3.7"
boto3==1.15.15
botocore==1.18.15
@@ -16,11 +16,11 @@ cloudflare==1.5.1
colorama==0.4.5; sys_platform == "win32" and python_version >= "3.7"
configargparse==0.10.0
configobj==5.0.6
coverage==6.4.1; python_version >= "3.7"
coverage==6.4.2; python_version >= "3.7"
cryptography==3.2.1
cython==0.29.30
cython==0.29.31
dill==0.3.5.1; python_version >= "3.7"
distlib==0.3.4; python_version >= "3.7"
distlib==0.3.5; python_version >= "3.7"
distro==1.0.1
dns-lexicon==3.2.1
dnspython==1.15.0
@@ -35,7 +35,7 @@ future==0.18.2; python_version >= "3.7"
google-api-python-client==1.5.5
httplib2==0.9.2
idna==2.6
importlib-metadata==4.11.4; python_version < "3.8" and python_version >= "3.7"
importlib-metadata==4.12.0; python_version < "3.8" and python_version >= "3.7"
iniconfig==1.1.1; python_version >= "3.7"
ipaddress==1.0.16
isort==5.10.1; python_version >= "3.7" and python_version < "4.0"
@@ -47,14 +47,14 @@ logger==1.4; python_version >= "3.7"
mccabe==0.7.0; python_version >= "3.7"
mock==1.0.1
mypy-extensions==0.4.3; python_version >= "3.7"
mypy==0.961; python_version >= "3.7"
mypy==0.971; python_version >= "3.7"
ndg-httpsclient==0.3.2
oauth2client==4.0.0
packaging==21.3; python_version >= "3.7"
paramiko==2.11.0; python_version >= "3.7"
parsedatetime==2.4
pbr==1.8.0
pip==22.1.2; python_version >= "3.7"
pip==22.2.1; python_version >= "3.7"
platformdirs==2.5.2; python_version >= "3.7"
pluggy==1.0.0; python_version >= "3.7"
ply==3.4
@@ -83,35 +83,31 @@ pyyaml==5.4.1; python_version >= "3.7"
requests-file==1.5.1; python_version >= "3.7"
requests-toolbelt==0.9.1; python_version >= "3.7"
requests==2.20.0
rsa==4.8; python_version >= "3.7" and python_version < "4"
rsa==4.9; python_version >= "3.7" and python_version < "4"
s3transfer==0.3.7; python_version >= "3.7"
setuptools==41.6.0
six==1.11.0
texttable==1.6.4; python_version >= "3.7"
tldextract==3.3.0; python_version >= "3.7"
tldextract==3.3.1; python_version >= "3.7"
tomli==2.0.1; python_version < "3.11" and python_version >= "3.7" or python_full_version <= "3.11.0a6" and python_version >= "3.7" or python_version >= "3.7"
tox==1.9.2; python_version >= "3.7"
typed-ast==1.5.4; python_version >= "3.7" and python_version < "3.8" or implementation_name == "cpython" and python_version < "3.8" and python_version >= "3.7"
types-cryptography==3.3.21; python_version >= "3.7"
types-mock==4.0.15; python_version >= "3.7"
types-pyopenssl==22.0.3; python_version >= "3.7"
types-pyopenssl==22.0.9; python_version >= "3.7"
types-pyrfc3339==1.1.1; python_version >= "3.7"
types-python-dateutil==2.8.17; python_version >= "3.7"
types-pytz==2022.1.0; python_version >= "3.7"
types-requests==2.27.31; python_version >= "3.7"
types-setuptools==57.4.17; python_version >= "3.7"
types-six==1.16.16; python_version >= "3.7"
types-urllib3==1.26.15; python_version >= "3.7"
typing-extensions==4.2.0; python_version >= "3.7" or python_version < "3.10" and python_version >= "3.7" or python_version < "3.8" and python_version >= "3.7"
types-python-dateutil==2.8.19; python_version >= "3.7"
types-pytz==2022.1.2; python_version >= "3.7"
types-requests==2.28.5; python_version >= "3.7"
types-setuptools==63.2.2; python_version >= "3.7"
types-six==1.16.18; python_version >= "3.7"
types-urllib3==1.26.17; python_version >= "3.7"
typing-extensions==4.3.0; python_version >= "3.7" or python_version < "3.10" and python_version >= "3.7" or python_version < "3.8" and python_version >= "3.7"
uritemplate==3.0.1; python_version >= "3.7"
urllib3==1.24.2
virtualenv==20.14.1; python_version >= "3.7"
virtualenv==20.16.2; python_version >= "3.7"
websocket-client==0.59.0; python_version >= "3.7"
wheel==0.33.6
wheel==0.33.6; python_version >= "3.7"
wrapt==1.14.1; python_version >= "3.7"
zipp==3.8.0; python_version < "3.8" and python_version >= "3.7"
zope.component==4.1.0
zope.event==4.0.3
zope.hookable==4.0.4
zope.interface==4.0.5
zipp==3.8.1; python_version < "3.8" and python_version >= "3.7"
-5
View File
@@ -79,11 +79,6 @@ requests = "2.20.0"
setuptools = "41.6.0"
six = "1.11.0"
urllib3 = "1.24.2"
# Package names containing "." need to be quoted.
"zope.component" = "4.1.0"
"zope.event" = "4.0.3"
"zope.hookable" = "4.0.4"
"zope.interface" = "4.0.5"
# Build dependencies
# Since there doesn't appear to
+1 -5
View File
@@ -189,8 +189,4 @@ websocket-client==0.59.0; python_version >= "3.7" and python_full_version < "3.0
wheel==0.37.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0"
wrapt==1.13.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0" or python_version >= "3.7" and python_full_version >= "3.6.2"
yarg==0.1.9; python_version >= "3.7"
zipp==3.7.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "3.8" or python_version >= "3.7" and python_version < "3.8" and python_full_version >= "3.5.0"
zope.component==5.0.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
zope.event==4.5.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
zope.hookable==5.1.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
zope.interface==5.4.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
zipp==3.8.1; python_version >= "3.7" and python_version < "3.8"