diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5fdf6e375..eec38c36d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: hooks: - id: doc8 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.0 + rev: v0.15.1 hooks: - id: ruff-check args: ['--fix', '--unsafe-fixes'] @@ -31,21 +31,3 @@ repos: additional_dependencies: - flake8-import-order~=0.19.2 exclude: '^(doc|releasenotes|tools)/.*$' - - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.19.1 - hooks: - - id: mypy - additional_dependencies: - - dogpile.cache - - keystoneauth1>=5.11.0 - - types-decorator - - types-PyYAML - - types-requests - - types-simplejson - # keep this in-sync with '[mypy] exclude' in 'setup.cfg' - exclude: | - (?x)( - doc/.* - | examples/.* - | releasenotes/.* - ) diff --git a/openstack/config/cloud_region.py b/openstack/config/cloud_region.py index 2aa26c921..d15764838 100644 --- a/openstack/config/cloud_region.py +++ b/openstack/config/cloud_region.py @@ -22,7 +22,7 @@ import warnings try: import keyring except ImportError: - keyring = None + keyring = None # type: ignore[assignment] from keystoneauth1.access import service_catalog as ks_service_catalog from keystoneauth1 import discover @@ -41,9 +41,11 @@ except ImportError: try: import prometheus_client except ImportError: - prometheus_client = None + prometheus_client = None # type: ignore[assignment] try: - import influxdb as influxdb_client + # NOTE(stephenfin): This library is EOL so we explicitly don't have it in + # our dependencies + import influxdb as influxdb_client # type: ignore[import-not-found] except ImportError: influxdb_client = None @@ -789,6 +791,9 @@ class CloudRegion: try: state = keyring.get_password('openstacksdk', cache_id) except RuntimeError: # the fail backend raises this + state = None + + if not state: self.log.debug('Failed to fetch auth from keyring') return @@ -802,10 +807,12 @@ class CloudRegion: assert self._auth is not None # narrow type cache_id = self._auth.get_cache_id() - state = self._auth.get_auth_state() + # NOTE(stephenfin): The actual return type of this is a serialized JSON + # object + state = ty.cast(str, self._auth.get_auth_state()) try: - if state: + if cache_id and state: # NOTE: under some conditions the method may be invoked when # auth is empty. This may lead to exception in the keyring lib, # thus do nothing. @@ -1393,7 +1400,7 @@ class CloudRegion: ], registry=registry, ) - registry._openstacksdk_histogram = hist + setattr(registry, '_openstacksdk_histogram', hist) return hist def get_prometheus_counter( @@ -1415,7 +1422,7 @@ class CloudRegion: ], registry=registry, ) - registry._openstacksdk_counter = counter + setattr(registry, '_openstacksdk_counter', counter) return counter def has_service(self, service_type: str) -> bool: diff --git a/openstack/exceptions.py b/openstack/exceptions.py index 2fb600ebf..02617bb28 100644 --- a/openstack/exceptions.py +++ b/openstack/exceptions.py @@ -102,7 +102,7 @@ class HttpException(SDKException, _rex.HTTPError): # Call directly rather than via super to control parameters SDKException.__init__(self, message=message) - _rex.HTTPError.__init__(self, message, response=response) + _rex.HTTPError.__init__(self, message, response=response) # type: ignore if response is not None: self.request_id = response.headers.get('x-openstack-request-id') diff --git a/openstack/proxy.py b/openstack/proxy.py index b75708d98..63227316f 100644 --- a/openstack/proxy.py +++ b/openstack/proxy.py @@ -41,7 +41,7 @@ from openstack import utils from openstack import warnings as os_warnings if ty.TYPE_CHECKING: - import influxdb as influxdb_client + import influxdb as influxdb_client # type: ignore[import-not-found] from keystoneauth1 import plugin import prometheus_client import requests diff --git a/pyproject.toml b/pyproject.toml index eebf048a6..576dfe120 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,6 @@ packages = [ python_version = "3.10" show_column_numbers = true show_error_context = true -ignore_missing_imports = true follow_imports = "normal" check_untyped_defs = true warn_unused_ignores = true @@ -58,16 +57,10 @@ disallow_subclassing_any = false disallow_untyped_calls = false disallow_incomplete_defs = true disallow_untyped_defs = false -no_implicit_reexport = false +no_implicit_reexport = true extra_checks = true -# keep this in-sync with 'mypy.exclude' in '.pre-commit-config.yaml' -exclude = ''' -(?x)( - doc - | examples - | releasenotes - ) -''' +disable_error_code = ["import-untyped"] +exclude = '(?x)(doc | examples | releasenotes)' [[tool.mypy.overrides]] module = [ diff --git a/test-requirements.txt b/test-requirements.txt index ad4d20706..846753c01 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -11,3 +11,4 @@ statsd>=3.3.0 stestr>=1.0.0 # Apache-2.0 testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.2.0 # MIT +keyring>=24.0.0 # MIT diff --git a/tox.ini b/tox.ini index 8d91a4779..883fc19d4 100644 --- a/tox.ini +++ b/tox.ini @@ -60,11 +60,26 @@ commands = [testenv:pep8] description = Run style checks. -skip_install = true deps = pre-commit + {[testenv:mypy]deps} commands = - pre-commit run --all-files --show-diff-on-failure + pre-commit run -a + {[testenv:mypy]commands} + +[testenv:mypy] +description = + Run type checks. +deps = + {[testenv]deps} + mypy + types-decorator + types-jmespath + types-PyYAML + types-requests + types-simplejson +commands = + mypy --cache-dir="{envdir}/mypy_cache" {posargs:openstack} [testenv:venv] description =