From 31a6d856e502f6ffa51070c0cca7a5fcb06ec189 Mon Sep 17 00:00:00 2001 From: Eric Almeida Date: Thu, 26 Oct 2023 00:59:46 -0300 Subject: [PATCH 1/4] empty_values: add forbid in list items --- yamllint/rules/empty_values.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/yamllint/rules/empty_values.py b/yamllint/rules/empty_values.py index bdc773d0..eeb08644 100644 --- a/yamllint/rules/empty_values.py +++ b/yamllint/rules/empty_values.py @@ -82,9 +82,11 @@ ID = 'empty-values' TYPE = 'token' CONF = {'forbid-in-block-mappings': bool, - 'forbid-in-flow-mappings': bool} + 'forbid-in-flow-mappings': bool, + 'forbid-in-list-items': bool} DEFAULT = {'forbid-in-block-mappings': True, - 'forbid-in-flow-mappings': True} + 'forbid-in-flow-mappings': True, + 'forbid-in-list-items': False} def check(conf, token, prev, next, nextnext, context): @@ -102,3 +104,10 @@ def check(conf, token, prev, next, nextnext, context): yield LintProblem(token.start_mark.line + 1, token.end_mark.column + 1, 'empty value in flow mapping') + + if conf['forbid-in-list-items']: + if isinstance(token, yaml.BlockEntryToken) and isinstance(next, ( + yaml.KeyToken, yaml.BlockEndToken, yaml.BlockEntryToken)): + yield LintProblem(token.start_mark.line + 1, + token.end_mark.column + 1, + 'empty value in list items') From 0e97ef318dfb58e9a363255350cbae6ccfec6e5c Mon Sep 17 00:00:00 2001 From: Eric Almeida Date: Tue, 7 Nov 2023 21:55:53 -0300 Subject: [PATCH 2/4] tests: added tests to empty_values in list --- tests/rules/test_empty_values.py | 57 ++++++++++++++++++++++++++++++++ yamllint/rules/empty_values.py | 22 ++++++++++++ 2 files changed, 79 insertions(+) diff --git a/tests/rules/test_empty_values.py b/tests/rules/test_empty_values.py index dee8a5c8..3b93b925 100644 --- a/tests/rules/test_empty_values.py +++ b/tests/rules/test_empty_values.py @@ -258,3 +258,60 @@ def test_in_flow_mappings_comments(self): problem1=(4, 7), problem2=(7, 9), problem3=(10, 5)) + + def test_in_list_items_disabled(self): + conf = ('empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-list-items: false}\n' + 'braces: disable\n' + 'commas: disable\n') + self.check('---\n' + 'foo:\n' + ' - bar\n' + ' -\n', conf) + self.check('---\n' + 'foo:\n' + ' -\n', conf) + + def test_in_list_items_primative_item(self): + conf = ('empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-list-items: true}\n' + 'braces: disable\n' + 'commas: disable\n') + self.check('---\n' + 'foo:\n' + ' -\n', conf, + problem=(3, 4)) + self.check('---\n' + 'foo:\n' + ' - bar\n' + ' -\n', conf, + problem=(4, 4)) + self.check('---\n' + 'foo:\n' + ' - 1\n' + ' - 2\n' + ' -\n', conf, + problem=(5, 4)) + self.check('---\n' + 'foo:\n' + ' - null\n', conf) + + def test_in_list_items_various_explicit_null(self): + conf = ('empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-list-items: true}\n' + 'braces: disable\n' + 'commas: disable\n') + self.check('---\n' + 'foo:\n' + ' - null\n', conf) + self.check('---\n' + '- null\n', conf) + self.check('---\n' + 'foo:\n' + ' - bar: null\n', conf) + self.check('---\n' + '- null\n' + '- null\n', conf) diff --git a/yamllint/rules/empty_values.py b/yamllint/rules/empty_values.py index eeb08644..3be0af62 100644 --- a/yamllint/rules/empty_values.py +++ b/yamllint/rules/empty_values.py @@ -21,6 +21,7 @@ * Use ``forbid-in-block-mappings`` to prevent empty values in block mappings. * Use ``forbid-in-flow-mappings`` to prevent empty values in flow mappings. +* Use ``forbid-in-list-items`` to prevent empty values in lists. .. rubric:: Default values (when enabled) @@ -30,6 +31,7 @@ empty-values: forbid-in-block-mappings: true forbid-in-flow-mappings: true + forbid-in-list-items: false .. rubric:: Examples @@ -72,6 +74,26 @@ {a: 1, b:, c: 3} +#. With ``empty-values: {forbid-in-list-items: true}`` + + the following code snippet would **PASS**: + :: + + some-list: + - string item + + the following code snippets would **FAIL**: + :: + + some-list: + - + + :: + + some-list: + - string item + - + """ import yaml From 81763bdbf7751dcde6b01d407f492d7d72ef4608 Mon Sep 17 00:00:00 2001 From: Eric Almeida Date: Wed, 8 Nov 2023 21:12:07 -0300 Subject: [PATCH 3/4] Refactor function name to forbid-in-block-sequences, enable by default, and add test cases --- tests/rules/test_empty_values.py | 111 ++++++++++++++++++++++--------- yamllint/rules/empty_values.py | 25 ++++--- 2 files changed, 95 insertions(+), 41 deletions(-) diff --git a/tests/rules/test_empty_values.py b/tests/rules/test_empty_values.py index 3b93b925..653f218e 100644 --- a/tests/rules/test_empty_values.py +++ b/tests/rules/test_empty_values.py @@ -42,7 +42,8 @@ def test_disabled(self): def test_in_block_mappings_disabled(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'foo:\n', conf) self.check('---\n' @@ -51,7 +52,8 @@ def test_in_block_mappings_disabled(self): def test_in_block_mappings_single_line(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'implicitly-null:\n', conf, problem1=(2, 17)) self.check('---\n' @@ -63,7 +65,8 @@ def test_in_block_mappings_single_line(self): def test_in_block_mappings_all_lines(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'foo:\n' 'bar:\n' @@ -72,14 +75,16 @@ def test_in_block_mappings_all_lines(self): def test_in_block_mappings_explicit_end_of_document(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'foo:\n' '...\n', conf, problem1=(2, 5)) def test_in_block_mappings_not_end_of_document(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'foo:\n' 'bar:\n' @@ -87,7 +92,8 @@ def test_in_block_mappings_not_end_of_document(self): def test_in_block_mappings_different_level(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'foo:\n' ' bar:\n' @@ -95,7 +101,8 @@ def test_in_block_mappings_different_level(self): def test_in_block_mappings_empty_flow_mapping(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' 'braces: disable\n' 'commas: disable\n') self.check('---\n' @@ -107,14 +114,16 @@ def test_in_block_mappings_empty_flow_mapping(self): def test_in_block_mappings_empty_block_sequence(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'foo:\n' ' -\n', conf) def test_in_block_mappings_not_empty_or_explicit_null(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'foo:\n' ' bar:\n' @@ -137,7 +146,8 @@ def test_in_block_mappings_not_empty_or_explicit_null(self): def test_in_block_mappings_various_explicit_null(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n') + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'null-alias: ~\n', conf) self.check('---\n' @@ -147,7 +157,8 @@ def test_in_block_mappings_various_explicit_null(self): def test_in_block_mappings_comments(self): conf = ('empty-values: {forbid-in-block-mappings: true,\n' - ' forbid-in-flow-mappings: false}\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' 'comments: disable\n') self.check('---\n' 'empty: # comment\n' @@ -158,7 +169,8 @@ def test_in_block_mappings_comments(self): def test_in_flow_mappings_disabled(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: false}\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: false}\n' 'braces: disable\n' 'commas: disable\n') self.check('---\n' @@ -175,7 +187,8 @@ def test_in_flow_mappings_disabled(self): def test_in_flow_mappings_single_line(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: true}\n' + ' forbid-in-flow-mappings: true,\n' + ' forbid-in-block-sequences: false}\n' 'braces: disable\n' 'commas: disable\n') self.check('---\n' @@ -201,7 +214,8 @@ def test_in_flow_mappings_single_line(self): def test_in_flow_mappings_multi_line(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: true}\n' + ' forbid-in-flow-mappings: true,\n' + ' forbid-in-block-sequences: false}\n' 'braces: disable\n' 'commas: disable\n') self.check('---\n' @@ -226,7 +240,8 @@ def test_in_flow_mappings_multi_line(self): def test_in_flow_mappings_various_explicit_null(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: true}\n' + ' forbid-in-flow-mappings: true,\n' + ' forbid-in-block-sequences: false}\n' 'braces: disable\n' 'commas: disable\n') self.check('---\n' @@ -240,7 +255,8 @@ def test_in_flow_mappings_various_explicit_null(self): def test_in_flow_mappings_comments(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' - ' forbid-in-flow-mappings: true}\n' + ' forbid-in-flow-mappings: true,\n' + ' forbid-in-block-sequences: false}\n' 'braces: disable\n' 'commas: disable\n' 'comments: disable\n') @@ -259,12 +275,10 @@ def test_in_flow_mappings_comments(self): problem2=(7, 9), problem3=(10, 5)) - def test_in_list_items_disabled(self): + def test_in_block_sequences_disabled(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' ' forbid-in-flow-mappings: false,\n' - ' forbid-in-list-items: false}\n' - 'braces: disable\n' - 'commas: disable\n') + ' forbid-in-block-sequences: false}\n') self.check('---\n' 'foo:\n' ' - bar\n' @@ -273,12 +287,10 @@ def test_in_list_items_disabled(self): 'foo:\n' ' -\n', conf) - def test_in_list_items_primative_item(self): + def test_in_block_sequences_primative_item(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' ' forbid-in-flow-mappings: false,\n' - ' forbid-in-list-items: true}\n' - 'braces: disable\n' - 'commas: disable\n') + ' forbid-in-block-sequences: true}\n') self.check('---\n' 'foo:\n' ' -\n', conf, @@ -296,14 +308,49 @@ def test_in_list_items_primative_item(self): problem=(5, 4)) self.check('---\n' 'foo:\n' - ' - null\n', conf) + ' - true\n', conf) - def test_in_list_items_various_explicit_null(self): + def test_in_block_sequences_complex_objects(self): conf = ('empty-values: {forbid-in-block-mappings: false,\n' ' forbid-in-flow-mappings: false,\n' - ' forbid-in-list-items: true}\n' - 'braces: disable\n' - 'commas: disable\n') + ' forbid-in-block-sequences: true}\n') + self.check('---\n' + 'foo:\n' + ' - a: 1\n', conf) + self.check('---\n' + 'foo:\n' + ' - a: 1\n' + ' -\n', conf, + problem=(4, 4)) + self.check('---\n' + 'foo:\n' + ' - a: 1\n' + ' b: 2\n' + ' -\n', conf, + problem=(5, 4)) + self.check('---\n' + 'foo:\n' + ' - a: 1\n' + ' - b: 2\n' + ' -\n', conf, + problem=(5, 4)) + self.check('---\n' + 'foo:\n' + ' - - a\n' + ' - b: 2\n' + ' -\n', conf, + problem=(5, 6)) + self.check('---\n' + 'foo:\n' + ' - - a\n' + ' - b: 2\n' + ' -\n', conf, + problem=(5, 4)) + + def test_in_block_sequences_various_explicit_null(self): + conf = ('empty-values: {forbid-in-block-mappings: false,\n' + ' forbid-in-flow-mappings: false,\n' + ' forbid-in-block-sequences: true}\n') self.check('---\n' 'foo:\n' ' - null\n', conf) @@ -311,7 +358,11 @@ def test_in_list_items_various_explicit_null(self): '- null\n', conf) self.check('---\n' 'foo:\n' - ' - bar: null\n', conf) + ' - bar: null\n' + ' - null\n', conf) self.check('---\n' '- null\n' '- null\n', conf) + self.check('---\n' + '- - null\n' + ' - null\n', conf) diff --git a/yamllint/rules/empty_values.py b/yamllint/rules/empty_values.py index 3be0af62..6c8902b8 100644 --- a/yamllint/rules/empty_values.py +++ b/yamllint/rules/empty_values.py @@ -21,7 +21,7 @@ * Use ``forbid-in-block-mappings`` to prevent empty values in block mappings. * Use ``forbid-in-flow-mappings`` to prevent empty values in flow mappings. -* Use ``forbid-in-list-items`` to prevent empty values in lists. +* Use ``forbid-in-block-sequences`` to prevent empty values in block sequences. .. rubric:: Default values (when enabled) @@ -31,7 +31,7 @@ empty-values: forbid-in-block-mappings: true forbid-in-flow-mappings: true - forbid-in-list-items: false + forbid-in-block-sequences: true .. rubric:: Examples @@ -74,23 +74,26 @@ {a: 1, b:, c: 3} -#. With ``empty-values: {forbid-in-list-items: true}`` +#. With ``empty-values: {forbid-in-block-sequences: true}`` the following code snippet would **PASS**: :: - some-list: + some-sequence: - string item + :: + + some-sequence: + - null the following code snippets would **FAIL**: :: - some-list: + some-sequence: - - :: - some-list: + some-sequence: - string item - @@ -105,10 +108,10 @@ TYPE = 'token' CONF = {'forbid-in-block-mappings': bool, 'forbid-in-flow-mappings': bool, - 'forbid-in-list-items': bool} + 'forbid-in-block-sequences': bool} DEFAULT = {'forbid-in-block-mappings': True, 'forbid-in-flow-mappings': True, - 'forbid-in-list-items': False} + 'forbid-in-block-sequences': True} def check(conf, token, prev, next, nextnext, context): @@ -127,9 +130,9 @@ def check(conf, token, prev, next, nextnext, context): token.end_mark.column + 1, 'empty value in flow mapping') - if conf['forbid-in-list-items']: + if conf['forbid-in-block-sequences']: if isinstance(token, yaml.BlockEntryToken) and isinstance(next, ( yaml.KeyToken, yaml.BlockEndToken, yaml.BlockEntryToken)): yield LintProblem(token.start_mark.line + 1, token.end_mark.column + 1, - 'empty value in list items') + 'empty value in block sequence') From 62f54e297cc7c73a8c9063f943350233701fc242 Mon Sep 17 00:00:00 2001 From: Eric Almeida Date: Wed, 8 Nov 2023 21:32:04 -0300 Subject: [PATCH 4/4] Fix: linter docstring rule empty_values --- yamllint/rules/empty_values.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yamllint/rules/empty_values.py b/yamllint/rules/empty_values.py index 6c8902b8..6c8328b7 100644 --- a/yamllint/rules/empty_values.py +++ b/yamllint/rules/empty_values.py @@ -81,6 +81,7 @@ some-sequence: - string item + :: some-sequence: @@ -91,6 +92,7 @@ some-sequence: - + :: some-sequence: