From 82d14db44df50c8dc7952f478dc1a98b67fe6060 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 29 Oct 2024 09:14:43 +0100 Subject: [PATCH] tox: Add support for type checking This gives a lot of type warnings/errors. Ignore the failure that we can fix it step by step. You can run it with: $ tox run -e type Found 104 errors in 14 files (checked 40 source files) --- pyproject.toml | 9 +++++ stubs/README.md | 5 +++ stubs/cepces/krb5/functions.pyi | 59 ++++++++++++++++++++++++++++ stubs/requests_gssapi/__init__.pyi | 19 +++++++++ stubs/requests_gssapi/compat.pyi | 26 ++++++++++++ stubs/requests_gssapi/exceptions.pyi | 6 +++ stubs/requests_gssapi/gssapi_.pyi | 54 +++++++++++++++++++++++++ tox.ini | 17 ++++---- 8 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 stubs/README.md create mode 100644 stubs/cepces/krb5/functions.pyi create mode 100644 stubs/requests_gssapi/__init__.pyi create mode 100644 stubs/requests_gssapi/compat.pyi create mode 100644 stubs/requests_gssapi/exceptions.pyi create mode 100644 stubs/requests_gssapi/gssapi_.pyi diff --git a/pyproject.toml b/pyproject.toml index 30ab4b9..b8e419b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,3 +39,12 @@ readme = "README.rst" [tool.black] target-version = ['py39'] + +[tool.ruff.per-file-ignores] +# don't resort auto-generated stub files +"stubs/*" = ["I"] + +[tool.mypy] +mypy_path = "src/:stubs/:tests/" +explicit_package_bases = true +check_untyped_defs = true diff --git a/stubs/README.md b/stubs/README.md new file mode 100644 index 0000000..afcb040 --- /dev/null +++ b/stubs/README.md @@ -0,0 +1,5 @@ +# Type stubs + +This directory contains type stubs for 3rd party packages. + +The stubs for have been generated with mypy's [stubgen](https://mypy.readthedocs.io/en/stable/stubgen.html). diff --git a/stubs/cepces/krb5/functions.pyi b/stubs/cepces/krb5/functions.pyi new file mode 100644 index 0000000..cfebbf4 --- /dev/null +++ b/stubs/cepces/krb5/functions.pyi @@ -0,0 +1,59 @@ +from _typeshed import Incomplete + +class Error(RuntimeError): + def __init__(self, context, code) -> None: ... + @property + def code(self): ... + +def error_decorator(func): ... + +krb5_cc_close: Incomplete +cc_close: Incomplete +krb5_cc_initialize: Incomplete +cc_initialize: Incomplete +krb5_cc_resolve: Incomplete +cc_resolve: Incomplete +krb5_cc_store_cred: Incomplete +cc_store_cred: Incomplete +krb5_free_context: Incomplete +free_context: Incomplete +krb5_free_cred_contents: Incomplete +free_cred_contents: Incomplete +krb5_free_error_message: Incomplete +free_error_message: Incomplete +krb5_free_principal: Incomplete +free_principal: Incomplete +krb5_free_unparsed_name: Incomplete +free_unparsed_name: Incomplete +krb5_get_error_message: Incomplete +get_error_message: Incomplete +krb5_get_init_creds_keytab: Incomplete +get_init_creds_keytab: Incomplete +krb5_get_init_creds_opt_alloc: Incomplete +get_init_creds_opt_alloc: Incomplete +krb5_get_init_creds_opt_free: Incomplete +get_init_creds_opt_free: Incomplete +krb5_get_init_creds_opt_set_etype_list: Incomplete +get_init_creds_opt_set_etype_list: Incomplete +krb5_get_init_creds_opt_set_forwardable: Incomplete +get_init_creds_opt_set_forwardable: Incomplete +krb5_init_context: Incomplete +init_context: Incomplete +krb5_kt_close: Incomplete +kt_close: Incomplete +krb5_kt_default: Incomplete +kt_default: Incomplete +krb5_kt_default_name: Incomplete +kt_default_name: Incomplete +krb5_kt_get_name: Incomplete +kt_get_name: Incomplete +krb5_kt_get_type: Incomplete +kt_get_type: Incomplete +krb5_kt_resolve: Incomplete +kt_resolve: Incomplete +krb5_parse_name: Incomplete +parse_name: Incomplete +krb5_sname_to_principal: Incomplete +sname_to_principal: Incomplete +krb5_unparse_name: Incomplete +unparse_name: Incomplete diff --git a/stubs/requests_gssapi/__init__.pyi b/stubs/requests_gssapi/__init__.pyi new file mode 100644 index 0000000..07ad34b --- /dev/null +++ b/stubs/requests_gssapi/__init__.pyi @@ -0,0 +1,19 @@ +from .compat import HTTPKerberosAuth as HTTPKerberosAuth +from .exceptions import MutualAuthenticationError as MutualAuthenticationError +from .gssapi_ import ( + DISABLED as DISABLED, + HTTPSPNEGOAuth as HTTPSPNEGOAuth, + OPTIONAL as OPTIONAL, + REQUIRED as REQUIRED, + SPNEGO as SPNEGO, +) + +__all__ = [ + "HTTPSPNEGOAuth", + "HTTPKerberosAuth", + "MutualAuthenticationError", + "SPNEGO", + "REQUIRED", + "OPTIONAL", + "DISABLED", +] diff --git a/stubs/requests_gssapi/compat.pyi b/stubs/requests_gssapi/compat.pyi new file mode 100644 index 0000000..70c4dd6 --- /dev/null +++ b/stubs/requests_gssapi/compat.pyi @@ -0,0 +1,26 @@ +from .gssapi_ import ( + DISABLED as DISABLED, + HTTPSPNEGOAuth as HTTPSPNEGOAuth, + SPNEGOExchangeError as SPNEGOExchangeError, + log as log, +) +from _typeshed import Incomplete +from logging import NullHandler as NullHandler + +class HTTPKerberosAuth(HTTPSPNEGOAuth): + principal: Incomplete + service: Incomplete + hostname_override: Incomplete + def __init__( + self, + mutual_authentication=..., + service: str = "HTTP", + delegate: bool = False, + force_preemptive: bool = False, + principal: Incomplete | None = None, + hostname_override: Incomplete | None = None, + sanitize_mutual_error_response: bool = True, + ) -> None: ... + creds: Incomplete + target_name: Incomplete + def generate_request_header(self, response, host, is_preemptive: bool = False): ... diff --git a/stubs/requests_gssapi/exceptions.pyi b/stubs/requests_gssapi/exceptions.pyi new file mode 100644 index 0000000..27b3f72 --- /dev/null +++ b/stubs/requests_gssapi/exceptions.pyi @@ -0,0 +1,6 @@ +from requests.exceptions import RequestException + +class MutualAuthenticationError(RequestException): ... +class SPNEGOExchangeError(RequestException): ... + +KerberosExchangeError = SPNEGOExchangeError diff --git a/stubs/requests_gssapi/gssapi_.pyi b/stubs/requests_gssapi/gssapi_.pyi new file mode 100644 index 0000000..2a94254 --- /dev/null +++ b/stubs/requests_gssapi/gssapi_.pyi @@ -0,0 +1,54 @@ +from .exceptions import ( + MutualAuthenticationError as MutualAuthenticationError, + SPNEGOExchangeError as SPNEGOExchangeError, +) +from _typeshed import Incomplete +from requests.auth import AuthBase +from requests.models import Response + +log: Incomplete +REQUIRED: int +OPTIONAL: int +DISABLED: int +SPNEGO: Incomplete + +class SanitizedResponse(Response): + status_code: Incomplete + encoding: Incomplete + raw: Incomplete + reason: Incomplete + url: Incomplete + request: Incomplete + connection: Incomplete + cookies: Incomplete + headers: Incomplete + def __init__(self, response) -> None: ... + +class HTTPSPNEGOAuth(AuthBase): + context: Incomplete + pos: Incomplete + mutual_authentication: Incomplete + target_name: Incomplete + delegate: Incomplete + opportunistic_auth: Incomplete + creds: Incomplete + mech: Incomplete + sanitize_mutual_error_response: Incomplete + def __init__( + self, + mutual_authentication=..., + target_name: str = "HTTP", + delegate: bool = False, + opportunistic_auth: bool = False, + creds: Incomplete | None = None, + mech=..., + sanitize_mutual_error_response: bool = True, + ) -> None: ... + def generate_request_header(self, response, host, is_preemptive: bool = False): ... + def authenticate_user(self, response, **kwargs): ... + def handle_401(self, response, **kwargs): ... + def handle_other(self, response): ... + def authenticate_server(self, response): ... + def handle_response(self, response, **kwargs): ... + def deregister(self, response) -> None: ... + def __call__(self, request): ... diff --git a/tox.ini b/tox.ini index 8e5bcce..94fa8ba 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] requires = tox>=4 -env_list = lint, format, 3.9, 3.10, 3.11, 3.12, 3.13 +env_list = lint, format, type, 3.9, 3.10, 3.11, 3.12, 3.13 [gh-actions] python = @@ -33,9 +33,12 @@ deps = black commands = {envpython} -m black --check --diff {posargs:{tox_root}} -; [testenv:type] -; description = run type checks -; deps = -; mypy -; commands = -; mypy {posargs:src tests} +[testenv:type] +description = run type checks +changedir = {tox_root} +ignore_outcome = true +deps = + mypy >= 1.2.0 + types-requests +commands = + {envpython} -m mypy {posargs:src tests}