diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f4a91a..c29274a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v5.0.0 hooks: - id: trailing-whitespace # Replaces or checks mixed line ending @@ -19,12 +19,17 @@ repos: - id: check-yaml files: .*\.(yaml|yml)$ - repo: https://opendev.org/openstack/hacking - rev: 6.1.0 + rev: 7.0.0 hooks: - id: hacking additional_dependencies: [] - repo: https://github.com/PyCQA/bandit - rev: 1.7.6 + rev: 1.7.10 hooks: - id: bandit args: ['-x', 'tests', '-s', 'B314,B405'] + - repo: https://github.com/asottile/pyupgrade + rev: v3.18.0 + hooks: + - id: pyupgrade + args: [--py3-only] diff --git a/doc/source/conf.py b/doc/source/conf.py index e8d8189..6b84fbf 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"); diff --git a/oslo_reports/generators/conf.py b/oslo_reports/generators/conf.py index cdb8c43..a3a7e15 100644 --- a/oslo_reports/generators/conf.py +++ b/oslo_reports/generators/conf.py @@ -24,7 +24,7 @@ from oslo_config import cfg from oslo_reports.models import conf as cm -class ConfigReportGenerator(object): +class ConfigReportGenerator: """A Configuration Data Generator This generator returns diff --git a/oslo_reports/generators/process.py b/oslo_reports/generators/process.py index 2749ff2..1738040 100644 --- a/oslo_reports/generators/process.py +++ b/oslo_reports/generators/process.py @@ -25,7 +25,7 @@ import psutil from oslo_reports.models import process as pm -class ProcessReportGenerator(object): +class ProcessReportGenerator: """A Process Data Generator This generator returns a diff --git a/oslo_reports/generators/threading.py b/oslo_reports/generators/threading.py index 09382e4..1e9af56 100644 --- a/oslo_reports/generators/threading.py +++ b/oslo_reports/generators/threading.py @@ -46,7 +46,7 @@ def _find_objects(t): return [o for o in gc.get_objects() if isinstance(o, t)] -class ThreadReportGenerator(object): +class ThreadReportGenerator: """A Thread Data Generator This generator returns a collection of @@ -63,10 +63,10 @@ class ThreadReportGenerator(object): self.traceback = curr_thread_traceback def __call__(self): - threadModels = dict( - (thread_id, tm.ThreadModel(thread_id, stack)) + threadModels = { + thread_id: tm.ThreadModel(thread_id, stack) for thread_id, stack in sys._current_frames().items() - ) + } if self.traceback is not None: curr_thread_id = threading.current_thread().ident @@ -77,7 +77,7 @@ class ThreadReportGenerator(object): text_view=text_views.MultiView()) -class GreenThreadReportGenerator(object): +class GreenThreadReportGenerator: """A Green Thread Data Generator This generator returns a collection of diff --git a/oslo_reports/generators/version.py b/oslo_reports/generators/version.py index 97f6e4f..125537f 100644 --- a/oslo_reports/generators/version.py +++ b/oslo_reports/generators/version.py @@ -23,7 +23,7 @@ generators for generating the model in from oslo_reports.models import version as vm -class PackageReportGenerator(object): +class PackageReportGenerator: """A Package Information Data Generator This generator returns diff --git a/oslo_reports/guru_meditation_report.py b/oslo_reports/guru_meditation_report.py index 22eba42..e3f848c 100644 --- a/oslo_reports/guru_meditation_report.py +++ b/oslo_reports/guru_meditation_report.py @@ -84,7 +84,7 @@ except ImportError: LOG = logging.getLogger(__name__) -class GuruMeditation(object): +class GuruMeditation: """A Guru Meditation Report Mixin/Base Class This class is a base class for Guru Meditation Reports. @@ -104,7 +104,7 @@ class GuruMeditation(object): self.version_obj = version_obj self.traceback = sig_handler_tb - super(GuruMeditation, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.start_section_index = len(self.sections) @classmethod @@ -179,8 +179,8 @@ class GuruMeditation(object): mtime = stat.st_mtime except OSError: msg = ("Guru Meditation Report cannot read " + - "'{0}' file".format(filepath)) - raise IOError(msg) + "'{}' file".format(filepath)) + raise OSError(msg) finally: time.sleep(interval) @@ -223,7 +223,7 @@ class GuruMeditation(object): if log_dir: service_name = service_name or os.path.basename( inspect.stack()[-1][1]) - filename = "%s_gurumeditation_%s" % ( + filename = "{}_gurumeditation_{}".format( service_name, timeutils.utcnow().strftime( cls.timestamp_fmt)) filepath = os.path.join(log_dir, filename) @@ -263,7 +263,7 @@ class GuruMeditation(object): def run(self): self._readd_sections() - return super(GuruMeditation, self).run() + return super().run() # GuruMeditation must come first to get the correct MRO @@ -291,5 +291,4 @@ class TextGuruMeditation(GuruMeditation, report.TextReport): """ def __init__(self, version_obj, traceback=None): - super(TextGuruMeditation, self).__init__(version_obj, traceback, - 'Guru Meditation') + super().__init__(version_obj, traceback, 'Guru Meditation') diff --git a/oslo_reports/models/conf.py b/oslo_reports/models/conf.py index e56a5cd..3060c89 100644 --- a/oslo_reports/models/conf.py +++ b/oslo_reports/models/conf.py @@ -36,7 +36,7 @@ class ConfigModel(mwdv.ModelWithDefaultViews): def __init__(self, conf_obj): kv_view = generic_text_views.KeyValueView(dict_sep=": ", before_dict='') - super(ConfigModel, self).__init__(text_view=kv_view) + super().__init__(text_view=kv_view) def opt_title(optname, co): return co._opts[optname]['opt'].name @@ -47,20 +47,20 @@ class ConfigModel(mwdv.ModelWithDefaultViews): else: return value - self['default'] = dict( - (opt_title(optname, conf_obj), - opt_value(conf_obj._opts[optname], conf_obj[optname])) + self['default'] = { + opt_title(optname, conf_obj): + opt_value(conf_obj._opts[optname], conf_obj[optname]) for optname in conf_obj._opts - ) + } groups = {} for groupname in conf_obj._groups: group_obj = conf_obj._groups[groupname] - curr_group_opts = dict( - (opt_title(optname, group_obj), - opt_value(group_obj._opts[optname], - conf_obj[groupname][optname])) - for optname in group_obj._opts) + curr_group_opts = { + opt_title(optname, group_obj): + opt_value(group_obj._opts[optname], + conf_obj[groupname][optname]) + for optname in group_obj._opts} groups[group_obj.name] = curr_group_opts self.update(groups) diff --git a/oslo_reports/models/process.py b/oslo_reports/models/process.py index 9f6514d..0dcb89c 100644 --- a/oslo_reports/models/process.py +++ b/oslo_reports/models/process.py @@ -32,7 +32,7 @@ class ProcessModel(mwdv.ModelWithDefaultViews): """ def __init__(self, process): - super(ProcessModel, self).__init__( + super().__init__( text_view=text_views.ProcessView()) self['pid'] = process.pid diff --git a/oslo_reports/models/threading.py b/oslo_reports/models/threading.py index 5caca3c..d52c06e 100644 --- a/oslo_reports/models/threading.py +++ b/oslo_reports/models/threading.py @@ -34,7 +34,7 @@ class StackTraceModel(mwdv.ModelWithDefaultViews): """ def __init__(self, stack_state): - super(StackTraceModel, self).__init__( + super().__init__( text_view=text_views.StackTraceView()) if (stack_state is not None): @@ -72,7 +72,7 @@ class ThreadModel(mwdv.ModelWithDefaultViews): # threadId, stack in sys._current_frams().items() def __init__(self, thread_id, stack): - super(ThreadModel, self).__init__(text_view=text_views.ThreadView()) + super().__init__(text_view=text_views.ThreadView()) self['thread_id'] = thread_id self['stack_trace'] = StackTraceModel(stack) @@ -95,6 +95,6 @@ class GreenThreadModel(mwdv.ModelWithDefaultViews): # gr in greenpool.coroutines_running --> gr.gr_frame def __init__(self, stack): - super(GreenThreadModel, self).__init__( + super().__init__( {'stack_trace': StackTraceModel(stack)}, text_view=text_views.GreenThreadView()) diff --git a/oslo_reports/models/version.py b/oslo_reports/models/version.py index 50d2f6c..4fa3d39 100644 --- a/oslo_reports/models/version.py +++ b/oslo_reports/models/version.py @@ -35,7 +35,7 @@ class PackageModel(mwdv.ModelWithDefaultViews): """ def __init__(self, vendor, product, version): - super(PackageModel, self).__init__( + super().__init__( text_view=generic_text_views.KeyValueView() ) diff --git a/oslo_reports/models/with_default_views.py b/oslo_reports/models/with_default_views.py index cce9d88..c4b1f42 100644 --- a/oslo_reports/models/with_default_views.py +++ b/oslo_reports/models/with_default_views.py @@ -62,11 +62,11 @@ class ModelWithDefaultViews(base_model.ReportModel): if k.endswith('_view'): self.views[k[:-5]] = kwargs[k] del newargs[k] - super(ModelWithDefaultViews, self).__init__(*args, **newargs) + super().__init__(*args, **newargs) def set_current_view_type(self, tp, visited=None): self.attached_view = self.views[tp] - super(ModelWithDefaultViews, self).set_current_view_type(tp, visited) + super().set_current_view_type(tp, visited) def __getattr__(self, attrname): if attrname[:3] == 'to_': @@ -78,4 +78,4 @@ class ModelWithDefaultViews(base_model.ReportModel): " a default view for " "{tp}").format(cn=type(self), tp=attrname[3:])) else: - return super(ModelWithDefaultViews, self).__getattr__(attrname) + return super().__getattr__(attrname) diff --git a/oslo_reports/report.py b/oslo_reports/report.py index f12f634..dd4f22d 100644 --- a/oslo_reports/report.py +++ b/oslo_reports/report.py @@ -23,7 +23,7 @@ sections. from oslo_reports.views.text import header as header_views -class BasicReport(object): +class BasicReport: """A Basic Report A Basic Report consists of a collection of :class:`ReportSection` @@ -76,7 +76,7 @@ class BasicReport(object): return "\n".join(str(sect) for sect in self.sections) -class ReportSection(object): +class ReportSection: """A Report Section A report section contains a generator and a top-level view. When something @@ -122,7 +122,7 @@ class ReportOfType(BasicReport): def __init__(self, tp): self.output_type = tp - super(ReportOfType, self).__init__() + super().__init__() def add_section(self, view, generator, index=None): def with_type(gen): @@ -136,7 +136,7 @@ class ReportOfType(BasicReport): return res return newgen - super(ReportOfType, self).add_section( + super().add_section( view, with_type(generator), index @@ -153,7 +153,7 @@ class TextReport(ReportOfType): """ def __init__(self, name): - super(TextReport, self).__init__('text') + super().__init__('text') self.name = name # add a title with a generator that creates an empty result model self.add_section(name, lambda: ('|' * 72) + "\n\n") @@ -183,6 +183,4 @@ class TextReport(ReportOfType): :type index: int or None """ - super(TextReport, self).add_section(header_views.TitledView(heading), - generator, - index) + super().add_section(header_views.TitledView(heading), generator, index) diff --git a/oslo_reports/tests/test_base_report.py b/oslo_reports/tests/test_base_report.py index 11dd18b..63bfb84 100644 --- a/oslo_reports/tests/test_base_report.py +++ b/oslo_reports/tests/test_base_report.py @@ -21,7 +21,7 @@ from oslo_reports.models import base as base_model from oslo_reports import report -class BasicView(object): +class BasicView: def __call__(self, model): res = "" for k in sorted(model.keys()): @@ -35,7 +35,7 @@ def basic_generator(): class TestBasicReport(base.BaseTestCase): def setUp(self): - super(TestBasicReport, self).setUp() + super().setUp() self.report = report.BasicReport() @@ -64,7 +64,7 @@ class TestBasicReport(base.BaseTestCase): class TestBaseModel(base.BaseTestCase): def test_submodel_attached_view(self): - class TmpView(object): + class TmpView: def __call__(self, model): return '{len: ' + str(len(model.c)) + '}' diff --git a/oslo_reports/tests/test_guru_meditation_report.py b/oslo_reports/tests/test_guru_meditation_report.py index a77af4e..14ad144 100644 --- a/oslo_reports/tests/test_guru_meditation_report.py +++ b/oslo_reports/tests/test_guru_meditation_report.py @@ -37,7 +37,7 @@ CONF = oslo_config.cfg.CONF opts.set_defaults(CONF) -class FakeVersionObj(object): +class FakeVersionObj: def vendor_string(self): return 'Cheese Shoppe' @@ -59,7 +59,7 @@ def skip_body_lines(start_line, report_lines): class GmrConfigFixture(fixture.Config): def setUp(self): - super(GmrConfigFixture, self).setUp() + super().setUp() self.conf.set_override( 'file_event_handler', @@ -77,7 +77,7 @@ class GmrConfigFixture(fixture.Config): class TestGuruMeditationReport(base.BaseTestCase): def setUp(self): - super(TestGuruMeditationReport, self).setUp() + super().setUp() self.curr_g = greenlet.getcurrent() @@ -242,6 +242,6 @@ class TestGuruMeditationReport(base.BaseTestCase): self.assertIn('RunFail', sys.stderr.getvalue()) def tearDown(self): - super(TestGuruMeditationReport, self).tearDown() + super().tearDown() if self.old_stderr is not None: sys.stderr = self.old_stderr diff --git a/oslo_reports/tests/test_openstack_generators.py b/oslo_reports/tests/test_openstack_generators.py index 9bda519..809c18b 100644 --- a/oslo_reports/tests/test_openstack_generators.py +++ b/oslo_reports/tests/test_openstack_generators.py @@ -45,7 +45,7 @@ class TestOpenstackGenerators(base.BaseTestCase): self.assertIsNotNone(str(model)) def test_thread_generator_tb(self): - class FakeModel(object): + class FakeModel: def __init__(self, thread_id, tb): self.traceback = tb @@ -117,7 +117,7 @@ class TestOpenstackGenerators(base.BaseTestCase): self.assertEqual(target_str, str(model)) def test_package_report_generator(self): - class VersionObj(object): + class VersionObj: def vendor_string(self): return 'Cheese Shoppe' @@ -136,7 +136,7 @@ class TestOpenstackGenerators(base.BaseTestCase): self.assertEqual(target_str, str(model)) def test_package_report_generator_without_vendor_string(self): - class VersionObj(object): + class VersionObj: def product_string(self): return 'Sharp Cheddar' diff --git a/oslo_reports/tests/test_views.py b/oslo_reports/tests/test_views.py index 76cbd09..9219e9e 100644 --- a/oslo_reports/tests/test_views.py +++ b/oslo_reports/tests/test_views.py @@ -121,7 +121,7 @@ class TestModelReportType(base.BaseTestCase): class TestGenericXMLView(base.BaseTestCase): def setUp(self): - super(TestGenericXMLView, self).setUp() + super().setUp() self.model = mwdv_generator() self.model.set_current_view_type('xml') @@ -191,7 +191,7 @@ class TestGenericXMLView(base.BaseTestCase): class TestGenericJSONViews(base.BaseTestCase): def setUp(self): - super(TestGenericJSONViews, self).setUp() + super().setUp() self.model = mwdv_generator() self.model.set_current_view_type('json') @@ -260,7 +260,7 @@ class TestGenericJSONViews(base.BaseTestCase): class TestGenericTextViews(base.BaseTestCase): def setUp(self): - super(TestGenericTextViews, self).setUp() + super().setUp() self.model = mwdv_generator() self.model.set_current_view_type('text') @@ -412,7 +412,7 @@ class TestJinjaView(base.BaseTestCase): MM_OPEN, MM_FILE = get_open_mocks(TEMPL_STR) def setUp(self): - super(TestJinjaView, self).setUp() + super().setUp() self.model = base_model.ReportModel(data={'int': 1, 'string': 'value'}) @mock.mock_open(MM_OPEN) diff --git a/oslo_reports/views/jinja_view.py b/oslo_reports/views/jinja_view.py index 765dbba..9d7b602 100644 --- a/oslo_reports/views/jinja_view.py +++ b/oslo_reports/views/jinja_view.py @@ -24,7 +24,7 @@ import copy import jinja2 -class JinjaView(object): +class JinjaView: """A Jinja View This view renders the given model using the provided Jinja @@ -49,7 +49,7 @@ class JinjaView(object): self._text = self.VIEW_TEXT except AttributeError: if path is not None: - with open(path, 'r') as f: + with open(path) as f: self._text = f.read() elif text is not None: self._text = text diff --git a/oslo_reports/views/json/generic.py b/oslo_reports/views/json/generic.py index 5580ba1..ce03506 100644 --- a/oslo_reports/views/json/generic.py +++ b/oslo_reports/views/json/generic.py @@ -30,7 +30,7 @@ from oslo_serialization import jsonutils as json from oslo_reports import _utils as utils -class BasicKeyValueView(object): +class BasicKeyValueView: """A Basic Key-Value JSON View This view performs a naive serialization of a model @@ -43,7 +43,7 @@ class BasicKeyValueView(object): return res -class KeyValueView(object): +class KeyValueView: """A Key-Value JSON View This view performs advanced serialization to a model diff --git a/oslo_reports/views/text/generic.py b/oslo_reports/views/text/generic.py index 3de3a45..b02bda3 100644 --- a/oslo_reports/views/text/generic.py +++ b/oslo_reports/views/text/generic.py @@ -21,7 +21,7 @@ serializing models into human-readable text. from collections import abc -class MultiView(object): +class MultiView: """A Text View Containing Multiple Views This view simply serializes each @@ -37,7 +37,7 @@ class MultiView(object): return "\n".join(res) -class BasicKeyValueView(object): +class BasicKeyValueView: """A Basic Key-Value Text View This view performs a naive serialization of a model into @@ -53,7 +53,7 @@ class BasicKeyValueView(object): return res -class KeyValueView(object): +class KeyValueView: """A Key-Value Text View This view performs an advanced serialization of a model @@ -151,7 +151,7 @@ class KeyValueView(object): return "\n".join(serialize(model, None, -1)) -class TableView(object): +class TableView: """A Basic Table Text View This view performs serialization of data into a basic table with @@ -196,6 +196,6 @@ class TableView(object): row = [str(raw_row[prop_name]) for prop_name in self.column_values] # double format is in case we have roundoff error - res += '{0: <72}\n'.format(self.row_fmt_str.format(cv=row)) + res += '{: <72}\n'.format(self.row_fmt_str.format(cv=row)) return res diff --git a/oslo_reports/views/text/header.py b/oslo_reports/views/text/header.py index be53c40..d9569a4 100644 --- a/oslo_reports/views/text/header.py +++ b/oslo_reports/views/text/header.py @@ -18,7 +18,7 @@ This package defines several text views with headers """ -class HeaderView(object): +class HeaderView: """A Text View With a Header This view simply serializes the model and places the given @@ -48,4 +48,4 @@ class TitledView(HeaderView): FORMAT_STR = ('=' * 72) + "\n===={0: ^64}====\n" + ('=' * 72) def __init__(self, title): - super(TitledView, self).__init__(self.FORMAT_STR.format(title)) + super().__init__(self.FORMAT_STR.format(title)) diff --git a/oslo_reports/views/text/threading.py b/oslo_reports/views/text/threading.py index 5b84f30..30d3c09 100644 --- a/oslo_reports/views/text/threading.py +++ b/oslo_reports/views/text/threading.py @@ -48,7 +48,7 @@ class StackTraceView(jv.JinjaView): ) -class GreenThreadView(object): +class GreenThreadView: """A Green Thread View This view displays a green thread provided by the data @@ -64,7 +64,7 @@ class GreenThreadView(object): ) -class ThreadView(object): +class ThreadView: """A Thread Collection View This view displays a python thread provided by the data @@ -75,6 +75,6 @@ class ThreadView(object): def __call__(self, model): return self.FORMAT_STR.format( - thread_str=" Thread #{0} ".format(model.thread_id), + thread_str=" Thread #{} ".format(model.thread_id), stack_trace=model.stack_trace ) diff --git a/oslo_reports/views/xml/generic.py b/oslo_reports/views/xml/generic.py index 2d1cd94..dd9b9cb 100644 --- a/oslo_reports/views/xml/generic.py +++ b/oslo_reports/views/xml/generic.py @@ -30,7 +30,7 @@ import xml.etree.ElementTree as ET from oslo_reports import _utils as utils -class KeyValueView(object): +class KeyValueView: """A Key-Value XML View This view performs advanced serialization of a data model diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py index bdf6976..33236f8 100644 --- a/releasenotes/source/conf.py +++ b/releasenotes/source/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at