pre-commit: Add ruff
This handles formatting and allows us to replace both the pyupgrade and bandit hooks. We also bump the versions of the other hooks and migrate to the native hacking extension. Change-Id: I1aca8ef6c782252293a0b71aba8afe5409366d70 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
@@ -18,20 +18,17 @@ repos:
|
||||
- id: debug-statements
|
||||
- id: check-yaml
|
||||
files: .*\.(yaml|yml)$
|
||||
- repo: https://github.com/PyCQA/bandit
|
||||
rev: 1.7.10
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.11.3
|
||||
hooks:
|
||||
- id: bandit
|
||||
args: ['-x', 'tests']
|
||||
- repo: local
|
||||
- id: ruff
|
||||
args: ['--fix', '--unsafe-fixes']
|
||||
- id: ruff-format
|
||||
- repo: https://opendev.org/openstack/hacking
|
||||
rev: 7.0.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
name: flake8
|
||||
additional_dependencies:
|
||||
- hacking>=6.1.0,<6.2.0
|
||||
language: python
|
||||
entry: flake8
|
||||
files: '^.*\.py$'
|
||||
- id: hacking
|
||||
additional_dependencies: []
|
||||
exclude: '^(doc|releasenotes)/.*$'
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.15.0
|
||||
@@ -43,8 +40,3 @@ repos:
|
||||
| doc/.*
|
||||
| releasenotes/.*
|
||||
)
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.18.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py3-only]
|
||||
|
||||
@@ -59,16 +59,19 @@ pygments_style = 'native'
|
||||
html_theme = 'openstackdocs'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
htmlhelp_basename = f'{project}doc'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index',
|
||||
'%s.tex' % project,
|
||||
'%s Documentation' % project,
|
||||
'OpenStack Foundation', 'manual'),
|
||||
(
|
||||
'index',
|
||||
f'{project}.tex',
|
||||
f'{project} Documentation',
|
||||
'OpenStack Foundation',
|
||||
'manual',
|
||||
),
|
||||
]
|
||||
|
||||
# openstackdocstheme options
|
||||
|
||||
@@ -40,12 +40,12 @@ LOG = logging.getLogger(__name__)
|
||||
LOG.info("Message without context")
|
||||
# ids in Openstack are 32 characters long
|
||||
# For readability a shorter id value is used
|
||||
context.RequestContext(user_id='6ce90b4d',
|
||||
project_id='d6134462',
|
||||
project_domain_id='a6b9360e')
|
||||
context.RequestContext(
|
||||
user_id='6ce90b4d', project_id='d6134462', project_domain_id='a6b9360e'
|
||||
)
|
||||
LOG.info("Message with context")
|
||||
|
||||
context = context.RequestContext(user_id='ace90b4d',
|
||||
project_id='b6134462',
|
||||
project_domain_id='c6b9360e')
|
||||
context = context.RequestContext(
|
||||
user_id='ace90b4d', project_id='b6134462', project_domain_id='c6b9360e'
|
||||
)
|
||||
LOG.info("Message with passed context", context=context)
|
||||
|
||||
@@ -33,7 +33,9 @@ CONF = cfg.CONF
|
||||
DOMAIN = "demo"
|
||||
|
||||
logging.register_options(CONF)
|
||||
CONF.logging_user_identity_format = "%(user_id)s/%(project_id)s@%(project_domain)s"
|
||||
CONF.logging_user_identity_format = (
|
||||
"%(user_id)s/%(project_id)s@%(project_domain)s"
|
||||
)
|
||||
logging.setup(CONF, DOMAIN)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@@ -41,8 +43,10 @@ LOG = logging.getLogger(__name__)
|
||||
LOG.info("Message without context")
|
||||
# ids in Openstack are 32 characters long
|
||||
# For readability a shorter id value is used
|
||||
context.RequestContext(request_id='req-abc',
|
||||
user_id='6ce90b4d',
|
||||
project_id='d6134462',
|
||||
project_domain_id='a6b9360e')
|
||||
context.RequestContext(
|
||||
request_id='req-abc',
|
||||
user_id='6ce90b4d',
|
||||
project_id='d6134462',
|
||||
project_domain_id='a6b9360e',
|
||||
)
|
||||
LOG.info("Message with context")
|
||||
|
||||
@@ -44,7 +44,7 @@ _request_store = threading.local()
|
||||
|
||||
# These arguments will be passed to a new context from the first available
|
||||
# header to support backwards compatibility.
|
||||
_ENVIRON_HEADERS: ty.Dict[str, ty.List[str]] = {
|
||||
_ENVIRON_HEADERS: dict[str, list[str]] = {
|
||||
'auth_token': ['HTTP_X_AUTH_TOKEN', 'HTTP_X_STORAGE_TOKEN'],
|
||||
'user_id': ['HTTP_X_USER_ID', 'HTTP_X_USER'],
|
||||
'project_id': ['HTTP_X_PROJECT_ID', 'HTTP_X_TENANT_ID', 'HTTP_X_TENANT'],
|
||||
@@ -58,7 +58,6 @@ _ENVIRON_HEADERS: ty.Dict[str, ty.List[str]] = {
|
||||
'project_domain_name': ['HTTP_X_PROJECT_DOMAIN_NAME'],
|
||||
'request_id': ['openstack.request_id'],
|
||||
'global_request_id': ['openstack.global_request_id'],
|
||||
|
||||
'service_token': ['HTTP_X_SERVICE_TOKEN'],
|
||||
'service_user_id': ['HTTP_X_SERVICE_USER_ID'],
|
||||
'service_user_name': ['HTTP_X_SERVICE_USER_NAME'],
|
||||
@@ -73,7 +72,7 @@ _ENVIRON_HEADERS: ty.Dict[str, ty.List[str]] = {
|
||||
|
||||
def generate_request_id() -> str:
|
||||
"""Generate a unique request id."""
|
||||
return 'req-%s' % uuid.uuid4()
|
||||
return f'req-{uuid.uuid4()}'
|
||||
|
||||
|
||||
class _DeprecatedPolicyValues(_MutableMapping):
|
||||
@@ -84,9 +83,9 @@ class _DeprecatedPolicyValues(_MutableMapping):
|
||||
these values as oslo.policy will do will trigger a DeprecationWarning.
|
||||
"""
|
||||
|
||||
def __init__(self, data: ty.Dict[str, ty.Any]):
|
||||
def __init__(self, data: dict[str, ty.Any]):
|
||||
self._data = data
|
||||
self._deprecated: ty.Dict[str, ty.Any] = {}
|
||||
self._deprecated: dict[str, ty.Any] = {}
|
||||
|
||||
def __getitem__(self, k: str) -> ty.Any:
|
||||
try:
|
||||
@@ -99,10 +98,12 @@ class _DeprecatedPolicyValues(_MutableMapping):
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
warnings.warn('Policy enforcement is depending on the value of '
|
||||
'%s. This key is deprecated. Please update your '
|
||||
'policy file to use the standard policy values.' % k,
|
||||
DeprecationWarning)
|
||||
warnings.warn(
|
||||
'Policy enforcement is depending on the value of '
|
||||
f'{k}. This key is deprecated. Please update your '
|
||||
'policy file to use the standard policy values.',
|
||||
DeprecationWarning,
|
||||
)
|
||||
return val
|
||||
|
||||
raise KeyError(k)
|
||||
@@ -126,14 +127,13 @@ class _DeprecatedPolicyValues(_MutableMapping):
|
||||
return self._dict.__repr__()
|
||||
|
||||
@property
|
||||
def _dict(self) -> ty.Dict[str, ty.Any]:
|
||||
def _dict(self) -> dict[str, ty.Any]:
|
||||
d = self._deprecated.copy()
|
||||
d.update(self._data)
|
||||
return d
|
||||
|
||||
|
||||
class RequestContext:
|
||||
|
||||
"""Helper class to represent useful information about a request context.
|
||||
|
||||
Stores information about the security context under which the user
|
||||
@@ -143,7 +143,7 @@ class RequestContext:
|
||||
user_idt_format = '{user} {project_id} {domain} {user_domain} {p_domain}'
|
||||
# Can be overridden in subclasses to specify extra keys that should be
|
||||
# read when constructing a context using from_dict.
|
||||
FROM_DICT_EXTRA_KEYS: ty.List[str] = []
|
||||
FROM_DICT_EXTRA_KEYS: list[str] = []
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -159,7 +159,7 @@ class RequestContext:
|
||||
request_id: ty.Optional[str] = None,
|
||||
resource_uuid: ty.Optional[str] = None,
|
||||
overwrite: bool = True,
|
||||
roles: ty.Optional[ty.List[str]] = None,
|
||||
roles: ty.Optional[list[str]] = None,
|
||||
user_name: ty.Optional[str] = None,
|
||||
project_name: ty.Optional[str] = None,
|
||||
domain_name: ty.Optional[str] = None,
|
||||
@@ -175,7 +175,7 @@ class RequestContext:
|
||||
service_project_name: ty.Optional[str] = None,
|
||||
service_project_domain_id: ty.Optional[str] = None,
|
||||
service_project_domain_name: ty.Optional[str] = None,
|
||||
service_roles: ty.Optional[ty.List[str]] = None,
|
||||
service_roles: ty.Optional[list[str]] = None,
|
||||
global_request_id: ty.Optional[str] = None,
|
||||
system_scope: ty.Optional[str] = None,
|
||||
):
|
||||
@@ -254,23 +254,25 @@ class RequestContext:
|
||||
# deprecated policy values that trigger a warning when used in favour
|
||||
# of our standard ones. This object acts like a dict but only values
|
||||
# from oslo.policy don't show a warning.
|
||||
return _DeprecatedPolicyValues({
|
||||
'user_id': self.user_id,
|
||||
'user_domain_id': self.user_domain_id,
|
||||
'system_scope': self.system_scope,
|
||||
'domain_id': self.domain_id,
|
||||
'project_id': self.project_id,
|
||||
'project_domain_id': self.project_domain_id,
|
||||
'roles': self.roles,
|
||||
'is_admin_project': self.is_admin_project,
|
||||
'service_user_id': self.service_user_id,
|
||||
'service_user_domain_id': self.service_user_domain_id,
|
||||
'service_project_id': self.service_project_id,
|
||||
'service_project_domain_id': self.service_project_domain_id,
|
||||
'service_roles': self.service_roles,
|
||||
})
|
||||
return _DeprecatedPolicyValues(
|
||||
{
|
||||
'user_id': self.user_id,
|
||||
'user_domain_id': self.user_domain_id,
|
||||
'system_scope': self.system_scope,
|
||||
'domain_id': self.domain_id,
|
||||
'project_id': self.project_id,
|
||||
'project_domain_id': self.project_domain_id,
|
||||
'roles': self.roles,
|
||||
'is_admin_project': self.is_admin_project,
|
||||
'service_user_id': self.service_user_id,
|
||||
'service_user_domain_id': self.service_user_domain_id,
|
||||
'service_project_id': self.service_project_id,
|
||||
'service_project_domain_id': self.service_project_domain_id,
|
||||
'service_roles': self.service_roles,
|
||||
}
|
||||
)
|
||||
|
||||
def to_dict(self) -> ty.Dict[str, ty.Any]:
|
||||
def to_dict(self) -> dict[str, ty.Any]:
|
||||
"""Return a dictionary of context attributes."""
|
||||
user_idt = self.user_idt_format.format(
|
||||
user=self.user_id or '-',
|
||||
@@ -280,36 +282,40 @@ class RequestContext:
|
||||
p_domain=self.project_domain_id or '-',
|
||||
)
|
||||
|
||||
return {'user': self.user_id,
|
||||
'project_id': self.project_id,
|
||||
'system_scope': self.system_scope,
|
||||
'project': self.project_id,
|
||||
'domain': self.domain_id,
|
||||
'user_domain': self.user_domain_id,
|
||||
'project_domain': self.project_domain_id,
|
||||
'is_admin': self.is_admin,
|
||||
'read_only': self.read_only,
|
||||
'show_deleted': self.show_deleted,
|
||||
'auth_token': self.auth_token,
|
||||
'request_id': self.request_id,
|
||||
'global_request_id': self.global_request_id,
|
||||
'resource_uuid': self.resource_uuid,
|
||||
'roles': self.roles,
|
||||
'user_identity': user_idt,
|
||||
'is_admin_project': self.is_admin_project}
|
||||
return {
|
||||
'user': self.user_id,
|
||||
'project_id': self.project_id,
|
||||
'system_scope': self.system_scope,
|
||||
'project': self.project_id,
|
||||
'domain': self.domain_id,
|
||||
'user_domain': self.user_domain_id,
|
||||
'project_domain': self.project_domain_id,
|
||||
'is_admin': self.is_admin,
|
||||
'read_only': self.read_only,
|
||||
'show_deleted': self.show_deleted,
|
||||
'auth_token': self.auth_token,
|
||||
'request_id': self.request_id,
|
||||
'global_request_id': self.global_request_id,
|
||||
'resource_uuid': self.resource_uuid,
|
||||
'roles': self.roles,
|
||||
'user_identity': user_idt,
|
||||
'is_admin_project': self.is_admin_project,
|
||||
}
|
||||
|
||||
def get_logging_values(self) -> ty.Dict[str, ty.Any]:
|
||||
def get_logging_values(self) -> dict[str, ty.Any]:
|
||||
"""Return a dictionary of logging specific context attributes."""
|
||||
values = {'user_name': self.user_name,
|
||||
'project_name': self.project_name,
|
||||
'domain_name': self.domain_name,
|
||||
'user_domain_name': self.user_domain_name,
|
||||
'project_domain_name': self.project_domain_name}
|
||||
values = {
|
||||
'user_name': self.user_name,
|
||||
'project_name': self.project_name,
|
||||
'domain_name': self.domain_name,
|
||||
'user_domain_name': self.user_domain_name,
|
||||
'project_domain_name': self.project_domain_name,
|
||||
}
|
||||
values.update(self.to_dict())
|
||||
if self.auth_token:
|
||||
# NOTE(jaosorior): Gotta obfuscate the token since this dict is
|
||||
# meant for logging and we shouldn't leak it.
|
||||
values['auth_token'] = '***' # nosec
|
||||
values['auth_token'] = '***' # noqa: S105
|
||||
else:
|
||||
values['auth_token'] = None
|
||||
# NOTE(bnemec: auth_token_info isn't defined in oslo.context, but it's
|
||||
@@ -362,12 +368,12 @@ class RequestContext:
|
||||
global_request_id=self.global_request_id,
|
||||
system_scope=self.system_scope,
|
||||
is_admin=self.is_admin,
|
||||
**kwargs
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_dict(
|
||||
cls, values: ty.Dict[str, ty.Any], **kwargs: ty.Any,
|
||||
cls, values: dict[str, ty.Any], **kwargs: ty.Any
|
||||
) -> ty_ext.Self:
|
||||
"""Construct a context object from a provided dictionary."""
|
||||
kwargs.setdefault('auth_token', values.get('auth_token'))
|
||||
@@ -387,10 +393,12 @@ class RequestContext:
|
||||
kwargs.setdefault('project_name', values.get('project_name'))
|
||||
kwargs.setdefault('domain_name', values.get('domain_name'))
|
||||
kwargs.setdefault('user_domain_name', values.get('user_domain_name'))
|
||||
kwargs.setdefault('project_domain_name',
|
||||
values.get('project_domain_name'))
|
||||
kwargs.setdefault('is_admin_project',
|
||||
values.get('is_admin_project', True))
|
||||
kwargs.setdefault(
|
||||
'project_domain_name', values.get('project_domain_name')
|
||||
)
|
||||
kwargs.setdefault(
|
||||
'is_admin_project', values.get('is_admin_project', True)
|
||||
)
|
||||
kwargs.setdefault('system_scope', values.get('system_scope'))
|
||||
for key in cls.FROM_DICT_EXTRA_KEYS:
|
||||
kwargs.setdefault(key, values.get(key))
|
||||
@@ -398,7 +406,7 @@ class RequestContext:
|
||||
|
||||
@classmethod
|
||||
def from_environ(
|
||||
cls, environ: ty.Dict[str, ty.Any], **kwargs: ty.Any,
|
||||
cls, environ: dict[str, ty.Any], **kwargs: ty.Any
|
||||
) -> ty_ext.Self:
|
||||
"""Load a context object from a request environment.
|
||||
|
||||
@@ -444,18 +452,20 @@ class RequestContext:
|
||||
|
||||
def get_admin_context(show_deleted: bool = False) -> RequestContext:
|
||||
"""Create an administrator context."""
|
||||
context = RequestContext(None,
|
||||
project_id=None,
|
||||
is_admin=True,
|
||||
show_deleted=show_deleted,
|
||||
overwrite=False)
|
||||
context = RequestContext(
|
||||
None,
|
||||
project_id=None,
|
||||
is_admin=True,
|
||||
show_deleted=show_deleted,
|
||||
overwrite=False,
|
||||
)
|
||||
return context
|
||||
|
||||
|
||||
def get_context_from_function_and_args(
|
||||
function: ty.Callable[..., ty.Any],
|
||||
args: ty.List[ty.Any],
|
||||
kwargs: ty.Dict[str, ty.Any],
|
||||
args: list[ty.Any],
|
||||
kwargs: dict[str, ty.Any],
|
||||
) -> ty.Optional[RequestContext]:
|
||||
"""Find an arg of type RequestContext and return it.
|
||||
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import fixtures
|
||||
import hashlib
|
||||
import uuid
|
||||
import warnings
|
||||
|
||||
import fixtures
|
||||
from oslotest import base as test_base
|
||||
|
||||
from oslo_context import context
|
||||
@@ -29,7 +29,6 @@ def generate_id(name):
|
||||
|
||||
|
||||
class WarningsFixture(fixtures.Fixture):
|
||||
|
||||
def __init__(self, action="always", category=DeprecationWarning):
|
||||
super().__init__()
|
||||
self.action = action
|
||||
@@ -59,6 +58,7 @@ class TestContext(context.RequestContext):
|
||||
This is representative of how at least some of our consumers use the
|
||||
RequestContext class in their projects.
|
||||
"""
|
||||
|
||||
FROM_DICT_EXTRA_KEYS = ['auth_token_info']
|
||||
|
||||
def __init__(self, auth_token_info=None, **kwargs):
|
||||
@@ -72,7 +72,6 @@ class TestContext(context.RequestContext):
|
||||
|
||||
|
||||
class ContextTest(test_base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.warnings = self.useFixture(WarningsFixture())
|
||||
@@ -143,7 +142,7 @@ class ContextTest(test_base.BaseTestCase):
|
||||
"global_request_id": "req-uuid",
|
||||
"resource_uuid": "instance1",
|
||||
"extra_data": "foo",
|
||||
"system_scope": "all"
|
||||
"system_scope": "all",
|
||||
}
|
||||
ctx = context.RequestContext.from_dict(dct)
|
||||
self.assertEqual(dct['auth_token'], ctx.auth_token)
|
||||
@@ -172,7 +171,7 @@ class ContextTest(test_base.BaseTestCase):
|
||||
"read_only": True,
|
||||
"roles": "role1,role2,role3", # future review provides this
|
||||
"color": "red",
|
||||
"unknown": ""
|
||||
"unknown": "",
|
||||
}
|
||||
ctx = context.RequestContext.from_dict(dct)
|
||||
self.assertEqual("token1", ctx.auth_token)
|
||||
@@ -189,7 +188,7 @@ class ContextTest(test_base.BaseTestCase):
|
||||
"read_only": True,
|
||||
"roles": "role1,role2,role3",
|
||||
"color": "red",
|
||||
"unknown": ""
|
||||
"unknown": "",
|
||||
}
|
||||
ctx = context.RequestContext.from_dict(
|
||||
dct,
|
||||
@@ -289,14 +288,17 @@ class ContextTest(test_base.BaseTestCase):
|
||||
self.assertEqual(service_user_id, ctx.service_user_id)
|
||||
self.assertEqual(service_user_name, ctx.service_user_name)
|
||||
self.assertEqual(service_user_domain_id, ctx.service_user_domain_id)
|
||||
self.assertEqual(service_user_domain_name,
|
||||
ctx.service_user_domain_name)
|
||||
self.assertEqual(
|
||||
service_user_domain_name, ctx.service_user_domain_name
|
||||
)
|
||||
self.assertEqual(service_project_id, ctx.service_project_id)
|
||||
self.assertEqual(service_project_name, ctx.service_project_name)
|
||||
self.assertEqual(service_project_domain_id,
|
||||
ctx.service_project_domain_id)
|
||||
self.assertEqual(service_project_domain_name,
|
||||
ctx.service_project_domain_name)
|
||||
self.assertEqual(
|
||||
service_project_domain_id, ctx.service_project_domain_id
|
||||
)
|
||||
self.assertEqual(
|
||||
service_project_domain_name, ctx.service_project_domain_name
|
||||
)
|
||||
self.assertEqual(service_roles, ctx.service_roles)
|
||||
|
||||
def test_from_environ_no_roles(self):
|
||||
@@ -338,37 +340,36 @@ class ContextTest(test_base.BaseTestCase):
|
||||
new = uuid.uuid4().hex
|
||||
override = uuid.uuid4().hex
|
||||
|
||||
environ = {'HTTP_X_USER': old,
|
||||
'HTTP_X_USER_ID': new}
|
||||
environ = {'HTTP_X_USER': old, 'HTTP_X_USER_ID': new}
|
||||
|
||||
ctx = context.RequestContext.from_environ(environ=environ)
|
||||
self.assertEqual(new, ctx.user_id)
|
||||
|
||||
ctx = context.RequestContext.from_environ(
|
||||
environ=environ, user_id=override,
|
||||
environ=environ, user_id=override
|
||||
)
|
||||
self.assertEqual(override, ctx.user_id)
|
||||
|
||||
environ = {'HTTP_X_TENANT': old,
|
||||
'HTTP_X_PROJECT_ID': new}
|
||||
environ = {'HTTP_X_TENANT': old, 'HTTP_X_PROJECT_ID': new}
|
||||
|
||||
ctx = context.RequestContext.from_environ(environ=environ)
|
||||
self.assertEqual(new, ctx.project_id)
|
||||
|
||||
ctx = context.RequestContext.from_environ(
|
||||
environ=environ, project_id=override,
|
||||
environ=environ, project_id=override
|
||||
)
|
||||
self.assertEqual(override, ctx.project_id)
|
||||
|
||||
environ = {'HTTP_X_TENANT_NAME': old,
|
||||
'HTTP_X_PROJECT_NAME': new}
|
||||
environ = {'HTTP_X_TENANT_NAME': old, 'HTTP_X_PROJECT_NAME': new}
|
||||
|
||||
ctx = context.RequestContext.from_environ(environ=environ)
|
||||
self.assertEqual(new, ctx.project_name)
|
||||
|
||||
def test_from_environ_strip_roles(self):
|
||||
environ = {'HTTP_X_ROLES': ' abc\t,\ndef\n,ghi\n\n',
|
||||
'HTTP_X_SERVICE_ROLES': ' jkl\t,\nmno\n,pqr\n\n'}
|
||||
environ = {
|
||||
'HTTP_X_ROLES': ' abc\t,\ndef\n,ghi\n\n',
|
||||
'HTTP_X_SERVICE_ROLES': ' jkl\t,\nmno\n,pqr\n\n',
|
||||
}
|
||||
ctx = context.RequestContext.from_environ(environ=environ)
|
||||
self.assertEqual(['abc', 'def', 'ghi'], ctx.roles)
|
||||
self.assertEqual(['jkl', 'mno', 'pqr'], ctx.service_roles)
|
||||
@@ -491,8 +492,7 @@ class ContextTest(test_base.BaseTestCase):
|
||||
self.assertEqual(show_deleted, d['show_deleted'])
|
||||
self.assertEqual(request_id, d['request_id'])
|
||||
self.assertEqual(resource_uuid, d['resource_uuid'])
|
||||
user_identity = "{} {} {} {} {}".format(
|
||||
user_id, project_id, domain_id, user_domain_id, project_domain_id)
|
||||
user_identity = f"{user_id} {project_id} {domain_id} {user_domain_id} {project_domain_id}"
|
||||
self.assertEqual(user_identity, d['user_identity'])
|
||||
self.assertEqual([], d['roles'])
|
||||
|
||||
@@ -535,7 +535,8 @@ class ContextTest(test_base.BaseTestCase):
|
||||
auth_token_info={'auth_token': 'topsecret'},
|
||||
service_token="1234567",
|
||||
auth_token="8901234",
|
||||
user_id=userid)
|
||||
user_id=userid,
|
||||
)
|
||||
safe_ctxt = ctx.redacted_copy()
|
||||
self.assertIsNone(safe_ctxt.auth_token_info)
|
||||
self.assertIsNone(safe_ctxt.service_token)
|
||||
|
||||
@@ -17,7 +17,6 @@ from oslo_context import fixture
|
||||
|
||||
|
||||
class ClearRequestContextTest(test_base.BaseTestCase):
|
||||
|
||||
# def setUp(self):
|
||||
# super(ContextTest, self).setUp()
|
||||
# self.useFixture(fixture.ClearRequestContext())
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
[tool.ruff]
|
||||
line-length = 79
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "preserve"
|
||||
docstring-code-format = true
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["E4", "E7", "E9", "F", "S", "U"]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"oslo_context/tests/*" = ["S"]
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.9"
|
||||
show_column_numbers = true
|
||||
|
||||
@@ -186,9 +186,13 @@ htmlhelp_basename = 'oslo.contextReleaseNotesDoc'
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'oslo.contextReleaseNotes.tex',
|
||||
'oslo.context Release Notes Documentation',
|
||||
'oslo.context Developers', 'manual'),
|
||||
(
|
||||
'index',
|
||||
'oslo.contextReleaseNotes.tex',
|
||||
'oslo.context Release Notes Documentation',
|
||||
'oslo.context Developers',
|
||||
'manual',
|
||||
),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
@@ -216,9 +220,13 @@ latex_documents = [
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'oslo.contextReleaseNotes',
|
||||
'oslo.context Release Notes Documentation',
|
||||
['oslo.context Developers'], 1)
|
||||
(
|
||||
'index',
|
||||
'oslo.contextReleaseNotes',
|
||||
'oslo.context Release Notes Documentation',
|
||||
['oslo.context Developers'],
|
||||
1,
|
||||
)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
@@ -230,11 +238,15 @@ man_pages = [
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'oslo.contextReleaseNotes',
|
||||
'oslo.context Release Notes Documentation',
|
||||
'oslo.context Developers', 'oslo.contextReleaseNotes',
|
||||
'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
(
|
||||
'index',
|
||||
'oslo.contextReleaseNotes',
|
||||
'oslo.context Release Notes Documentation',
|
||||
'oslo.context Developers',
|
||||
'oslo.contextReleaseNotes',
|
||||
'One line description of project.',
|
||||
'Miscellaneous',
|
||||
),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
|
||||
3
setup.py
3
setup.py
@@ -17,4 +17,5 @@ import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr>=2.0.0'],
|
||||
pbr=True)
|
||||
pbr=True,
|
||||
)
|
||||
|
||||
10
tox.ini
10
tox.ini
@@ -46,10 +46,12 @@ commands =
|
||||
coverage xml -o cover/coverage.xml
|
||||
|
||||
[flake8]
|
||||
# E123, E125 skipped as they are invalid PEP-8.
|
||||
show-source = true
|
||||
ignore = E123,E125
|
||||
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
|
||||
# We only enable the hacking (H) checks
|
||||
select = H
|
||||
# H301 Black will put commas after imports that can't fit on one line
|
||||
# H404 Docstrings don't always start with a newline
|
||||
# H405 Multiline docstrings are okay
|
||||
ignore = H301,H403,H404,H405
|
||||
|
||||
[hacking]
|
||||
import_exceptions =
|
||||
|
||||
Reference in New Issue
Block a user