mirror of
https://github.com/certbot/certbot.git
synced 2026-05-28 04:34:11 -04:00
Get mypy passing with check_untyped_defs everywhere (#6021)
* unchecked_typed_defs everywhere * fix mypy for lock_test * add magic_typing * fix mypy in letshelp * fix validator errors in compat test * fix mypy for test_driver.py * fix mypy in util.py * delint
This commit is contained in:
parent
0d3a157525
commit
c9a206ca89
9 changed files with 106 additions and 85 deletions
|
|
@ -15,6 +15,7 @@ from six.moves import xrange # pylint: disable=import-error,redefined-builtin
|
|||
from acme import challenges
|
||||
from acme import crypto_util
|
||||
from acme import messages
|
||||
from acme.magic_typing import List, Tuple # pylint: disable=unused-import, no-name-in-module
|
||||
from certbot import achallenges
|
||||
from certbot import errors as le_errors
|
||||
from certbot.tests import acme_util
|
||||
|
|
@ -52,9 +53,8 @@ def test_authenticator(plugin, config, temp_dir):
|
|||
|
||||
try:
|
||||
responses = plugin.perform(achalls)
|
||||
except le_errors.Error as error:
|
||||
logger.error("Performing challenges on %s caused an error:", config)
|
||||
logger.exception(error)
|
||||
except le_errors.Error:
|
||||
logger.error("Performing challenges on %s caused an error:", config, exc_info=True)
|
||||
return False
|
||||
|
||||
success = True
|
||||
|
|
@ -82,9 +82,8 @@ def test_authenticator(plugin, config, temp_dir):
|
|||
if success:
|
||||
try:
|
||||
plugin.cleanup(achalls)
|
||||
except le_errors.Error as error:
|
||||
logger.error("Challenge cleanup for %s caused an error:", config)
|
||||
logger.exception(error)
|
||||
except le_errors.Error:
|
||||
logger.error("Challenge cleanup for %s caused an error:", config, exc_info=True)
|
||||
success = False
|
||||
|
||||
if _dirs_are_unequal(config, backup):
|
||||
|
|
@ -147,9 +146,8 @@ def test_deploy_cert(plugin, temp_dir, domains):
|
|||
try:
|
||||
plugin.deploy_cert(domain, cert_path, util.KEY_PATH, cert_path, cert_path)
|
||||
plugin.save() # Needed by the Apache plugin
|
||||
except le_errors.Error as error:
|
||||
logger.error("**** Plugin failed to deploy certificate for %s:", domain)
|
||||
logger.exception(error)
|
||||
except le_errors.Error:
|
||||
logger.error("**** Plugin failed to deploy certificate for %s:", domain, exc_info=True)
|
||||
return False
|
||||
|
||||
if not _save_and_restart(plugin, "deployed"):
|
||||
|
|
@ -179,7 +177,7 @@ def test_enhancements(plugin, domains):
|
|||
"enhancements")
|
||||
return False
|
||||
|
||||
domains_and_info = [(domain, []) for domain in domains]
|
||||
domains_and_info = [(domain, []) for domain in domains] # type: List[Tuple[str, List[bool]]]
|
||||
|
||||
for domain, info in domains_and_info:
|
||||
try:
|
||||
|
|
@ -192,10 +190,9 @@ def test_enhancements(plugin, domains):
|
|||
# Don't immediately fail because a redirect may already be enabled
|
||||
logger.warning("*** Plugin failed to enable redirect for %s:", domain)
|
||||
logger.warning("%s", error)
|
||||
except le_errors.Error as error:
|
||||
except le_errors.Error:
|
||||
logger.error("*** An error occurred while enabling redirect for %s:",
|
||||
domain)
|
||||
logger.exception(error)
|
||||
domain, exc_info=True)
|
||||
|
||||
if not _save_and_restart(plugin, "enhanced"):
|
||||
return False
|
||||
|
|
@ -222,9 +219,8 @@ def _save_and_restart(plugin, title=None):
|
|||
plugin.save(title)
|
||||
plugin.restart()
|
||||
return True
|
||||
except le_errors.Error as error:
|
||||
logger.error("*** Plugin failed to save and restart server:")
|
||||
logger.exception(error)
|
||||
except le_errors.Error:
|
||||
logger.error("*** Plugin failed to save and restart server:", exc_info=True)
|
||||
return False
|
||||
|
||||
|
||||
|
|
@ -232,9 +228,8 @@ def test_rollback(plugin, config, backup):
|
|||
"""Tests the rollback checkpoints function"""
|
||||
try:
|
||||
plugin.rollback_checkpoints(1337)
|
||||
except le_errors.Error as error:
|
||||
logger.error("*** Plugin raised an exception during rollback:")
|
||||
logger.exception(error)
|
||||
except le_errors.Error:
|
||||
logger.error("*** Plugin raised an exception during rollback:", exc_info=True)
|
||||
return False
|
||||
|
||||
if _dirs_are_unequal(config, backup):
|
||||
|
|
@ -263,21 +258,21 @@ def _dirs_are_unequal(dir1, dir2):
|
|||
logger.error("The following files and directories are only "
|
||||
"present in one directory")
|
||||
if dircmp.left_only:
|
||||
logger.error(dircmp.left_only)
|
||||
logger.error(str(dircmp.left_only))
|
||||
else:
|
||||
logger.error(dircmp.right_only)
|
||||
logger.error(str(dircmp.right_only))
|
||||
return True
|
||||
elif dircmp.common_funny or dircmp.funny_files:
|
||||
logger.error("The following files and directories could not be "
|
||||
"compared:")
|
||||
if dircmp.common_funny:
|
||||
logger.error(dircmp.common_funny)
|
||||
logger.error(str(dircmp.common_funny))
|
||||
else:
|
||||
logger.error(dircmp.funny_files)
|
||||
logger.error(str(dircmp.funny_files))
|
||||
return True
|
||||
elif dircmp.diff_files:
|
||||
logger.error("The following files differ:")
|
||||
logger.error(dircmp.diff_files)
|
||||
logger.error(str(dircmp.diff_files))
|
||||
return True
|
||||
|
||||
for subdir in dircmp.subdirs.itervalues():
|
||||
|
|
@ -354,9 +349,8 @@ def main():
|
|||
success = test_authenticator(plugin, config, temp_dir)
|
||||
if success and args.install:
|
||||
success = test_installer(args, plugin, config, temp_dir)
|
||||
except errors.Error as error:
|
||||
logger.error("Tests on %s raised:", config)
|
||||
logger.exception(error)
|
||||
except errors.Error:
|
||||
logger.error("Tests on %s raised:", config, exc_info=True)
|
||||
success = False
|
||||
|
||||
if success:
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ def create_le_config(parent_dir):
|
|||
config = copy.deepcopy(constants.CLI_DEFAULTS)
|
||||
|
||||
le_dir = os.path.join(parent_dir, "certbot")
|
||||
config["config_dir"] = os.path.join(le_dir, "config")
|
||||
config["work_dir"] = os.path.join(le_dir, "work")
|
||||
config["logs_dir"] = os.path.join(le_dir, "logs_dir")
|
||||
os.makedirs(config["config_dir"])
|
||||
os.mkdir(config["work_dir"])
|
||||
os.mkdir(config["logs_dir"])
|
||||
os.mkdir(le_dir)
|
||||
for dir_name in ("config", "logs", "work"):
|
||||
full_path = os.path.join(le_dir, dir_name)
|
||||
os.mkdir(full_path)
|
||||
full_name = dir_name + "_dir"
|
||||
config[full_name] = full_path
|
||||
|
||||
config["domains"] = None
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Validator(object):
|
|||
try:
|
||||
presented_cert = crypto_util.probe_sni(name, host, port)
|
||||
except acme_errors.Error as error:
|
||||
logger.exception(error)
|
||||
logger.exception(str(error))
|
||||
return False
|
||||
|
||||
return presented_cert.digest("sha256") == cert.digest("sha256")
|
||||
|
|
@ -86,8 +86,7 @@ class Validator(object):
|
|||
return False
|
||||
|
||||
try:
|
||||
_, max_age_value = max_age[0]
|
||||
max_age_value = int(max_age_value)
|
||||
max_age_value = int(max_age[0][1])
|
||||
except ValueError:
|
||||
logger.error("Server responded with invalid HSTS header field")
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ import textwrap
|
|||
|
||||
import six
|
||||
|
||||
from letshelp_certbot.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
|
||||
_DESCRIPTION = """
|
||||
Let's Help is a simple script you can run to help out the Certbot
|
||||
project. Since Certbot will support automatically configuring HTTPS on
|
||||
|
|
@ -87,7 +89,8 @@ def copy_config(server_root, temp_dir):
|
|||
:rtype: `tuple` of `list` of `str`
|
||||
|
||||
"""
|
||||
copied_files, copied_dirs = [], []
|
||||
copied_files = [] # type: List[str]
|
||||
copied_dirs = [] # type: List[str]
|
||||
dir_len = len(os.path.dirname(server_root))
|
||||
|
||||
for config_path, config_dirs, config_files in os.walk(server_root):
|
||||
|
|
|
|||
|
|
@ -203,13 +203,19 @@ class LetsHelpApacheTest(unittest.TestCase):
|
|||
tempdir_path, "config.tar.gz"))
|
||||
|
||||
tempdir = tar.next()
|
||||
self.assertTrue(tempdir.isdir())
|
||||
self.assertEqual(tempdir.name, ".")
|
||||
if tempdir is None:
|
||||
self.fail("Invalid tarball!") # pragma: no cover
|
||||
else:
|
||||
self.assertTrue(tempdir.isdir())
|
||||
self.assertEqual(tempdir.name, ".")
|
||||
|
||||
testdir = tar.next()
|
||||
self.assertTrue(testdir.isdir())
|
||||
self.assertEqual(os.path.basename(testdir.name),
|
||||
testdir_basename)
|
||||
if testdir is None:
|
||||
self.fail("Invalid tarball!") # pragma: no cover
|
||||
else:
|
||||
self.assertTrue(testdir.isdir())
|
||||
self.assertEqual(os.path.basename(testdir.name),
|
||||
testdir_basename)
|
||||
|
||||
self.assertEqual(tar.next(), None)
|
||||
|
||||
|
|
|
|||
16
letshelp-certbot/letshelp_certbot/magic_typing.py
Normal file
16
letshelp-certbot/letshelp_certbot/magic_typing.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
"""Shim class to not have to depend on typing module in prod."""
|
||||
import sys
|
||||
|
||||
class TypingClass(object):
|
||||
"""Ignore import errors by getting anything"""
|
||||
def __getattr__(self, name):
|
||||
return None
|
||||
|
||||
try:
|
||||
# mypy doesn't respect modifying sys.modules
|
||||
from typing import * # pylint: disable=wildcard-import, unused-wildcard-import
|
||||
# pylint: disable=unused-import
|
||||
from typing import Collection, IO # type: ignore
|
||||
# pylint: enable=unused-import
|
||||
except ImportError:
|
||||
sys.modules[__name__] = TypingClass()
|
||||
41
letshelp-certbot/letshelp_certbot/magic_typing_test.py
Normal file
41
letshelp-certbot/letshelp_certbot/magic_typing_test.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
"""Tests for letshelp_certbot.magic_typing."""
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
|
||||
|
||||
class MagicTypingTest(unittest.TestCase):
|
||||
"""Tests for letshelp_certbot.magic_typing."""
|
||||
def test_import_success(self):
|
||||
try:
|
||||
import typing as temp_typing
|
||||
except ImportError: # pragma: no cover
|
||||
temp_typing = None # pragma: no cover
|
||||
typing_class_mock = mock.MagicMock()
|
||||
text_mock = mock.MagicMock()
|
||||
typing_class_mock.Text = text_mock
|
||||
sys.modules['typing'] = typing_class_mock
|
||||
if 'letshelp_certbot.magic_typing' in sys.modules:
|
||||
del sys.modules['letshelp_certbot.magic_typing'] # pragma: no cover
|
||||
from letshelp_certbot.magic_typing import Text # pylint: disable=no-name-in-module
|
||||
self.assertEqual(Text, text_mock)
|
||||
del sys.modules['letshelp_certbot.magic_typing']
|
||||
sys.modules['typing'] = temp_typing
|
||||
|
||||
def test_import_failure(self):
|
||||
try:
|
||||
import typing as temp_typing
|
||||
except ImportError: # pragma: no cover
|
||||
temp_typing = None # pragma: no cover
|
||||
sys.modules['typing'] = None
|
||||
if 'letshelp_certbot.magic_typing' in sys.modules:
|
||||
del sys.modules['letshelp_certbot.magic_typing'] # pragma: no cover
|
||||
from letshelp_certbot.magic_typing import Text # pylint: disable=no-name-in-module
|
||||
self.assertTrue(Text is None)
|
||||
del sys.modules['letshelp_certbot.magic_typing']
|
||||
sys.modules['typing'] = temp_typing
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main() # pragma: no cover
|
||||
46
mypy.ini
46
mypy.ini
|
|
@ -1,48 +1,10 @@
|
|||
[mypy]
|
||||
python_version = 2.7
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-acme.*]
|
||||
check_untyped_defs = True
|
||||
ignore_missing_imports = True
|
||||
python_version = 2.7
|
||||
|
||||
[mypy-acme.magic_typing_test]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-certbot.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_apache.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_cloudflare.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_cloudxns.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_digitalocean.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_dnsimple.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_dnsmadeeasy.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_google.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_luadns.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_nsone.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_rfc2136.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_dns_route53.*]
|
||||
check_untyped_defs = True
|
||||
|
||||
[mypy-certbot_nginx.*]
|
||||
check_untyped_defs = True
|
||||
[mypy-letshelp_certbot.magic_typing_test]
|
||||
ignore_errors = True
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ def report_failure(err_msg, out, err):
|
|||
:param str err: stderr output
|
||||
|
||||
"""
|
||||
logger.fatal(err_msg)
|
||||
logger.critical(err_msg)
|
||||
log_output(logging.INFO, out, err)
|
||||
sys.exit(err_msg)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue