* Initial configuration of mypy in box, correction of base mypy errors.

* Move mypy install to toe

* Add pylint comments for typing imports.

* Remove typing module for Python 2.6 compatibility.
This commit is contained in:
dokazaki
2017-03-18 19:10:10 -07:00
committed by Brad Warren
parent 679887f691
commit 8011fb2879
20 changed files with 59 additions and 48 deletions
+3 -3
View File
@@ -5,7 +5,7 @@ import hashlib
import logging import logging
import socket import socket
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes # type: ignore
import OpenSSL import OpenSSL
import requests import requests
@@ -23,7 +23,7 @@ logger = logging.getLogger(__name__)
class Challenge(jose.TypedJSONObjectWithFields): class Challenge(jose.TypedJSONObjectWithFields):
# _fields_to_partial_json | pylint: disable=abstract-method # _fields_to_partial_json | pylint: disable=abstract-method
"""ACME challenge.""" """ACME challenge."""
TYPES = {} TYPES = {} # type: dict
@classmethod @classmethod
def from_json(cls, jobj): def from_json(cls, jobj):
@@ -37,7 +37,7 @@ class Challenge(jose.TypedJSONObjectWithFields):
class ChallengeResponse(jose.TypedJSONObjectWithFields): class ChallengeResponse(jose.TypedJSONObjectWithFields):
# _fields_to_partial_json | pylint: disable=abstract-method # _fields_to_partial_json | pylint: disable=abstract-method
"""ACME challenge response.""" """ACME challenge response."""
TYPES = {} TYPES = {} # type: dict
resource_type = 'challenge' resource_type = 'challenge'
resource = fields.Resource(resource_type) resource = fields.Resource(resource_type)
+1 -1
View File
@@ -28,7 +28,7 @@ logger = logging.getLogger(__name__)
# https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning # https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning
if sys.version_info < (2, 7, 9): # pragma: no cover if sys.version_info < (2, 7, 9): # pragma: no cover
try: try:
requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3() requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3() # type: ignore
except AttributeError: except AttributeError:
import urllib3.contrib.pyopenssl # pylint: disable=import-error import urllib3.contrib.pyopenssl # pylint: disable=import-error
urllib3.contrib.pyopenssl.inject_into_urllib3() urllib3.contrib.pyopenssl.inject_into_urllib3()
+1 -1
View File
@@ -23,7 +23,7 @@ logger = logging.getLogger(__name__)
# https://www.openssl.org/docs/ssl/SSLv23_method.html). _serve_sni # https://www.openssl.org/docs/ssl/SSLv23_method.html). _serve_sni
# should be changed to use "set_options" to disable SSLv2 and SSLv3, # should be changed to use "set_options" to disable SSLv2 and SSLv3,
# in case it's used for things other than probing/serving! # in case it's used for things other than probing/serving!
_DEFAULT_TLSSNI01_SSL_METHOD = OpenSSL.SSL.SSLv23_METHOD _DEFAULT_TLSSNI01_SSL_METHOD = OpenSSL.SSL.SSLv23_METHOD # type: ignore
class SSLSocket(object): # pylint: disable=too-few-public-methods class SSLSocket(object): # pylint: disable=too-few-public-methods
+1 -1
View File
@@ -6,7 +6,7 @@ import time
import unittest import unittest
import six import six
from six.moves import socketserver # pylint: disable=import-error from six.moves import socketserver #type: ignore # pylint: disable=import-error
import OpenSSL import OpenSSL
+5 -5
View File
@@ -9,9 +9,9 @@ import logging
import cryptography.exceptions import cryptography.exceptions
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes # type: ignore
from cryptography.hazmat.primitives import hmac from cryptography.hazmat.primitives import hmac # type: ignore
from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.asymmetric import padding # type: ignore
from acme.jose import errors from acme.jose import errors
from acme.jose import interfaces from acme.jose import interfaces
@@ -28,9 +28,9 @@ class JWA(interfaces.JSONDeSerializable): # pylint: disable=abstract-method
"""JSON Web Algorithm.""" """JSON Web Algorithm."""
class JWASignature(JWA, collections.Hashable): class JWASignature(JWA, collections.Hashable): # type: ignore
"""JSON Web Signature Algorithm.""" """JSON Web Signature Algorithm."""
SIGNATURES = {} SIGNATURES = {} # type: dict
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
+4 -4
View File
@@ -6,9 +6,9 @@ import logging
import cryptography.exceptions import cryptography.exceptions
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes # type: ignore
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.asymmetric import ec # type: ignore
from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.asymmetric import rsa
import six import six
@@ -25,8 +25,8 @@ class JWK(json_util.TypedJSONObjectWithFields):
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
"""JSON Web Key.""" """JSON Web Key."""
type_field_name = 'kty' type_field_name = 'kty'
TYPES = {} TYPES = {} # type: dict
cryptography_key_types = () cryptography_key_types = () # type: tuple
"""Subclasses should override.""" """Subclasses should override."""
required = NotImplemented required = NotImplemented
+4 -4
View File
@@ -121,12 +121,12 @@ class Header(json_util.JSONObjectWithFields):
# x5c does NOT use JOSE Base64 (4.1.6) # x5c does NOT use JOSE Base64 (4.1.6)
@x5c.encoder @x5c.encoder # type: ignore
def x5c(value): # pylint: disable=missing-docstring,no-self-argument def x5c(value): # pylint: disable=missing-docstring,no-self-argument
return [base64.b64encode(OpenSSL.crypto.dump_certificate( return [base64.b64encode(OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_ASN1, cert.wrapped)) for cert in value] OpenSSL.crypto.FILETYPE_ASN1, cert.wrapped)) for cert in value]
@x5c.decoder @x5c.decoder # type: ignore
def x5c(value): # pylint: disable=missing-docstring,no-self-argument def x5c(value): # pylint: disable=missing-docstring,no-self-argument
try: try:
return tuple(util.ComparableX509(OpenSSL.crypto.load_certificate( return tuple(util.ComparableX509(OpenSSL.crypto.load_certificate(
@@ -157,12 +157,12 @@ class Signature(json_util.JSONObjectWithFields):
'signature', decoder=json_util.decode_b64jose, 'signature', decoder=json_util.decode_b64jose,
encoder=json_util.encode_b64jose) encoder=json_util.encode_b64jose)
@protected.encoder @protected.encoder # type: ignore
def protected(value): # pylint: disable=missing-docstring,no-self-argument def protected(value): # pylint: disable=missing-docstring,no-self-argument
# wrong type guess (Signature, not bytes) | pylint: disable=no-member # wrong type guess (Signature, not bytes) | pylint: disable=no-member
return json_util.encode_b64jose(value.encode('utf-8')) return json_util.encode_b64jose(value.encode('utf-8'))
@protected.decoder @protected.decoder # type: ignore
def protected(value): # pylint: disable=missing-docstring,no-self-argument def protected(value): # pylint: disable=missing-docstring,no-self-argument
return json_util.decode_b64jose(value).decode('utf-8') return json_util.decode_b64jose(value).decode('utf-8')
+2 -2
View File
@@ -134,7 +134,7 @@ class ComparableRSAKey(ComparableKey): # pylint: disable=too-few-public-methods
return hash((self.__class__, pub.n, pub.e)) return hash((self.__class__, pub.n, pub.e))
class ImmutableMap(collections.Mapping, collections.Hashable): class ImmutableMap(collections.Mapping, collections.Hashable): # type: ignore
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
"""Immutable key to value mapping with attribute access.""" """Immutable key to value mapping with attribute access."""
@@ -180,7 +180,7 @@ class ImmutableMap(collections.Mapping, collections.Hashable):
for key, value in six.iteritems(self))) for key, value in six.iteritems(self)))
class frozendict(collections.Mapping, collections.Hashable): class frozendict(collections.Mapping, collections.Hashable): # type: ignore
# pylint: disable=invalid-name,too-few-public-methods # pylint: disable=invalid-name,too-few-public-methods
"""Frozen dictionary.""" """Frozen dictionary."""
__slots__ = ('_items', '_keys') __slots__ = ('_items', '_keys')
+4 -4
View File
@@ -98,7 +98,7 @@ class Error(jose.JSONObjectWithFields, errors.Error):
if part is not None) if part is not None)
class _Constant(jose.JSONDeSerializable, collections.Hashable): class _Constant(jose.JSONDeSerializable, collections.Hashable): # type: ignore
"""ACME constant.""" """ACME constant."""
__slots__ = ('name',) __slots__ = ('name',)
POSSIBLE_NAMES = NotImplemented POSSIBLE_NAMES = NotImplemented
@@ -132,7 +132,7 @@ class _Constant(jose.JSONDeSerializable, collections.Hashable):
class Status(_Constant): class Status(_Constant):
"""ACME "status" field.""" """ACME "status" field."""
POSSIBLE_NAMES = {} POSSIBLE_NAMES = {} # type: dict
STATUS_UNKNOWN = Status('unknown') STATUS_UNKNOWN = Status('unknown')
STATUS_PENDING = Status('pending') STATUS_PENDING = Status('pending')
STATUS_PROCESSING = Status('processing') STATUS_PROCESSING = Status('processing')
@@ -143,7 +143,7 @@ STATUS_REVOKED = Status('revoked')
class IdentifierType(_Constant): class IdentifierType(_Constant):
"""ACME identifier type.""" """ACME identifier type."""
POSSIBLE_NAMES = {} POSSIBLE_NAMES = {} # type: dict
IDENTIFIER_FQDN = IdentifierType('dns') # IdentifierDNS in Boulder IDENTIFIER_FQDN = IdentifierType('dns') # IdentifierDNS in Boulder
@@ -161,7 +161,7 @@ class Identifier(jose.JSONObjectWithFields):
class Directory(jose.JSONDeSerializable): class Directory(jose.JSONDeSerializable):
"""Directory.""" """Directory."""
_REGISTERED_TYPES = {} _REGISTERED_TYPES = {} # type: dict
class Meta(jose.JSONObjectWithFields): class Meta(jose.JSONObjectWithFields):
"""Directory Meta.""" """Directory Meta."""
+2 -2
View File
@@ -6,9 +6,9 @@ import logging
import os import os
import sys import sys
from six.moves import BaseHTTPServer # pylint: disable=import-error from six.moves import BaseHTTPServer # type: ignore # pylint: disable=import-error
from six.moves import http_client # pylint: disable=import-error from six.moves import http_client # pylint: disable=import-error
from six.moves import socketserver # pylint: disable=import-error from six.moves import socketserver # type: ignore # pylint: disable=import-error
import OpenSSL import OpenSSL
+1 -1
View File
@@ -7,7 +7,7 @@ import time
import unittest import unittest
from six.moves import http_client # pylint: disable=import-error from six.moves import http_client # pylint: disable=import-error
from six.moves import socketserver # pylint: disable=import-error from six.moves import socketserver # type: ignore # pylint: disable=import-error
import requests import requests
@@ -20,20 +20,20 @@ class IPluginProxy(zope.interface.Interface):
def __init__(args): def __init__(args):
"""Initializes the plugin with the given command line args""" """Initializes the plugin with the given command line args"""
def cleanup_from_tests(): def cleanup_from_tests(): # type: ignore
"""Performs any necessary cleanup from running plugin tests. """Performs any necessary cleanup from running plugin tests.
This is guaranteed to be called before the program exits. This is guaranteed to be called before the program exits.
""" """
def has_more_configs(): def has_more_configs(): # type: ignore
"""Returns True if there are more configs to test""" """Returns True if there are more configs to test"""
def load_config(): def load_config(): # type: ignore
"""Loads the next config and returns its name""" """Loads the next config and returns its name"""
def get_testable_domain_names(): def get_testable_domain_names(): # type: ignore
"""Returns the domain names that can be used in testing""" """Returns the domain names that can be used in testing"""
@@ -44,7 +44,7 @@ class IAuthenticatorProxy(IPluginProxy, certbot.interfaces.IAuthenticator):
class IInstallerProxy(IPluginProxy, certbot.interfaces.IInstaller): class IInstallerProxy(IPluginProxy, certbot.interfaces.IInstaller):
"""Wraps a Certbot installer""" """Wraps a Certbot installer"""
def get_all_names_answer(): def get_all_names_answer(): # type: ignore
"""Returns all names that should be found by the installer""" """Returns all names that should be found by the installer"""
+1 -1
View File
@@ -207,7 +207,7 @@ def set_by_cli(var):
return False return False
# static housekeeping var # static housekeeping var
set_by_cli.detector = None set_by_cli.detector = None # type: ignore
def has_default_value(option, value): def has_default_value(option, value):
+1 -1
View File
@@ -4,7 +4,7 @@ import glob
try: try:
import readline import readline
except ImportError: except ImportError:
import certbot.display.dummy_readline as readline import certbot.display.dummy_readline as readline # type: ignore
class Completer(object): class Completer(object):
+6 -2
View File
@@ -13,12 +13,14 @@ from certbot.plugins import util as plug_util
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def validate_hooks(config): def validate_hooks(config):
"""Check hook commands are executable.""" """Check hook commands are executable."""
validate_hook(config.pre_hook, "pre") validate_hook(config.pre_hook, "pre")
validate_hook(config.post_hook, "post") validate_hook(config.post_hook, "post")
validate_hook(config.renew_hook, "renew") validate_hook(config.renew_hook, "renew")
def _prog(shell_cmd): def _prog(shell_cmd):
"""Extract the program run by a shell command. """Extract the program run by a shell command.
@@ -52,6 +54,7 @@ def validate_hook(shell_cmd, hook_name):
raise errors.HookCommandNotFound(msg) raise errors.HookCommandNotFound(msg)
def pre_hook(config): def pre_hook(config):
"Run pre-hook if it's defined and hasn't been run." "Run pre-hook if it's defined and hasn't been run."
cmd = config.pre_hook cmd = config.pre_hook
@@ -62,7 +65,7 @@ def pre_hook(config):
elif cmd: elif cmd:
logger.info("Pre-hook command already run, skipping: %s", cmd) logger.info("Pre-hook command already run, skipping: %s", cmd)
pre_hook.already = set() pre_hook.already = set() # type: ignore
def post_hook(config): def post_hook(config):
@@ -82,7 +85,8 @@ def post_hook(config):
logger.info("Running post-hook command: %s", cmd) logger.info("Running post-hook command: %s", cmd)
_run_hook(cmd) _run_hook(cmd)
post_hook.eventually = [] post_hook.eventually = [] # type: ignore
def run_saved_post_hooks(): def run_saved_post_hooks():
"""Run any post hooks that were saved up in the course of the 'renew' verb""" """Run any post hooks that were saved up in the course of the 'renew' verb"""
+8 -8
View File
@@ -99,7 +99,7 @@ class IPluginFactory(zope.interface.Interface):
class IPlugin(zope.interface.Interface): class IPlugin(zope.interface.Interface):
"""Certbot plugin.""" """Certbot plugin."""
def prepare(): def prepare(): # type: ignore
"""Prepare the plugin. """Prepare the plugin.
Finish up any additional initialization. Finish up any additional initialization.
@@ -118,7 +118,7 @@ class IPlugin(zope.interface.Interface):
""" """
def more_info(): def more_info(): # type: ignore
"""Human-readable string to help the user. """Human-readable string to help the user.
Should describe the steps taken and any relevant info to help the user Should describe the steps taken and any relevant info to help the user
@@ -251,7 +251,7 @@ class IInstaller(IPlugin):
""" """
def get_all_names(): def get_all_names(): # type: ignore
"""Returns all names that may be authenticated. """Returns all names that may be authenticated.
:rtype: `collections.Iterable` of `str` :rtype: `collections.Iterable` of `str`
@@ -288,7 +288,7 @@ class IInstaller(IPlugin):
""" """
def supported_enhancements(): def supported_enhancements(): # type: ignore
"""Returns a `collections.Iterable` of supported enhancements. """Returns a `collections.Iterable` of supported enhancements.
:returns: supported enhancements which should be a subset of :returns: supported enhancements which should be a subset of
@@ -326,7 +326,7 @@ class IInstaller(IPlugin):
""" """
def recovery_routine(): def recovery_routine(): # type: ignore
"""Revert configuration to most recent finalized checkpoint. """Revert configuration to most recent finalized checkpoint.
Remove all changes (temporary and permanent) that have not been Remove all changes (temporary and permanent) that have not been
@@ -337,21 +337,21 @@ class IInstaller(IPlugin):
""" """
def view_config_changes(): def view_config_changes(): # type: ignore
"""Display all of the LE config changes. """Display all of the LE config changes.
:raises .PluginError: when config changes cannot be parsed :raises .PluginError: when config changes cannot be parsed
""" """
def config_test(): def config_test(): # type: ignore
"""Make sure the configuration is valid. """Make sure the configuration is valid.
:raises .MisconfigurationError: when the config is not in a usable state :raises .MisconfigurationError: when the config is not in a usable state
""" """
def restart(): def restart(): # type: ignore
"""Restart or refresh the server content. """Restart or refresh the server content.
:raises .PluginError: when server cannot be restarted :raises .PluginError: when server cannot be restarted
+1 -1
View File
@@ -27,7 +27,7 @@ class PluginEntryPoint(object):
"""Distributions for which prefix will be omitted.""" """Distributions for which prefix will be omitted."""
# this object is mutable, don't allow it to be hashed! # this object is mutable, don't allow it to be hashed!
__hash__ = None __hash__ = None # type: ignore
def __init__(self, entry_point): def __init__(self, entry_point):
self.name = self.entry_point_to_plugin_name(entry_point) self.name = self.entry_point_to_plugin_name(entry_point)
+1 -1
View File
@@ -7,7 +7,7 @@ import os
import sys import sys
import textwrap import textwrap
from six.moves import queue # pylint: disable=import-error from six.moves import queue # type: ignore # pylint: disable=import-error
import zope.interface import zope.interface
from certbot import interfaces from certbot import interfaces
+1 -1
View File
@@ -193,7 +193,7 @@ try:
file_type = file file_type = file
except NameError: except NameError:
import io import io
file_type = io.TextIOWrapper file_type = io.TextIOWrapper # type: ignore
class UniqueLineageNameTest(unittest.TestCase): class UniqueLineageNameTest(unittest.TestCase):
+7
View File
@@ -61,6 +61,13 @@ commands =
pip install -q -e acme[dev] -e .[dev] -e certbot-apache -e certbot-nginx -e certbot-compatibility-test -e letshelp-certbot pip install -q -e acme[dev] -e .[dev] -e certbot-apache -e certbot-nginx -e certbot-compatibility-test -e letshelp-certbot
pylint --reports=n --rcfile=.pylintrc acme/acme certbot certbot-apache/certbot_apache certbot-nginx/certbot_nginx certbot-compatibility-test/certbot_compatibility_test letshelp-certbot/letshelp_certbot pylint --reports=n --rcfile=.pylintrc acme/acme certbot certbot-apache/certbot_apache certbot-nginx/certbot_nginx certbot-compatibility-test/certbot_compatibility_test letshelp-certbot/letshelp_certbot
[testenv:mypy]
basepython = python3.4
commands =
pip install mypy
pip install -q -e acme[dev] -e .[dev] -e certbot-apache -e certbot-nginx -e certbot-compatibility-test -e letshelp-certbot
mypy --py2 --ignore-missing-imports acme/acme certbot certbot-apache/certbot_apache certbot-nginx/certbot_nginx certbot-compatibility-test/certbot_compatibility_test letshelp-certbot/letshelp_certbot
[testenv:apacheconftest] [testenv:apacheconftest]
#basepython = python2.7 #basepython = python2.7
commands = commands =