From 34292ee649e038631b39fb6bb969a83e6e901ff1 Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Mon, 13 Feb 2023 21:07:15 +0000 Subject: [PATCH] Add hacking check for line continuation backslash This patch adds a hacking check for line continuation backslashes and fixes the occurences that existed in the code. Change-Id: I13cd03e16698b7f1d8036815d12a665bd1156f2f --- designateclient/functionaltests/datagen.py | 17 ++++++------- .../functionaltests/v2/test_recordsets.py | 6 ++--- designateclient/hacking/checks.py | 24 +++++++++++++++++++ designateclient/utils.py | 4 ++-- designateclient/v2/cli/common.py | 20 ++++++++-------- designateclient/v2/cli/zones.py | 8 +++---- designateclient/v2/recordsets.py | 4 ++-- tox.ini | 1 + 8 files changed, 55 insertions(+), 29 deletions(-) diff --git a/designateclient/functionaltests/datagen.py b/designateclient/functionaltests/datagen.py index aaa555fb..3aea79d6 100644 --- a/designateclient/functionaltests/datagen.py +++ b/designateclient/functionaltests/datagen.py @@ -46,11 +46,12 @@ def random_blacklist(name='testblacklist'): def random_zone_file(name='testzoneimport'): - return "$ORIGIN {0}{1}.com.\n" \ - "$TTL 300\n" \ - "{0}{1}.com. 300 IN SOA ns.{0}{1}.com. " \ - "nsadmin.{0}{1}.com. 42 42 42 42 42\n" \ - "{0}{1}.com. 300 IN NS ns.{0}{1}.com.\n" \ - "{0}{1}.com. 300 IN MX 10 mail.{0}{1}.com.\n" \ - "ns.{0}{1}.com. 300 IN A 10.0.0.1\n" \ - "mail.{0}{1}.com. 300 IN A 10.0.0.2\n".format(name, random_digits()) + return ("$ORIGIN {0}{1}.com.\n" + "$TTL 300\n" + "{0}{1}.com. 300 IN SOA ns.{0}{1}.com. " + "nsadmin.{0}{1}.com. 42 42 42 42 42\n" + "{0}{1}.com. 300 IN NS ns.{0}{1}.com.\n" + "{0}{1}.com. 300 IN MX 10 mail.{0}{1}.com.\n" + "ns.{0}{1}.com. 300 IN A 10.0.0.1\n" + "mail.{0}{1}.com. 300 IN A 10.0.0.2\n".format(name, + random_digits())) diff --git a/designateclient/functionaltests/v2/test_recordsets.py b/designateclient/functionaltests/v2/test_recordsets.py index c9ab529d..419d03ce 100644 --- a/designateclient/functionaltests/v2/test_recordsets.py +++ b/designateclient/functionaltests/v2/test_recordsets.py @@ -101,9 +101,9 @@ class TestRecordset(BaseDesignateTest): class TestRecordsetNegative(BaseDesignateTest): def test_invalid_option_on_recordset_create(self): - cmd = 'recordset create de47d30b-41c5-4e38-b2c5-e0b908e19ec7 ' \ - 'aaa.desig.com. --type A --records 1.2.3.4 ' \ - '--invalid "not valid"' + cmd = ('recordset create de47d30b-41c5-4e38-b2c5-e0b908e19ec7 ' + 'aaa.desig.com. --type A --records 1.2.3.4 ' + '--invalid "not valid"') self.assertRaises(CommandFailed, self.clients.openstack, cmd) def test_invalid_recordset_command(self): diff --git a/designateclient/hacking/checks.py b/designateclient/hacking/checks.py index e2a5410a..c840a03d 100644 --- a/designateclient/hacking/checks.py +++ b/designateclient/hacking/checks.py @@ -27,6 +27,7 @@ import pycodestyle # D708: Do not use xrange. Use range for large loops. # D709: LOG.audit is deprecated, please use LOG.info! # D710: LOG.warn() is not allowed. Use LOG.warning() +# D711: Don't use backslashes for line continuation. UNDERSCORE_IMPORT_FILES = [] @@ -44,6 +45,7 @@ graduated_oslo_libraries_import_re = re.compile( r"^\s*(?:import|from) designate\.openstack\.common\.?.*?" r"(gettextutils|rpc)" r".*?") +no_line_continuation_backslash_re = re.compile(r'.*(\\)\n') @core.flake8ext @@ -161,3 +163,25 @@ def check_no_log_warn(logical_line): """ if logical_line.startswith('LOG.warn('): yield(0, "D710:Use LOG.warning() rather than LOG.warn()") + + +@core.flake8ext +def check_line_continuation_no_backslash(logical_line, tokens): + """D711 - Don't use backslashes for line continuation. + + :param logical_line: The logical line to check. Not actually used. + :param tokens: List of tokens to check. + :returns: None if the tokens don't contain any issues, otherwise a tuple + is yielded that contains the offending index in the logical + line and a message describe the check validation failure. + """ + backslash = None + for token_type, text, start, end, orig_line in tokens: + m = no_line_continuation_backslash_re.match(orig_line) + if m: + backslash = (start[0], m.start(1)) + break + + if backslash is not None: + msg = 'D711 Backslash line continuations not allowed' + yield backslash, msg diff --git a/designateclient/utils.py b/designateclient/utils.py index 1425b83c..79b1fb68 100644 --- a/designateclient/utils.py +++ b/designateclient/utils.py @@ -42,8 +42,8 @@ def get_item_properties(item, fields, mixed_case_fields=(), formatters=None): field_name = field.replace(' ', '_') else: field_name = field.lower().replace(' ', '_') - if not hasattr(item, field_name) and \ - (isinstance(item, dict) and field_name in item): + if (not hasattr(item, field_name) and + (isinstance(item, dict) and field_name in item)): data = item[field_name] else: data = getattr(item, field_name, '') diff --git a/designateclient/v2/cli/common.py b/designateclient/v2/cli/common.py index f8dbdfa2..564af0d7 100644 --- a/designateclient/v2/cli/common.py +++ b/designateclient/v2/cli/common.py @@ -74,20 +74,20 @@ def set_hard_delete(client, value): def set_all_common_headers(client, parsed_args): - if parsed_args.all_projects is not None and \ - isinstance(parsed_args.all_projects, bool): + if (parsed_args.all_projects is not None and + isinstance(parsed_args.all_projects, bool)): set_all_projects(client, parsed_args.all_projects) - if hasattr(parsed_args, 'edit_managed') and \ - parsed_args.edit_managed is not None and \ - isinstance(parsed_args.edit_managed, bool): + if (hasattr(parsed_args, 'edit_managed') and + parsed_args.edit_managed is not None and + isinstance(parsed_args.edit_managed, bool)): set_edit_managed(client, parsed_args.edit_managed) - if parsed_args.sudo_project_id is not None and \ - isinstance(parsed_args.sudo_project_id, str): + if (parsed_args.sudo_project_id is not None and + isinstance(parsed_args.sudo_project_id, str)): set_sudo_project_id(client, parsed_args.sudo_project_id) - if hasattr(parsed_args, 'hard_delete') and \ - parsed_args.hard_delete is not None and \ - isinstance(parsed_args.hard_delete, bool): + if (hasattr(parsed_args, 'hard_delete') and + parsed_args.hard_delete is not None and + isinstance(parsed_args.hard_delete, bool)): set_hard_delete(client, parsed_args.hard_delete) diff --git a/designateclient/v2/cli/zones.py b/designateclient/v2/cli/zones.py index f3262329..ca8d104a 100644 --- a/designateclient/v2/cli/zones.py +++ b/designateclient/v2/cli/zones.py @@ -159,8 +159,8 @@ class CreateZoneCommand(command.ShowOne): k, v = attr.split(':') payload["attributes"][k] = v except ValueError: - msg = "Attribute '%s' is in an incorrect format. "\ - "Attributes are : formated" + msg = ("Attribute '%s' is in an incorrect format. " + "Attributes are : formated") raise osc_exc.CommandError(msg % attr) if parsed_args.type == 'PRIMARY': @@ -177,8 +177,8 @@ class CreateZoneCommand(command.ShowOne): elif parsed_args.type == 'SECONDARY': payload["masters"] = parsed_args.masters else: - msg = "Type %s is not supported. Please choose between " \ - "PRIMARY or SECONDARY" + msg = ("Type %s is not supported. Please choose between " + "PRIMARY or SECONDARY") raise osc_exc.CommandError(msg % parsed_args.type) data = client.zones.create( diff --git a/designateclient/v2/recordsets.py b/designateclient/v2/recordsets.py index 7ae2266e..e6904fcd 100644 --- a/designateclient/v2/recordsets.py +++ b/designateclient/v2/recordsets.py @@ -24,8 +24,8 @@ class RecordSetController(V2Controller): zone_info = None # If we get a zone name we'll need to get the ID of it before POST. - if isinstance(zone, str) and not \ - uuidutils.is_uuid_like(zone): + if (isinstance(zone, str) and not + uuidutils.is_uuid_like(zone)): zone_info = self.client.zones.get(zone) elif isinstance(zone, dict): zone_info = zone diff --git a/tox.ini b/tox.ini index 86770408..7ccf3a8e 100644 --- a/tox.ini +++ b/tox.ini @@ -112,4 +112,5 @@ extension = D708 = checks:check_python3_xrange D709 = checks:check_no_log_audit D710 = checks:check_no_log_warn + D711 = checks:check_line_continuation_no_backslash paths = ./designateclient/hacking