mirror of
https://github.com/certbot/certbot.git
synced 2026-07-28 08:45:19 +02:00
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:
co-authored by
Alex Zorin
parent
529a0e2272
commit
9d736d5c9c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -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__]))
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,8 +2,6 @@
|
||||
import logging
|
||||
import unittest
|
||||
|
||||
import certbot.util
|
||||
|
||||
try:
|
||||
import mock
|
||||
except ImportError: # pragma: no cover
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user