From 1f472bc1443bf58446fe489994be5b2327334f69 Mon Sep 17 00:00:00 2001 From: Peter Ericson Date: Wed, 28 Sep 2016 21:56:45 +1000 Subject: [PATCH] Add rule: truthy, to forbid truthy values that are not quoted --- tests/rules/test_comments_indentation.py | 4 +- tests/rules/test_truthy.py | 40 +++++++++++++++++ tests/test_spec_examples.py | 2 + yamllint/conf/default.yaml | 2 + yamllint/conf/relaxed.yaml | 1 + yamllint/rules/__init__.py | 2 + yamllint/rules/truthy.py | 56 ++++++++++++++++++++++++ 7 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 tests/rules/test_truthy.py create mode 100644 yamllint/rules/truthy.py diff --git a/tests/rules/test_comments_indentation.py b/tests/rules/test_comments_indentation.py index 149b6b2..8e0fe40 100644 --- a/tests/rules/test_comments_indentation.py +++ b/tests/rules/test_comments_indentation.py @@ -102,13 +102,13 @@ class CommentsIndentationTestCase(RuleTestCase): ' a: 1\n' ' # b: 2\n' '# this object is useless\n' - 'obj2: no\n', conf) + 'obj2: "no"\n', conf) self.check('---\n' 'obj1:\n' ' a: 1\n' '# this object is useless\n' ' # b: 2\n' - 'obj2: no\n', conf, problem=(5, 3)) + 'obj2: "no"\n', conf, problem=(5, 3)) self.check('---\n' 'obj1:\n' ' a: 1\n' diff --git a/tests/rules/test_truthy.py b/tests/rules/test_truthy.py new file mode 100644 index 0000000..bb16a0c --- /dev/null +++ b/tests/rules/test_truthy.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016 Peter Ericson +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from tests.common import RuleTestCase + + +class TruthyTestCase(RuleTestCase): + rule_id = 'truthy' + + def test_disabled(self): + conf = 'truthy: disable' + self.check('---\n' + '1: True\n', conf) + self.check('---\n' + 'True: 1\n', conf) + + def test_enabled(self): + conf = 'truthy: enable\n' + self.check('---\n' + '1: True\n', conf, problem=(2, 4)) + self.check('---\n' + 'True: 1\n', conf, problem=(2, 1)) + self.check('---\n' + '1: "True"\n', conf) + self.check('---\n' + '"True": 1\n', conf) + diff --git a/tests/test_spec_examples.py b/tests/test_spec_examples.py index b23ad56..04d6ea7 100644 --- a/tests/test_spec_examples.py +++ b/tests/test_spec_examples.py @@ -119,6 +119,8 @@ conf_overrides = { 'example-8.22': ('indentation: disable\n'), 'example-10.1': ('colons: {max-spaces-before: 2}\n'), 'example-10.2': ('indentation: {indent-sequences: no}\n'), + 'example-10.8': ('truthy: disable\n'), + 'example-10.9': ('truthy: disable\n'), } files = os.listdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), diff --git a/yamllint/conf/default.yaml b/yamllint/conf/default.yaml index 9eec756..e4d720b 100644 --- a/yamllint/conf/default.yaml +++ b/yamllint/conf/default.yaml @@ -43,3 +43,5 @@ rules: new-lines: type: unix trailing-spaces: enable + truthy: + level: warning diff --git a/yamllint/conf/relaxed.yaml b/yamllint/conf/relaxed.yaml index f653757..fb2cdaf 100644 --- a/yamllint/conf/relaxed.yaml +++ b/yamllint/conf/relaxed.yaml @@ -26,3 +26,4 @@ rules: line-length: level: warning allow-non-breakable-inline-mappings: yes + truthy: disable diff --git a/yamllint/rules/__init__.py b/yamllint/rules/__init__.py index 6e82970..619e32d 100644 --- a/yamllint/rules/__init__.py +++ b/yamllint/rules/__init__.py @@ -31,6 +31,7 @@ from yamllint.rules import ( new_line_at_end_of_file, new_lines, trailing_spaces, + truthy, ) _RULES = { @@ -50,6 +51,7 @@ _RULES = { new_line_at_end_of_file.ID: new_line_at_end_of_file, new_lines.ID: new_lines, trailing_spaces.ID: trailing_spaces, + truthy.ID: truthy, } diff --git a/yamllint/rules/truthy.py b/yamllint/rules/truthy.py new file mode 100644 index 0000000..ef0e771 --- /dev/null +++ b/yamllint/rules/truthy.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016 Peter Ericson +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Use this rule to forbid truthy values that are not quoted. + +.. rubric:: Examples + +#. With ``truthy: {}`` + + the following code snippet would **PASS**: + :: + + object: {"True": 1, 1: "True"} + + the following code snippet would **FAIL**: + :: + + object: {True: 1, 1: True} +""" + +import yaml + +from yamllint.linter import LintProblem + +ID = 'truthy' +TYPE = 'token' +CONF = {} + +TRUTHY = ['YES', 'Yes', 'yes', + 'NO', 'No', 'no', + 'TRUE', 'True', # true is a boolean + 'FALSE', 'False', # false is a boolean + 'ON', 'On', 'on', + 'OFF', 'Off', 'off'] + + +def check(conf, token, prev, next, nextnext, context): + if isinstance(token, yaml.tokens.ScalarToken): + if token.value in TRUTHY and token.style is None: + yield LintProblem(token.start_mark.line + 1, + token.start_mark.column + 1, + "truthy value is not quoted")