Enable strict typing
Change-Id: Iff363e0dfdf5741ebd5147402f73a230d30ea9b6 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
@@ -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/.*
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
10
setup.cfg
10
setup.cfg
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user