From 754ccb9992445cbdab5d2f69003b567b889653e4 Mon Sep 17 00:00:00 2001 From: Sarath Francis Date: Fri, 26 Jun 2026 02:46:33 -0400 Subject: [PATCH] truthy: Don't carry %YAML version into the next document A `%YAML` directive applies only to the document it introduces, but the rule only reset its cached spec version on a `...` DocumentEndToken. When documents are separated by `---` alone (no `...`), the version of the previous document leaked into the next one, which has no directive of its own and should be treated as YAML 1.1: %YAML 1.2 --- on: 1 --- on: 2 The second `on` is a YAML 1.1 truthy value and should be flagged, but the leaked 1.2 version suppressed it. Reset the cached version when a `---` marker starts a document that has no directive of its own (a directive always precedes the marker), so every document is linted against its own spec version. --- tests/rules/test_truthy.py | 13 +++++++++++++ yamllint/rules/truthy.py | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/tests/rules/test_truthy.py b/tests/rules/test_truthy.py index e485d07..045ac07 100644 --- a/tests/rules/test_truthy.py +++ b/tests/rules/test_truthy.py @@ -186,6 +186,19 @@ class TruthyTestCase(RuleTestCase): 'boolean6: !!bool NO\n', conf) + def test_explicit_yaml_version_does_not_leak_to_next_document(self): + conf = ('truthy: enable\n' + 'document-start: disable\n') + # A %YAML directive only applies to the document it introduces. A + # following directive-less document (separated by '---', without + # '...') must be linted as YAML 1.1, where 'on' is truthy. + self.check('%YAML 1.2\n' + '---\n' + 'on: 1\n' + '---\n' + 'on: 2\n', + conf, problem1=(5, 1)) + def test_check_keys_disabled(self): conf = ('truthy:\n' ' allowed-values: []\n' diff --git a/yamllint/rules/truthy.py b/yamllint/rules/truthy.py index ff47a83..772dbea 100644 --- a/yamllint/rules/truthy.py +++ b/yamllint/rules/truthy.py @@ -168,6 +168,15 @@ def yaml_spec_version_for_document(context): def check(conf, token, prev, next, nextnext, context): if isinstance(token, yaml.tokens.DirectiveToken) and token.name == 'YAML': context['yaml_spec_version'] = token.value + elif isinstance(token, yaml.tokens.DocumentStartToken): + # A new document starts with this '---' marker. Its spec version is + # set by a directive, which always precedes the marker, so only forget + # the previous document's version when this document has no directive + # of its own -- otherwise the version would leak into a directive-less + # document separated by '---' (no '...' DocumentEndToken to reset it). + if not isinstance(prev, yaml.tokens.DirectiveToken): + context.pop('yaml_spec_version', None) + context.pop('bad_truthy_values', None) elif isinstance(token, yaml.tokens.DocumentEndToken): context.pop('yaml_spec_version', None) context.pop('bad_truthy_values', None)