Enable strict typing

Change-Id: Iff363e0dfdf5741ebd5147402f73a230d30ea9b6
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane
2023-09-12 10:02:45 +01:00
parent 99b81ac428
commit 18e9ca0167
5 changed files with 37 additions and 26 deletions

View File

@@ -34,12 +34,12 @@ repos:
files: '^.*\.py$'
exclude: '^(doc|releasenotes|tools)/.*$'
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.12.1
rev: v1.15.0
hooks:
- id: mypy
exclude: |
(?x)(
oslo_context/tests/.*
oslo_context/fixture.py
| doc/.*
| releasenotes/.*
)

View File

@@ -33,6 +33,13 @@ import typing as ty
import uuid
import warnings
import typing_extensions as ty_ext
if ty.TYPE_CHECKING:
_MutableMapping = collections.abc.MutableMapping[str, ty.Any]
else:
_MutableMapping = collections.abc.MutableMapping
_request_store = threading.local()
# These arguments will be passed to a new context from the first available
@@ -69,7 +76,7 @@ def generate_request_id() -> str:
return 'req-%s' % uuid.uuid4()
class _DeprecatedPolicyValues(collections.abc.MutableMapping):
class _DeprecatedPolicyValues(_MutableMapping):
"""A Dictionary that manages current and deprecated policy values.
Anything added to this dictionary after initial creation is considered a
@@ -324,7 +331,7 @@ class RequestContext:
"""
return self.global_request_id or self.request_id
def redacted_copy(self, **kwargs: ty.Any) -> 'RequestContext':
def redacted_copy(self, **kwargs: ty.Any) -> ty_ext.Self:
"""Return a copy of the context with sensitive fields redacted.
This is useful for creating a context that can be safely logged.
@@ -361,7 +368,7 @@ class RequestContext:
@classmethod
def from_dict(
cls, values: ty.Dict[str, ty.Any], **kwargs: ty.Any,
) -> 'RequestContext':
) -> ty_ext.Self:
"""Construct a context object from a provided dictionary."""
kwargs.setdefault('auth_token', values.get('auth_token'))
kwargs.setdefault('user_id', values.get('user'))
@@ -392,7 +399,7 @@ class RequestContext:
@classmethod
def from_environ(
cls, environ: ty.Dict[str, ty.Any], **kwargs: ty.Any,
) -> 'RequestContext':
) -> ty_ext.Self:
"""Load a context object from a request environment.
If keyword arguments are provided then they override the values in the
@@ -446,7 +453,7 @@ def get_admin_context(show_deleted: bool = False) -> RequestContext:
def get_context_from_function_and_args(
function: ty.Callable,
function: ty.Callable[..., ty.Any],
args: ty.List[ty.Any],
kwargs: ty.Dict[str, ty.Any],
) -> ty.Optional[RequestContext]:
@@ -462,7 +469,7 @@ def get_context_from_function_and_args(
return None
def is_user_context(context: RequestContext) -> bool:
def is_user_context(context: ty.Any) -> bool:
"""Indicates if the request context is a normal user."""
if not context or not isinstance(context, RequestContext):
return False

View File

@@ -374,34 +374,35 @@ class ContextTest(test_base.BaseTestCase):
self.assertEqual(['jkl', 'mno', 'pqr'], ctx.service_roles)
def test_environ_admin_project(self):
environ = {}
ctx = context.RequestContext.from_environ(environ=environ)
ctx = context.RequestContext.from_environ(environ={})
self.assertIs(True, ctx.is_admin_project)
self.assertIs(True, ctx.to_policy_values()['is_admin_project'])
environ = {'HTTP_X_IS_ADMIN_PROJECT': 'True'}
ctx = context.RequestContext.from_environ(environ=environ)
ctx = context.RequestContext.from_environ(
environ={'HTTP_X_IS_ADMIN_PROJECT': 'True'}
)
self.assertIs(True, ctx.is_admin_project)
self.assertIs(True, ctx.to_policy_values()['is_admin_project'])
environ = {'HTTP_X_IS_ADMIN_PROJECT': 'False'}
ctx = context.RequestContext.from_environ(environ=environ)
ctx = context.RequestContext.from_environ(
environ={'HTTP_X_IS_ADMIN_PROJECT': 'False'}
)
self.assertIs(False, ctx.is_admin_project)
self.assertIs(False, ctx.to_policy_values()['is_admin_project'])
def test_from_function_and_args(self):
ctx = context.RequestContext(user_id="user1")
arg = []
kw = dict(c=ctx, s="s")
fn = context.get_context_from_function_and_args
ctx1 = context.get_context_from_function_and_args(fn, arg, kw)
ctx1 = context.get_context_from_function_and_args(
context.get_context_from_function_and_args,
[],
{'c': ctx, 's': 's'},
)
self.assertIs(ctx1, ctx)
def test_not_in_from_function_and_args(self):
arg = []
kw = dict()
fn = context.get_context_from_function_and_args
ctx1 = context.get_context_from_function_and_args(fn, arg, kw)
ctx1 = context.get_context_from_function_and_args(
context.get_context_from_function_and_args, [], {}
)
self.assertIsNone(ctx1)
def test_values(self):

View File

@@ -3,3 +3,4 @@
# you find any incorrect lower bounds, let us know or propose a fix.
pbr>=2.0.0 # Apache-2.0
typing-extensions>=4.12.0 # PSF

View File

@@ -30,10 +30,12 @@ packages =
show_column_numbers = true
show_error_context = true
ignore_missing_imports = true
check_untyped_defs = true
warn_unused_ignores = true
warn_return_any = true
disallow_untyped_defs = true
strict = true
[mypy-oslo_context.tests.*]
ignore_errors = true
strict = false
[mypy-oslo_context.fixture]
ignore_errors = true
strict = false