diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9c25eaae3..8f28bb402 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: v2.1.0 + rev: v2.3.0 hooks: - id: check-builtin-literals args: ['--no-allow-dict-kwargs'] @@ -14,15 +14,15 @@ repos: exclude: ^test_data/ - id: trailing-whitespace - repo: https://github.com/asottile/reorder_python_imports - rev: v1.3.4 + rev: v1.6.1 hooks: - id: reorder-python-imports language_version: python3 - repo: https://github.com/asottile/add-trailing-comma - rev: v0.7.1 + rev: v1.4.1 hooks: - id: add-trailing-comma - repo: https://github.com/pre-commit/mirrors-autopep8 - rev: v1.4.3 + rev: v1.4.4 hooks: - id: autopep8 diff --git a/detect_secrets/core/audit.py b/detect_secrets/core/audit.py index 2502ecb89..11497d761 100644 --- a/detect_secrets/core/audit.py +++ b/detect_secrets/core/audit.py @@ -349,7 +349,7 @@ def _check_secret(a, b): if not new_filename: secrets_to_compare += list( map( - lambda x: (old_filename, x, True,), + lambda x: (old_filename, x, True), old_baseline['results'][old_filename], ), ) @@ -357,7 +357,7 @@ def _check_secret(a, b): elif not old_filename: secrets_to_compare += list( map( - lambda x: (new_filename, x, False,), + lambda x: (new_filename, x, False), new_baseline['results'][new_filename], ), ) @@ -374,11 +374,11 @@ def _check_secret(a, b): if old_secret: secrets_to_compare.append( - (old_filename, old_secret, True,), + (old_filename, old_secret, True), ) else: secrets_to_compare.append( - (new_filename, new_secret, False,), + (new_filename, new_secret, False), ) return secrets_to_compare @@ -404,22 +404,22 @@ def _comparison_generator(old_list, new_list, compare_fn): status = compare_fn(old_value, new_value) if status == 0: - yield (old_value, new_value,) + yield (old_value, new_value) old_index += 1 new_index += 1 elif status == -1: - yield (old_value, None,) + yield (old_value, None) old_index += 1 else: - yield (None, new_value,) + yield (None, new_value) new_index += 1 # Catch leftovers. Only one of these while statements should run. while old_index < len(old_list): - yield (old_list[old_index], None,) + yield (old_list[old_index], None) old_index += 1 while new_index < len(new_list): - yield (None, new_list[new_index],) + yield (None, new_list[new_index]) new_index += 1 @@ -462,16 +462,18 @@ def _print_context( # pragma: no cover :raises: SecretNotFoundOnSpecifiedLineError """ - print('{} {} {} {}\n{} {}\n{} {}'.format( - colorize('Secret: ', AnsiColor.BOLD), - colorize(str(count), AnsiColor.PURPLE), - colorize('of', AnsiColor.BOLD), - colorize(str(total), AnsiColor.PURPLE), - colorize('Filename: ', AnsiColor.BOLD), - colorize(filename, AnsiColor.PURPLE), - colorize('Secret Type:', AnsiColor.BOLD), - colorize(secret['type'], AnsiColor.PURPLE), - )) + print( + '{} {} {} {}\n{} {}\n{} {}'.format( + colorize('Secret: ', AnsiColor.BOLD), + colorize(str(count), AnsiColor.PURPLE), + colorize('of', AnsiColor.BOLD), + colorize(str(total), AnsiColor.PURPLE), + colorize('Filename: ', AnsiColor.BOLD), + colorize(filename, AnsiColor.PURPLE), + colorize('Secret Type:', AnsiColor.BOLD), + colorize(secret['type'], AnsiColor.PURPLE), + ), + ) if additional_header_lines: print(additional_header_lines) diff --git a/detect_secrets/core/baseline.py b/detect_secrets/core/baseline.py index 9e16a6f81..bff8da118 100644 --- a/detect_secrets/core/baseline.py +++ b/detect_secrets/core/baseline.py @@ -242,7 +242,7 @@ def format_baseline_for_output(baseline): for filename, secret_list in baseline['results'].items(): baseline['results'][filename] = sorted( secret_list, - key=lambda x: (x['line_number'], x['hashed_secret'],), + key=lambda x: (x['line_number'], x['hashed_secret']), ) return json.dumps( diff --git a/detect_secrets/core/secrets_collection.py b/detect_secrets/core/secrets_collection.py index 9aed15a68..9266dd15f 100644 --- a/detect_secrets/core/secrets_collection.py +++ b/detect_secrets/core/secrets_collection.py @@ -70,17 +70,21 @@ def load_baseline_from_dict(cls, data): """ result = SecretsCollection() - if not all(key in data for key in ( - 'plugins_used', - 'results', - )): + if not all( + key in data for key in ( + 'plugins_used', + 'results', + ) + ): raise IOError # In v0.12.0 `exclude_regex` got replaced by `exclude` - if not any(key in data for key in ( - 'exclude', - 'exclude_regex', - )): + if not any( + key in data for key in ( + 'exclude', + 'exclude_regex', + ) + ): raise IOError if 'exclude_regex' in data: @@ -259,10 +263,12 @@ def format_for_baseline_output(self): for key in results: results[key] = sorted(results[key], key=lambda x: x['line_number']) - plugins_used = list(map( - lambda x: x.__dict__, - self.plugins, - )) + plugins_used = list( + map( + lambda x: x.__dict__, + self.plugins, + ), + ) plugins_used = sorted(plugins_used, key=lambda x: x['name']) return { diff --git a/detect_secrets/core/usage.py b/detect_secrets/core/usage.py index cbbddd903..ad6e3116d 100644 --- a/detect_secrets/core/usage.py +++ b/detect_secrets/core/usage.py @@ -233,32 +233,34 @@ def add_arguments(self): return self -class PluginDescriptor(namedtuple( - 'PluginDescriptor', - [ - # Classname of plugin; used for initialization - 'classname', - - # Flag to disable plugin. e.g. `--no-hex-string-scan` - 'disable_flag_text', - - # Description for disable flag. - 'disable_help_text', - - # type: list - # Allows the bundling of all related command line provided - # arguments together, under one plugin name. - # Assumes there is no shared related arg. - # - # Furthermore, each related arg can have its own default - # value (paired together, with a tuple). This allows us to - # distinguish the difference between a default value, and - # whether a user has entered the same value as a default value. - # Therefore, only populate the default value upon consolidation - # (rather than relying on argparse default). - 'related_args', - ], -)): +class PluginDescriptor( + namedtuple( + 'PluginDescriptor', + [ + # Classname of plugin; used for initialization + 'classname', + + # Flag to disable plugin. e.g. `--no-hex-string-scan` + 'disable_flag_text', + + # Description for disable flag. + 'disable_help_text', + + # type: list + # Allows the bundling of all related command line provided + # arguments together, under one plugin name. + # Assumes there is no shared related arg. + # + # Furthermore, each related arg can have its own default + # value (paired together, with a tuple). This allows us to + # distinguish the difference between a default value, and + # whether a user has entered the same value as a default value. + # Therefore, only populate the default value upon consolidation + # (rather than relying on argparse default). + 'related_args', + ], + ), +): def __new__(cls, related_args=None, **kwargs): if not related_args: @@ -279,7 +281,7 @@ class PluginOptions(object): disable_flag_text='--no-hex-string-scan', disable_help_text='Disables scanning for hex high entropy strings', related_args=[ - ('--hex-limit', 3,), + ('--hex-limit', 3), ], ), PluginDescriptor( @@ -287,7 +289,7 @@ class PluginOptions(object): disable_flag_text='--no-base64-string-scan', disable_help_text='Disables scanning for base64 high entropy strings', related_args=[ - ('--base64-limit', 4.5,), + ('--base64-limit', 4.5), ], ), PluginDescriptor( diff --git a/detect_secrets/plugins/common/ini_file_parser.py b/detect_secrets/plugins/common/ini_file_parser.py index b412ef6d1..e42744591 100644 --- a/detect_secrets/plugins/common/ini_file_parser.py +++ b/detect_secrets/plugins/common/ini_file_parser.py @@ -119,10 +119,12 @@ def _get_value_and_line_offset(self, key, values): continue if current_value_list_index == 0: - first_line_regex = re.compile(r'^\s*{}[ :=]+{}'.format( - re.escape(key), - re.escape(values_list[current_value_list_index]), - )) + first_line_regex = re.compile( + r'^\s*{}[ :=]+{}'.format( + re.escape(key), + re.escape(values_list[current_value_list_index]), + ), + ) if first_line_regex.match(line): output.append(( values_list[current_value_list_index], diff --git a/detect_secrets/plugins/common/yaml_file_parser.py b/detect_secrets/plugins/common/yaml_file_parser.py index 079d4e98c..2e6902064 100644 --- a/detect_secrets/plugins/common/yaml_file_parser.py +++ b/detect_secrets/plugins/common/yaml_file_parser.py @@ -76,7 +76,7 @@ def _tag_dict_values(self, map_node): new_values = [] for key, value in map_node.value: if not value.tag.endswith(':str'): - new_values.append((key, value,)) + new_values.append((key, value)) continue augmented_string = yaml.nodes.MappingNode( @@ -95,7 +95,7 @@ def _tag_dict_values(self, map_node): ], ) - new_values.append((key, augmented_string,)) + new_values.append((key, augmented_string)) output = yaml.nodes.MappingNode( tag=map_node.tag, diff --git a/detect_secrets/plugins/high_entropy_strings.py b/detect_secrets/plugins/high_entropy_strings.py index 96f75a7eb..e5d692906 100644 --- a/detect_secrets/plugins/high_entropy_strings.py +++ b/detect_secrets/plugins/high_entropy_strings.py @@ -49,10 +49,10 @@ def __init__(self, charset, limit, exclude_lines_regex, *args): def analyze(self, file, filename): file_type_analyzers = ( - (self._analyze_ini_file(), configparser.Error,), - (self._analyze_yaml_file, yaml.YAMLError,), - (super(HighEntropyStringsPlugin, self).analyze, Exception,), - (self._analyze_ini_file(add_header=True), configparser.Error,), + (self._analyze_ini_file(), configparser.Error), + (self._analyze_yaml_file, yaml.YAMLError), + (super(HighEntropyStringsPlugin, self).analyze, Exception), + (self._analyze_ini_file(add_header=True), configparser.Error), ) for analyze_function, exception_class in file_type_analyzers: @@ -169,11 +169,13 @@ def wrapped(file, filename): add_header, exclude_lines_regex=self.exclude_lines_regex, ).iterator(): - potential_secrets.update(self.analyze_string( - value, - lineno, - filename, - )) + potential_secrets.update( + self.analyze_string( + value, + lineno, + filename, + ), + ) return potential_secrets diff --git a/testing/mocks.py b/testing/mocks.py index c2b444135..6597618a8 100644 --- a/testing/mocks.py +++ b/testing/mocks.py @@ -65,14 +65,16 @@ def _mock_subprocess_git_call(cmds, **kwargs): yield -class SubprocessMock(namedtuple( - 'SubprocessMock', - [ - 'expected_input', - 'mocked_output', - 'should_throw_exception', - ], -)): +class SubprocessMock( + namedtuple( + 'SubprocessMock', + [ + 'expected_input', + 'mocked_output', + 'should_throw_exception', + ], + ), +): """For use with mock_subprocess. :type expected_input: string diff --git a/tests/core/audit_test.py b/tests/core/audit_test.py index 1fca23ad9..e6e22ae81 100644 --- a/tests/core/audit_test.py +++ b/tests/core/audit_test.py @@ -1023,10 +1023,10 @@ class TestGetUserDecision(object): @pytest.mark.parametrize( 'user_input, expected_value', [ - ('y', 'y',), - ('N', 'n',), - ('Skip', 's',), - ('QUIT', 'q',), + ('y', 'y'), + ('N', 'n'), + ('Skip', 's'), + ('QUIT', 'q'), ], ) def test_get_user_decision_valid_input( diff --git a/tests/core/baseline_test.py b/tests/core/baseline_test.py index ebd96722b..03d7e1dc5 100644 --- a/tests/core/baseline_test.py +++ b/tests/core/baseline_test.py @@ -61,10 +61,12 @@ def test_basic_usage(self, path): assert len(results['test_data/files/tmp/file_with_secrets.py']) == 2 def test_with_multiple_files(self): - results = self.get_results(path=[ - 'test_data/files/file_with_secrets.py', - 'test_data/files/tmp/file_with_secrets.py', - ]) + results = self.get_results( + path=[ + 'test_data/files/file_with_secrets.py', + 'test_data/files/tmp/file_with_secrets.py', + ], + ) assert len(results['test_data/files/file_with_secrets.py']) == 1 assert len(results['test_data/files/tmp/file_with_secrets.py']) == 2 @@ -589,9 +591,11 @@ def test_sorts_by_line_number_then_hash(self): }, }) - ordered_hashes = list(map( - lambda x: x['hashed_secret'], - json.loads(output_string)['results']['filename'], - )) + ordered_hashes = list( + map( + lambda x: x['hashed_secret'], + json.loads(output_string)['results']['filename'], + ), + ) assert ordered_hashes == ['z', 'a', 'f'] diff --git a/tests/core/usage_test.py b/tests/core/usage_test.py index 9e99ed7e5..890bc4f55 100644 --- a/tests/core/usage_test.py +++ b/tests/core/usage_test.py @@ -53,8 +53,8 @@ def test_consolidates_removes_disabled_plugins(self): @pytest.mark.parametrize( 'argument_string,expected_value', [ - ('--hex-limit 5', 5.0,), - ('--hex-limit 2.3', 2.3,), + ('--hex-limit 5', 5.0), + ('--hex-limit 2.3', 2.3), ('--hex-limit 0', 0), ('--hex-limit 8', 8), ('--hex-limit -1', None), diff --git a/tests/main_test.py b/tests/main_test.py index 27e096683..6f9108eed 100644 --- a/tests/main_test.py +++ b/tests/main_test.py @@ -87,7 +87,8 @@ def test_scan_string_basic( main_module, ) as printer_shim: assert main('scan --string'.split()) == 0 - assert uncolor(printer_shim.message) == textwrap.dedent(""" + assert uncolor(printer_shim.message) == textwrap.dedent( + """ AWSKeyDetector : False ArtifactoryDetector : False Base64HighEntropyString: {} @@ -99,9 +100,10 @@ def test_scan_string_basic( SlackDetector : False StripeDetector : False """.format( - expected_base64_result, - expected_hex_result, - ))[1:] + expected_base64_result, + expected_hex_result, + ), + )[1:] mock_baseline_initialize.assert_not_called() diff --git a/tests/plugins/basic_auth_test.py b/tests/plugins/basic_auth_test.py index d87005386..57be9a20e 100644 --- a/tests/plugins/basic_auth_test.py +++ b/tests/plugins/basic_auth_test.py @@ -10,12 +10,12 @@ class TestBasicAuthDetector(object): @pytest.mark.parametrize( 'payload, should_flag', [ - ('https://username:password@yelp.com', True,), - ('http://localhost:5000/<%= @variable %>', False,), - ('"https://url:8000";@something else', False,), - ('\'https://url:8000\';@something else', False,), - ('https://url:8000 @something else', False,), - ('https://url:8000/ @something else', False,), + ('https://username:password@yelp.com', True), + ('http://localhost:5000/<%= @variable %>', False), + ('"https://url:8000";@something else', False), + ('\'https://url:8000\';@something else', False), + ('https://url:8000 @something else', False), + ('https://url:8000/ @something else', False), ], ) def test_analyze_string(self, payload, should_flag): diff --git a/tests/plugins/high_entropy_strings_test.py b/tests/plugins/high_entropy_strings_test.py index 6ec8f1fc1..9c9b72c7e 100644 --- a/tests/plugins/high_entropy_strings_test.py +++ b/tests/plugins/high_entropy_strings_test.py @@ -170,7 +170,7 @@ def setup(self): ), ( 'test_data/files/file_with_secrets.py', - ['Location: test_data/files/file_with_secrets.py:3', ], + ['Location: test_data/files/file_with_secrets.py:3'], ), # Mark down files with colons and unicode charaters preceding the # colon on the line would cause the scanner to fail and exit on @@ -179,7 +179,7 @@ def setup(self): # high entropy issues ( 'test_data/config.md', - ['Location: test_data/config.md:10', ], + ['Location: test_data/config.md:10'], ), ], ) diff --git a/tests/pre_commit_hook_test.py b/tests/pre_commit_hook_test.py index 7c6fd011e..003941e71 100644 --- a/tests/pre_commit_hook_test.py +++ b/tests/pre_commit_hook_test.py @@ -32,10 +32,12 @@ class TestPreCommitHook(object): def test_file_with_secrets(self, mock_log): assert_commit_blocked('test_data/files/file_with_secrets.py') - message_by_lines = list(filter( - lambda x: x != '', - mock_log.error_messages.splitlines(), - )) + message_by_lines = list( + filter( + lambda x: x != '', + mock_log.error_messages.splitlines(), + ), + ) assert message_by_lines[0].startswith( 'Potential secrets about to be committed to git repo!', @@ -136,10 +138,10 @@ def test_quit_if_baseline_is_changed_but_not_staged(self, mock_log): @pytest.mark.parametrize( 'baseline_version, current_version', [ - ('', '0.8.8',), - ('0.8.8', '0.8.9',), - ('0.8.8', '0.9.0',), - ('0.8.8', '1.0.0',), + ('', '0.8.8'), + ('0.8.8', '0.8.9'), + ('0.8.8', '0.9.0'), + ('0.8.8', '1.0.0'), ], ) def test_that_baseline_gets_updated( diff --git a/tox.ini b/tox.ini index 7cdf50d48..cca1ed7df 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ commands = coverage run -m pytest tests coverage report --show-missing --include=tests/* --fail-under 100 coverage report --show-missing --include=detect_secrets/* --fail-under 98 - pre-commit run --all-files + pre-commit run --all-files --show-diff-on-failure [testenv:venv] envdir = venv