diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 836a062..e65ad31 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,6 +12,12 @@ repos: - id: debug-statements - id: check-yaml files: .*\.(yaml|yml)$ + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.13.0 + hooks: + - id: ruff-check + args: ['--fix', '--unsafe-fixes'] + - id: ruff-format - repo: https://opendev.org/openstack/hacking rev: 7.0.0 hooks: diff --git a/doc/source/conf.py b/doc/source/conf.py index 0c474a0..f067dc7 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (C) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -33,7 +32,7 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', - 'openstackdocstheme' + 'openstackdocstheme', ] # Add any paths that contain templates here, relative to this directory. @@ -50,7 +49,7 @@ master_doc = 'index' # General information about the project. project = 'microversion-parse' copyright = '2016, OpenStack' -author = u'OpenStack' +author = 'OpenStack' # openstackdocstheme options repository_name = 'openstack/microversion-parse' @@ -92,7 +91,7 @@ latex_documents = [ 'microversion-parse.tex', 'microversion-parse Documentation', 'OpenStack', - 'manual' + 'manual', ), ] @@ -104,9 +103,9 @@ man_pages = [ ( master_doc, 'microversion-parse', - u'microversion-parse Documentation', + 'microversion-parse Documentation', [author], - 1 + 1, ) ] @@ -120,11 +119,11 @@ texinfo_documents = [ ( master_doc, 'microversion-parse', - u'microversion-parse Documentation', + 'microversion-parse Documentation', author, 'microversion-parse', 'One line description of project.', - 'Miscellaneous' + 'Miscellaneous', ), ] diff --git a/microversion_parse/__init__.py b/microversion_parse/__init__.py index d126ea7..7a5efa4 100644 --- a/microversion_parse/__init__.py +++ b/microversion_parse/__init__.py @@ -26,17 +26,16 @@ class Version(collections.namedtuple('Version', 'major minor')): def __new__(cls, major, minor): """Add min and max version attributes to the tuple.""" - self = super(Version, cls).__new__(cls, major, minor) + self = super().__new__(cls, major, minor) self.max_version = (-1, 0) self.min_version = (-1, 0) return self def __str__(self): - return '%s.%s' % (self.major, self.minor) + return f'{self.major}.{self.minor}' def matches(self, min_version=None, max_version=None): - """Is this version within min_version and max_version. - """ + """Is this version within min_version and max_version.""" # NOTE(cdent): min_version and max_version are expected # to be set by the code that is creating the Version, if # they are known. @@ -155,7 +154,8 @@ def _extract_header_value(headers, header_name): value = headers[header_name] except KeyError: wsgi_header_name = ENVIRON_HTTP_HEADER_FMT.format( - header_name.replace('-', '_')) + header_name.replace('-', '_') + ) value = headers[wsgi_header_name] return value @@ -173,11 +173,9 @@ def parse_version_string(version_string): # ValueError, TypeError or AttributeError when the incoming # data is poorly formed but will, however, naturally adapt to # extraneous whitespace. - return Version(*(int(value) for value - in version_string.split('.', 1))) + return Version(*(int(value) for value in version_string.split('.', 1))) except (ValueError, TypeError, AttributeError) as exc: - raise TypeError('invalid version string: %s; %s' % ( - version_string, exc)) + raise TypeError(f'invalid version string: {version_string}; {exc}') def extract_version(headers, service_type, versions_list): @@ -213,4 +211,4 @@ def extract_version(headers, service_type, versions_list): # to administratively disable a version if we really need to. if str(request_version) in versions_list: return request_version - raise ValueError('Unacceptable version header: %s' % version_string) + raise ValueError(f'Unacceptable version header: {version_string}') diff --git a/microversion_parse/middleware.py b/microversion_parse/middleware.py index 00a8693..6961593 100644 --- a/microversion_parse/middleware.py +++ b/microversion_parse/middleware.py @@ -18,7 +18,7 @@ import webob.dec import microversion_parse -class MicroversionMiddleware(object): +class MicroversionMiddleware: """WSGI middleware for getting microversion info. The application will get a WSGI environ with a @@ -37,8 +37,9 @@ class MicroversionMiddleware(object): Otherwise the application is called. """ - def __init__(self, application, service_type, versions, - json_error_formatter=None): + def __init__( + self, application, service_type, versions, json_error_formatter=None + ): """Create the WSGI middleware. :param application: The application hosting the service. @@ -51,7 +52,7 @@ class MicroversionMiddleware(object): """ self.application = application self.service_type = service_type - self.microversion_environ = '%s.microversion' % service_type + self.microversion_environ = f'{service_type}.microversion' self.versions = versions self.json_error_formatter = json_error_formatter @@ -59,21 +60,24 @@ class MicroversionMiddleware(object): def __call__(self, req): try: microversion = microversion_parse.extract_version( - req.headers, self.service_type, self.versions) + req.headers, self.service_type, self.versions + ) # TODO(cdent): These error response are not formatted according to # api-sig guidelines, unless a json_error_formatter is provided # that can do it. For an example, see the placement service. except ValueError as exc: raise webob.exc.HTTPNotAcceptable( - ('Invalid microversion: %(error)s') % {'error': exc}, - json_formatter=self.json_error_formatter) + (f'Invalid microversion: {exc}'), + json_formatter=self.json_error_formatter, + ) except TypeError as exc: raise webob.exc.HTTPBadRequest( - ('Invalid microversion: %(error)s') % {'error': exc}, - json_formatter=self.json_error_formatter) + (f'Invalid microversion: {exc}'), + json_formatter=self.json_error_formatter, + ) req.environ[self.microversion_environ] = microversion - microversion_header = '%s %s' % (self.service_type, microversion) + microversion_header = f'{self.service_type} {microversion}' standard_header = microversion_parse.STANDARD_HEADER try: diff --git a/microversion_parse/tests/test_extract_version.py b/microversion_parse/tests/test_extract_version.py index 62bcf83..55b6a86 100644 --- a/microversion_parse/tests/test_extract_version.py +++ b/microversion_parse/tests/test_extract_version.py @@ -18,9 +18,8 @@ import microversion_parse class TestVersion(testtools.TestCase): - def setUp(self): - super(TestVersion, self).setUp() + super().setUp() self.version = microversion_parse.Version(1, 5) def test_version_is_tuple(self): @@ -69,7 +68,6 @@ class TestVersion(testtools.TestCase): class TestParseVersionString(testtools.TestCase): - def test_good_version(self): version = microversion_parse.parse_version_string('1.1') self.assertEqual((1, 1), version) @@ -81,57 +79,68 @@ class TestParseVersionString(testtools.TestCase): self.assertEqual(microversion_parse.Version(1, 1), version) def test_non_numeric(self): - self.assertRaises(TypeError, - microversion_parse.parse_version_string, - 'hello') + self.assertRaises( + TypeError, microversion_parse.parse_version_string, 'hello' + ) def test_mixed_alphanumeric(self): - self.assertRaises(TypeError, - microversion_parse.parse_version_string, - '1.a') + self.assertRaises( + TypeError, microversion_parse.parse_version_string, '1.a' + ) def test_too_many_numeric(self): - self.assertRaises(TypeError, - microversion_parse.parse_version_string, - '1.1.1') + self.assertRaises( + TypeError, microversion_parse.parse_version_string, '1.1.1' + ) def test_not_string(self): - self.assertRaises(TypeError, - microversion_parse.parse_version_string, - 1.1) + self.assertRaises( + TypeError, microversion_parse.parse_version_string, 1.1 + ) class TestExtractVersion(testtools.TestCase): - def setUp(self): - super(TestExtractVersion, self).setUp() + super().setUp() self.headers = [ ('OpenStack-API-Version', 'service1 1.2'), ('OpenStack-API-Version', 'service2 1.5'), ('OpenStack-API-Version', 'service3 latest'), ('OpenStack-API-Version', 'service4 2.5'), ] - self.version_list = ['1.1', '1.2', '1.3', '1.4', - '2.1', '2.2', '2.3', '2.4'] + self.version_list = [ + '1.1', + '1.2', + '1.3', + '1.4', + '2.1', + '2.2', + '2.3', + '2.4', + ] def test_simple_extract(self): version = microversion_parse.extract_version( - self.headers, 'service1', self.version_list) + self.headers, 'service1', self.version_list + ) self.assertEqual((1, 2), version) def test_default_min(self): version = microversion_parse.extract_version( - self.headers, 'notlisted', self.version_list) + self.headers, 'notlisted', self.version_list + ) self.assertEqual((1, 1), version) def test_latest(self): version = microversion_parse.extract_version( - self.headers, 'service3', self.version_list) + self.headers, 'service3', self.version_list + ) self.assertEqual((2, 4), version) def test_min_max_extract(self): version = microversion_parse.extract_version( - self.headers, 'service1', self.version_list) + self.headers, 'service1', self.version_list + ) # below min self.assertFalse(version.matches((1, 3))) @@ -144,13 +153,24 @@ class TestExtractVersion(testtools.TestCase): # explicit min self.assertFalse(version.matches(min_version=(2, 3))) # explicit both - self.assertTrue(version.matches(min_version=(0, 3), - max_version=(1, 5))) + self.assertTrue( + version.matches(min_version=(0, 3), max_version=(1, 5)) + ) def test_version_disabled(self): - self.assertRaises(ValueError, microversion_parse.extract_version, - self.headers, 'service2', self.version_list) + self.assertRaises( + ValueError, + microversion_parse.extract_version, + self.headers, + 'service2', + self.version_list, + ) def test_version_out_of_range(self): - self.assertRaises(ValueError, microversion_parse.extract_version, - self.headers, 'service4', self.version_list) + self.assertRaises( + ValueError, + microversion_parse.extract_version, + self.headers, + 'service4', + self.version_list, + ) diff --git a/microversion_parse/tests/test_get_version.py b/microversion_parse/tests/test_get_version.py index fa16681..0b8d55c 100644 --- a/microversion_parse/tests/test_get_version.py +++ b/microversion_parse/tests/test_get_version.py @@ -17,7 +17,6 @@ import microversion_parse class TestFoldHeaders(testtools.TestCase): - def test_dict_headers(self): headers = { 'header-one': 'alpha', @@ -39,20 +38,19 @@ class TestFoldHeaders(testtools.TestCase): folded_headers = microversion_parse.fold_headers(headers) self.assertEqual(2, len(folded_headers)) - self.assertEqual(set(['header-one', 'header-two']), - set(folded_headers.keys())) + self.assertEqual( + set(['header-one', 'header-two']), set(folded_headers.keys()) + ) self.assertEqual('alpha,gamma', folded_headers['header-one']) def test_bad_headers(self): headers = 'wow this is not a headers' - self.assertRaises(ValueError, microversion_parse.fold_headers, - headers) + self.assertRaises(ValueError, microversion_parse.fold_headers, headers) # TODO(cdent): Test with request objects from frameworks. class TestStandardHeader(testtools.TestCase): - def test_simple_match(self): headers = { 'header-one': 'alpha', @@ -88,8 +86,7 @@ class TestStandardHeader(testtools.TestCase): 'openstack-api-version': 'network 5.9 ', 'header-two': 'beta', } - version = microversion_parse.check_standard_header( - headers, 'compute') + version = microversion_parse.check_standard_header(headers, 'compute') self.assertEqual(None, version) def test_match_multiple_services(self): @@ -98,11 +95,11 @@ class TestStandardHeader(testtools.TestCase): 'openstack-api-version': 'network 5.9 ,compute 2.1,telemetry 7.8', 'header-two': 'beta', } - version = microversion_parse.check_standard_header( - headers, 'compute') + version = microversion_parse.check_standard_header(headers, 'compute') self.assertEqual('2.1', version) version = microversion_parse.check_standard_header( - headers, 'telemetry') + headers, 'telemetry' + ) self.assertEqual('7.8', version) def test_match_multiple_same_service(self): @@ -111,13 +108,11 @@ class TestStandardHeader(testtools.TestCase): 'openstack-api-version': 'compute 5.9 ,compute 2.1,compute 7.8', 'header-two': 'beta', } - version = microversion_parse.check_standard_header( - headers, 'compute') + version = microversion_parse.check_standard_header(headers, 'compute') self.assertEqual('7.8', version) class TestLegacyHeaders(testtools.TestCase): - def test_legacy_headers_straight(self): headers = { 'header-one': 'alpha', @@ -125,8 +120,10 @@ class TestLegacyHeaders(testtools.TestCase): 'header-two': 'beta', } version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['openstack-CoMpUte-api-version']) + headers, + service_type='compute', + legacy_headers=['openstack-CoMpUte-api-version'], + ) self.assertEqual('2.1', version) def test_legacy_headers_folded(self): @@ -136,8 +133,10 @@ class TestLegacyHeaders(testtools.TestCase): 'header-two': 'beta', } version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['openstack-compute-api-version']) + headers, + service_type='compute', + legacy_headers=['openstack-compute-api-version'], + ) self.assertEqual('9.2', version) def test_older_legacy_headers(self): @@ -147,9 +146,13 @@ class TestLegacyHeaders(testtools.TestCase): 'header-two': 'beta', } version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['openstack-nova-api-version', - 'x-openstack-nova-api-version']) + headers, + service_type='compute', + legacy_headers=[ + 'openstack-nova-api-version', + 'x-openstack-nova-api-version', + ], + ) # We don't do x- for service types. self.assertEqual('9.2', version) @@ -161,19 +164,26 @@ class TestLegacyHeaders(testtools.TestCase): 'header-two': 'beta', } version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['openstack-compute-api-version', - 'x-openstack-nova-api-version']) + headers, + service_type='compute', + legacy_headers=[ + 'openstack-compute-api-version', + 'x-openstack-nova-api-version', + ], + ) self.assertEqual('3.7', version) version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['x-openstack-nova-api-version', - 'openstack-compute-api-version']) + headers, + service_type='compute', + legacy_headers=[ + 'x-openstack-nova-api-version', + 'openstack-compute-api-version', + ], + ) self.assertEqual('9.2', version) class TestGetHeaders(testtools.TestCase): - def test_preference(self): headers = { 'header-one': 'alpha', @@ -183,15 +193,20 @@ class TestGetHeaders(testtools.TestCase): 'header-two': 'beta', } version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['openstack-compute-api-version', - 'x-openstack-nova-api-version']) + headers, + service_type='compute', + legacy_headers=[ + 'openstack-compute-api-version', + 'x-openstack-nova-api-version', + ], + ) self.assertEqual('11.12', version) def test_no_headers(self): headers = {} version = microversion_parse.get_version( - headers, service_type='compute') + headers, service_type='compute' + ) self.assertEqual(None, version) def test_unfolded_service(self): @@ -202,7 +217,8 @@ class TestGetHeaders(testtools.TestCase): ('openstack-api-version', '3.0'), ] version = microversion_parse.get_version( - headers, service_type='compute') + headers, service_type='compute' + ) self.assertEqual('2.0', version) def test_unfolded_in_name(self): @@ -213,15 +229,17 @@ class TestGetHeaders(testtools.TestCase): ('openstack-telemetry-api-version', '3.0'), ] version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['x-openstack-nova-api-version']) + headers, + service_type='compute', + legacy_headers=['x-openstack-nova-api-version'], + ) self.assertEqual('2.0', version) def test_capitalized_headers(self): - headers = { - 'X-Openstack-Ironic-Api-Version': '123.456' - } + headers = {'X-Openstack-Ironic-Api-Version': '123.456'} version = microversion_parse.get_version( - headers, service_type='ironic', - legacy_headers=['X-Openstack-Ironic-Api-Version']) + headers, + service_type='ironic', + legacy_headers=['X-Openstack-Ironic-Api-Version'], + ) self.assertEqual('123.456', version) diff --git a/microversion_parse/tests/test_headers_from_wsgi_environ.py b/microversion_parse/tests/test_headers_from_wsgi_environ.py index 525ac6e..0c1420c 100644 --- a/microversion_parse/tests/test_headers_from_wsgi_environ.py +++ b/microversion_parse/tests/test_headers_from_wsgi_environ.py @@ -17,13 +17,12 @@ import microversion_parse class TestHeadersFromWSGIEnviron(testtools.TestCase): - def test_empty_environ(self): environ = {} expected = {} self.assertEqual( - expected, - microversion_parse.headers_from_wsgi_environ(environ)) + expected, microversion_parse.headers_from_wsgi_environ(environ) + ) def test_non_empty_no_headers(self): environ = {'PATH_INFO': '/foo/bar'} @@ -32,30 +31,40 @@ class TestHeadersFromWSGIEnviron(testtools.TestCase): self.assertEqual(expected, found_headers) def test_headers(self): - environ = {'PATH_INFO': '/foo/bar', - 'HTTP_OPENSTACK_API_VERSION': 'placement 2.1', - 'HTTP_CONTENT_TYPE': 'application/json'} - expected = {'HTTP_OPENSTACK_API_VERSION': 'placement 2.1', - 'HTTP_CONTENT_TYPE': 'application/json'} + environ = { + 'PATH_INFO': '/foo/bar', + 'HTTP_OPENSTACK_API_VERSION': 'placement 2.1', + 'HTTP_CONTENT_TYPE': 'application/json', + } + expected = { + 'HTTP_OPENSTACK_API_VERSION': 'placement 2.1', + 'HTTP_CONTENT_TYPE': 'application/json', + } found_headers = microversion_parse.headers_from_wsgi_environ(environ) self.assertEqual(expected, found_headers) def test_get_version_from_environ(self): - environ = {'PATH_INFO': '/foo/bar', - 'HTTP_OPENSTACK_API_VERSION': 'placement 2.1', - 'HTTP_CONTENT_TYPE': 'application/json'} + environ = { + 'PATH_INFO': '/foo/bar', + 'HTTP_OPENSTACK_API_VERSION': 'placement 2.1', + 'HTTP_CONTENT_TYPE': 'application/json', + } expected_version = '2.1' headers = microversion_parse.headers_from_wsgi_environ(environ) version = microversion_parse.get_version(headers, 'placement') self.assertEqual(expected_version, version) def test_get_version_from_environ_legacy(self): - environ = {'PATH_INFO': '/foo/bar', - 'HTTP_X_OPENSTACK_PLACEMENT_API_VERSION': '2.1', - 'HTTP_CONTENT_TYPE': 'application/json'} + environ = { + 'PATH_INFO': '/foo/bar', + 'HTTP_X_OPENSTACK_PLACEMENT_API_VERSION': '2.1', + 'HTTP_CONTENT_TYPE': 'application/json', + } expected_version = '2.1' headers = microversion_parse.headers_from_wsgi_environ(environ) version = microversion_parse.get_version( - headers, 'placement', - legacy_headers=['x-openstack-placement-api-version']) + headers, + 'placement', + legacy_headers=['x-openstack-placement-api-version'], + ) self.assertEqual(expected_version, version) diff --git a/microversion_parse/tests/test_middleware.py b/microversion_parse/tests/test_middleware.py index 9060d08..731b7a0 100644 --- a/microversion_parse/tests/test_middleware.py +++ b/microversion_parse/tests/test_middleware.py @@ -32,7 +32,7 @@ VERSIONS = [ ] -class SimpleWSGI(object): +class SimpleWSGI: """A WSGI application that can be contiained within a middlware.""" def __call__(self, environ, start_response): @@ -41,12 +41,13 @@ class SimpleWSGI(object): start_response('200 OK', [('content-type', 'text/plain')]) return [b'good'] - raise webob.exc.HTTPNotFound('%s not found' % path_info) + raise webob.exc.HTTPNotFound(f'{path_info} not found') def app(): app = middleware.MicroversionMiddleware( - SimpleWSGI(), SERVICE_TYPE, VERSIONS) + SimpleWSGI(), SERVICE_TYPE, VERSIONS + ) return app @@ -54,4 +55,5 @@ def load_tests(loader, tests, pattern): """Provide a TestSuite to the discovery process.""" test_dir = os.path.join(os.path.dirname(__file__), TESTS_DIR) return driver.build_tests( - test_dir, loader, test_loader_name=__name__, intercept=app) + test_dir, loader, test_loader_name=__name__, intercept=app + ) diff --git a/microversion_parse/tests/test_webob.py b/microversion_parse/tests/test_webob.py index a2e36c8..405d1a1 100644 --- a/microversion_parse/tests/test_webob.py +++ b/microversion_parse/tests/test_webob.py @@ -22,59 +22,74 @@ class TestWebobHeaders(testtools.TestCase): """Webob uses a dict-like header which is not actually a dict.""" def test_simple_headers(self): - headers = wb_headers.EnvironHeaders({ - 'HTTP_HEADER_ONE': 'alpha', - 'HTTP_HEADER_TWO': 'beta', - 'HTTP_HEADER_THREE': 'gamma', - }) + headers = wb_headers.EnvironHeaders( + { + 'HTTP_HEADER_ONE': 'alpha', + 'HTTP_HEADER_TWO': 'beta', + 'HTTP_HEADER_THREE': 'gamma', + } + ) folded_headers = microversion_parse.fold_headers(headers) self.assertEqual(3, len(folded_headers)) - self.assertEqual(set(['header-one', 'header-three', 'header-two']), - set(folded_headers.keys())) + self.assertEqual( + set(['header-one', 'header-three', 'header-two']), + set(folded_headers.keys()), + ) self.assertEqual('gamma', folded_headers['header-three']) def test_simple_match(self): - headers = wb_headers.EnvironHeaders({ - 'HTTP_HEADER_ONE': 'alpha', - 'HTTP_OPENSTACK_API_VERSION': 'compute 2.1', - 'HTTP_HEADER_TWO': 'beta', - }) + headers = wb_headers.EnvironHeaders( + { + 'HTTP_HEADER_ONE': 'alpha', + 'HTTP_OPENSTACK_API_VERSION': 'compute 2.1', + 'HTTP_HEADER_TWO': 'beta', + } + ) version = microversion_parse.check_standard_header(headers, 'compute') self.assertEqual('2.1', version) def test_match_multiple_services(self): - headers = wb_headers.EnvironHeaders({ - 'HTTP_HEADER_ONE': 'alpha', - 'HTTP_OPENSTACK_API_VERSION': - 'network 5.9 ,compute 2.1,telemetry 7.8', - 'HTTP_HEADER_TWO': 'beta', - }) - version = microversion_parse.check_standard_header( - headers, 'compute') + headers = wb_headers.EnvironHeaders( + { + 'HTTP_HEADER_ONE': 'alpha', + 'HTTP_OPENSTACK_API_VERSION': 'network 5.9 ,compute 2.1,telemetry 7.8', + 'HTTP_HEADER_TWO': 'beta', + } + ) + version = microversion_parse.check_standard_header(headers, 'compute') self.assertEqual('2.1', version) version = microversion_parse.check_standard_header( - headers, 'telemetry') + headers, 'telemetry' + ) self.assertEqual('7.8', version) def test_legacy_headers_straight(self): - headers = wb_headers.EnvironHeaders({ - 'HTTP_HEADER_ONE': 'alpha', - 'HTTP_X_OPENSTACK_NOVA_API_VERSION': ' 2.1 ', - 'HTTP_HEADER_TWO': 'beta', - }) + headers = wb_headers.EnvironHeaders( + { + 'HTTP_HEADER_ONE': 'alpha', + 'HTTP_X_OPENSTACK_NOVA_API_VERSION': ' 2.1 ', + 'HTTP_HEADER_TWO': 'beta', + } + ) version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['x-openstack-nova-api-version']) + headers, + service_type='compute', + legacy_headers=['x-openstack-nova-api-version'], + ) self.assertEqual('2.1', version) def test_legacy_headers_folded(self): - headers = wb_headers.EnvironHeaders({ - 'HTTP_HEADER_ONE': 'alpha', - 'HTTP_X_OPENSTACK_NOVA_API_VERSION': ' 2.1, 9.2 ', - 'HTTP_HEADER_TWO': 'beta', - }) + headers = wb_headers.EnvironHeaders( + { + 'HTTP_HEADER_ONE': 'alpha', + 'HTTP_X_OPENSTACK_NOVA_API_VERSION': ' 2.1, 9.2 ', + 'HTTP_HEADER_TWO': 'beta', + } + ) version = microversion_parse.get_version( - headers, service_type='compute', - legacy_headers=['x-openstack-nova-api-version']) + headers, + service_type='compute', + legacy_headers=['x-openstack-nova-api-version'], + ) self.assertEqual('9.2', version) diff --git a/pyproject.toml b/pyproject.toml index d04fe09..a08ff5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,3 +33,20 @@ Repository = "https://opendev.org/openstack/microversion-parse" packages = [ "microversion_parse" ] + +[tool.ruff] +line-length = 79 + +[tool.ruff.format] +quote-style = "single" +docstring-code-format = true + +[tool.ruff.lint] +select = ["E4", "E7", "E9", "F", "S", "U"] +ignore = [ + # we only use asserts for type narrowing + "S101", +] + +[tool.ruff.lint.per-file-ignores] +"microversion_parse/tests/*" = ["S"] diff --git a/setup.py b/setup.py index 7f1bbe8..808f790 100644 --- a/setup.py +++ b/setup.py @@ -15,4 +15,5 @@ import setuptools setuptools.setup( setup_requires=['pbr'], - pbr=True) + pbr=True, +) diff --git a/tox.ini b/tox.ini index 851eba9..74cef87 100644 --- a/tox.ini +++ b/tox.ini @@ -48,6 +48,8 @@ whitelist_externals = rm [flake8] -ignore = H405,E126 +# We only enable the hacking (H) checks +select = H +ignore = H405 exclude = .venv,.git,.tox,dist,*egg,*.egg-info,build,examples,doc show-source = true