Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ansible-lint for openSUSE:Factory checked in at 2026-10-13 17:46:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ansible-lint (Old) and /work/SRC/openSUSE:Factory/.ansible-lint.new.3698736 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ansible-lint" Tue Oct 13 17:46:01 2026 rev:84 rq:1384485 version:26.10.0 Changes: -------- --- /work/SRC/openSUSE:Factory/ansible-lint/ansible-lint.changes 2026-09-23 14:37:23.611419988 +0200 +++ /work/SRC/openSUSE:Factory/.ansible-lint.new.3698736/ansible-lint.changes 2026-10-13 17:46:14.629574638 +0200 @@ -1,0 +2,10 @@ +Tue Oct 13 04:43:46 UTC 2026 - Johannes Kastl <[email protected]> + +- update to 26.10.0: + * fix: respect skip_list for yaml[comments] during --fix in #5177 + * Fix/scorecard security improvements v2 in #5194 + * fix: correctly match symlinked PATH entries in path_inject() in + #5205 + * fix(security): update dependencies [SECURITY] in #5206 + +------------------------------------------------------------------- Old: ---- ansible-lint-26.9.0.tar.gz New: ---- ansible-lint-26.10.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ansible-lint.spec ++++++ --- /var/tmp/diff_new_pack.yYJ9vt/_old 2026-10-13 17:46:15.560613656 +0200 +++ /var/tmp/diff_new_pack.yYJ9vt/_new 2026-10-13 17:46:15.563613782 +0200 @@ -39,7 +39,7 @@ %global lib_name ansiblelint Name: ansible-lint -Version: 26.9.0 +Version: 26.10.0 Release: 0%{?dist} Summary: Best practices checker for Ansible License: MIT ++++++ ansible-lint-26.9.0.tar.gz -> ansible-lint-26.10.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/.git_archival.txt new/ansible-lint-26.10.0/.git_archival.txt --- old/ansible-lint-26.9.0/.git_archival.txt 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/.git_archival.txt 2026-10-07 06:26:51.000000000 +0200 @@ -1,4 +1,4 @@ -node: e7f397ad6dfa20d274afa17cd7bbedd84ed136f5 -node-date: 2026-09-20T20:29:30+05:30 +node: fac2489f3e4ccffa83a40b839770abbf4ab52327 +node-date: 2026-10-07T09:56:51+05:30 describe-name: v26 -ref-names: HEAD -> main, tag: v26.9.0, tag: v26 +ref-names: HEAD -> main, tag: v26.10.0, tag: v26 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/.github/workflows/ack.yml new/ansible-lint-26.10.0/.github/workflows/ack.yml --- old/ansible-lint-26.9.0/.github/workflows/ack.yml 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/.github/workflows/ack.yml 2026-10-07 06:26:51.000000000 +0200 @@ -6,6 +6,8 @@ pull_request_target: types: [opened, labeled, unlabeled, synchronize] +permissions: {} + jobs: ack: uses: ansible/team-devtools/.github/workflows/ack.yml@main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/.github/workflows/push.yml new/ansible-lint-26.10.0/.github/workflows/push.yml --- old/ansible-lint-26.9.0/.github/workflows/push.yml 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/.github/workflows/push.yml 2026-10-07 06:26:51.000000000 +0200 @@ -8,6 +8,9 @@ - "releases/**" - "stable/**" +permissions: + contents: read + jobs: ack: uses: ansible/team-devtools/.github/workflows/push.yml@main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/.github/workflows/redirects.yml new/ansible-lint-26.10.0/.github/workflows/redirects.yml --- old/ansible-lint-26.9.0/.github/workflows/redirects.yml 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/.github/workflows/redirects.yml 2026-10-07 06:26:51.000000000 +0200 @@ -13,13 +13,20 @@ # Manually triggered using GitHub's UI workflow_dispatch: +permissions: + contents: read + jobs: docs: environment: release runs-on: ubuntu-24.04 + permissions: + contents: read steps: - - uses: actions/checkout@v7 - - uses: actions/setup-python@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - name: Upgrade Python toolchain run: python3 -m pip install --upgrade pip setuptools wheel diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/.github/workflows/release.yml new/ansible-lint-26.10.0/.github/workflows/release.yml --- old/ansible-lint-26.9.0/.github/workflows/release.yml 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/.github/workflows/release.yml 2026-10-07 06:26:51.000000000 +0200 @@ -6,17 +6,18 @@ types: [published] workflow_dispatch: +permissions: + contents: read + jobs: # https://github.com/marketplace/actions/actions-tagger actions-tagger: needs: pypi # do not move the mobile tag until we publish runs-on: windows-latest permissions: - # Give the default GITHUB_TOKEN write permission. - # https://github.blog/changelog/2023-02-02-github-actions-updating-the-default-github_token-permissions-to-read-only/ contents: write steps: - - uses: Actions-R-Us/actions-tagger@latest + - uses: Actions-R-Us/actions-tagger@330ddfac760021349fef7ff62b372f2f691c20fb # v2.0.3 with: token: "${{ github.token }}" # Do not activate latest tag because it seems to affect RTD builds @@ -26,6 +27,7 @@ environment: release runs-on: ubuntu-24.04 permissions: + contents: read id-token: write env: @@ -35,7 +37,7 @@ steps: - name: Switch to using latest Python by default - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.14" @@ -43,7 +45,7 @@ run: python3 -m pip install --user "tox>=4.0.0" - name: Check out src from Git - uses: actions/checkout@v7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 # needed by setuptools-scm submodules: true @@ -54,4 +56,4 @@ - name: Publish to pypi.org if: >- # "create" workflows run separately from "push" & "pull_request" github.event_name == 'release' - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/src/ansiblelint/__main__.py new/ansible-lint-26.10.0/src/ansiblelint/__main__.py --- old/ansible-lint-26.9.0/src/ansiblelint/__main__.py 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/src/ansiblelint/__main__.py 2026-10-07 06:26:51.000000000 +0200 @@ -561,6 +561,11 @@ # does this as part of the ansible detection. paths = [x for x in os.environ.get("PATH", "").split(os.pathsep) if x] + # Build a resolved view of PATH so symlinked entries correctly match + # against resolved candidate paths below (fixes false "PATH altered" + # warnings when a venv is reached through a symlinked directory). + resolved_paths = {str(Path(p).expanduser().resolve()) for p in paths} + # Expand ~ in PATH as it known to break many tools expanded = False for idx, path in enumerate(paths): @@ -587,6 +592,7 @@ pipx_path = os.environ.get("PIPX_HOME", "pipx") if ( str(py_path) not in paths + and str(py_path) not in resolved_paths and (py_path / "ansible").exists() and pipx_path not in str(py_path) ): @@ -596,7 +602,11 @@ if own_location: own_location = os.path.realpath(own_location) parent = Path(own_location).parent - if (parent / "ansible").exists() and str(parent) not in paths: + if ( + (parent / "ansible").exists() + and str(parent) not in paths + and str(parent) not in resolved_paths + ): inject_paths.append(str(parent)) if not os.environ.get("PYENV_VIRTUAL_ENV", None): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/src/ansiblelint/schemas/__store__.json new/ansible-lint-26.10.0/src/ansiblelint/schemas/__store__.json --- old/ansible-lint-26.9.0/src/ansiblelint/schemas/__store__.json 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/src/ansiblelint/schemas/__store__.json 2026-10-07 06:26:51.000000000 +0200 @@ -40,7 +40,7 @@ "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/play-argspec.json" }, "playbook": { - "etag": "3a703ff75b757c2f62a9322ce67cd10f6d53e3c9b6d2a44c80f6c368b136ed3b", + "etag": "b906f9b7f7be252443f2a34267bcd3d4722dff9cd572ddf04753e0c75b13aa91", "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/playbook.json" }, "requirements": { @@ -60,7 +60,7 @@ "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/tasks.json" }, "vars": { - "etag": "76e5ac2daa6465ba16c3a566307876cf6d74ff433cf7fd0836bc4a9e389b668a", + "etag": "b6668731573a5ead47af724e144dda6e3c740364417c44aa248506a641d30efc", "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/vars.json" } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/src/ansiblelint/transformer.py new/ansible-lint-26.10.0/src/ansiblelint/transformer.py --- old/ansible-lint-26.9.0/src/ansiblelint/transformer.py 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/src/ansiblelint/transformer.py 2026-10-07 06:26:51.000000000 +0200 @@ -51,6 +51,10 @@ """Initialize a Transformer instance.""" self.write_set = self.effective_write_set(options.write_list) self.write_exclude_set = self.effective_write_set(options.write_exclude_list) + self.fix_comment_spaces = not any( + tag in (options.skip_list or []) or tag in (options.warn_list or []) + for tag in ("yaml[comments]", "yaml") + ) self.warn_list = set(options.warn_list) self.matches: list[MatchError] = result.matches @@ -118,6 +122,7 @@ yaml = FormattedYAML( # Ansible only uses YAML 1.1, but others files should use newer 1.2 (ruamel.yaml defaults to 1.2) version=(1, 1) if file.is_owned_by_ansible() else None, + fix_comment_spaces=self.fix_comment_spaces, ) ruamel_data = yaml.load(data) @@ -184,6 +189,15 @@ ): match.yaml_path = get_path_to_task(file, match.lineno, data) + # When yaml[comments] is in warn_list the emitter won't apply + # comment-spacing fixes, so don't mark those matches as fixed — + # doing so would silently hide the unresolved warning. + if match.tag == "yaml[comments]" and not self.fix_comment_spaces: + _logger.debug( + "%s %s (comment spacing disabled)", self.FIX_NA_MSG, match_id + ) + continue + _logger.debug("%s %s", self.FIX_APPLY_MSG, match_id) try: match.rule.transform(match, file, data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/src/ansiblelint/yaml_utils.py new/ansible-lint-26.10.0/src/ansiblelint/yaml_utils.py --- old/ansible-lint-26.9.0/src/ansiblelint/yaml_utils.py 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/src/ansiblelint/yaml_utils.py 2026-10-07 06:26:51.000000000 +0200 @@ -624,6 +624,10 @@ _in_empty_flow_map = False + # Set to False when yaml[comments] is in skip_list to avoid reformatting + # comments even while other fixes are applied. See github issue #5048. + fix_comment_spaces = True + _flow_collection_styles: tuple[bool, ...] = () _previous_event_ended_flow_collection = False _pending_flow_collection_separator = False @@ -864,27 +868,28 @@ # Preserve a separating blank line after a flow collection. Pure # whitespace comments elsewhere remain removed by the formatter. value = "\n" if self._previous_event_ended_flow_collection else "" - elif ( + elif self.fix_comment_spaces and ( pre and not value.strip() and isinstance(self.event, ruamel.yaml.events.MappingStartEvent) ): value = self._re_repeat_blank_lines.sub("", value) - elif pre: + elif self.fix_comment_spaces and pre: # preserve content in pre comment, collapsing runs of blank lines # down to a single blank line. value = self._re_repeat_blank_lines.sub("\n\n", value) - else: + elif self.fix_comment_spaces: # single blank lines in post comments value = self._re_repeat_blank_lines.sub("\n\n", value) - value = self._re_missing_comment_space.sub(r"\1 ", value) - - comment.value = value - - # make sure that the eol comment only has one space before it. - if comment.column > self.column + 1 and not pre: - comment.column = self.column + 1 + if self.fix_comment_spaces: + value = self._re_missing_comment_space.sub(r"\1 ", value) + comment.value = value + # make sure that the eol comment only has one space before it. + if comment.column > self.column + 1 and not pre: + comment.column = self.column + 1 + else: + comment.value = value return super().write_comment(comment, pre) @@ -918,6 +923,7 @@ plug_ins: list[str] | None = None, version: tuple[int, int] | None = None, config: dict[str, bool | int | str] | None = None, + fix_comment_spaces: bool = True, ): """Return a configured ``ruamel.yaml.YAML`` instance. @@ -1012,6 +1018,16 @@ # If someone doesn't want our FormattedEmitter, they can change it. self.Emitter = FormattedEmitter + # When yaml[comments] is in skip_list, disable the comment-space + # reformatting in the emitter so --fix doesn't touch comments even + # while applying other transforms (see github issue #5048). + if not fix_comment_spaces: + + class _FormattedEmitterNoCommentFix(FormattedEmitter): + fix_comment_spaces = False + + self.Emitter = _FormattedEmitterNoCommentFix + # ignore invalid preferred_quote setting if preferred_quote in ['"', "'"]: FormattedEmitter.preferred_quote = preferred_quote diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/test/test_path_inject.py new/ansible-lint-26.10.0/test/test_path_inject.py --- old/ansible-lint-26.9.0/test/test_path_inject.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-lint-26.10.0/test/test_path_inject.py 2026-10-07 06:26:51.000000000 +0200 @@ -0,0 +1,57 @@ +"""Tests for path_inject() handling of symlinked PATH entries.""" + +import os +import sys +from pathlib import Path + +import pytest + +from ansiblelint.__main__ import path_inject + + +def _make_venv_with_symlink(tmp_path: Path) -> tuple[Path, Path]: + real_bin = tmp_path / "real" / "venv" / "bin" + real_bin.mkdir(parents=True) + ansible = real_bin / "ansible" + ansible.touch() + ansible.chmod(0o755) + (tmp_path / "link").symlink_to(tmp_path / "real", target_is_directory=True) + return real_bin, tmp_path / "link" / "venv" / "bin" + + [email protected](sys.platform == "win32", reason="symlinks") +def test_path_inject_symlinked_path_entry( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + capsys: pytest.CaptureFixture[str], +) -> None: + """A venv bin reached through a symlink must not trigger a PATH warning.""" + real_bin, link_bin = _make_venv_with_symlink(tmp_path) + path_value = os.pathsep.join([str(link_bin), "/usr/bin"]) + monkeypatch.setenv("PATH", path_value) + monkeypatch.delenv("PYENV_VIRTUAL_ENV", raising=False) + monkeypatch.setattr(sys, "executable", str(real_bin / "python")) + + path_inject() + + assert "PATH altered to include" not in capsys.readouterr().err + assert os.environ["PATH"] == path_value + + [email protected](sys.platform == "win32", reason="symlinks") +def test_path_inject_symlinked_tilde_path_entry( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + capsys: pytest.CaptureFixture[str], +) -> None: + """A ~-prefixed PATH entry reached through a symlink must not be duplicated.""" + real_bin, _ = _make_venv_with_symlink(tmp_path) + monkeypatch.setenv("HOME", str(tmp_path)) + monkeypatch.setenv("PATH", os.pathsep.join(["~/link/venv/bin", "/usr/bin"])) + monkeypatch.delenv("PYENV_VIRTUAL_ENV", raising=False) + monkeypatch.setattr(sys, "executable", str(real_bin / "python")) + + path_inject() + + assert "PATH altered to include" not in capsys.readouterr().err + assert os.environ["PATH"].split(os.pathsep).count(str(real_bin)) == 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/test/test_transformer.py new/ansible-lint-26.10.0/test/test_transformer.py --- old/ansible-lint-26.9.0/test/test_transformer.py 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/test/test_transformer.py 2026-10-07 06:26:51.000000000 +0200 @@ -813,3 +813,130 @@ log_2 = f"{transformer.DUMP_MSG} {TransformTests.rewrite_part()}" assert logs[2].message == log_2 assert logs[2].levelname == "DEBUG" + + +def _run_transformer_on_content( + content: str, + tmp_path: Path, + rules: RulesCollection, + *, + skip_list: list[str] | None = None, + warn_list: list[str] | None = None, +) -> str: + """Write content to a tmp playbook, run Transformer.run(), return output.""" + tmp_path.mkdir(parents=True, exist_ok=True) + playbook = tmp_path / "test_comments.yml" + playbook.write_text(content) + + opts = Options() + opts.write_list = ["yaml"] + opts.lintables = [str(playbook)] + if skip_list: + opts.skip_list = skip_list + if warn_list: + opts.warn_list = warn_list + + result = get_matches(rules=rules, options=opts) + transformer = Transformer(result, opts) + transformer.run() + return playbook.read_text() + + +# A minimal playbook with a mis-spaced inline comment (#test-comment) +_PLAYBOOK_WITH_BAD_COMMENT = """\ +--- +- name: Play + hosts: localhost + tasks: + - name: Task #test-comment + ansible.builtin.debug: + msg: hello +""" + + +def test_transformer_respects_yaml_comments_skip_list( + tmp_path: Path, + default_rules_collection: RulesCollection, +) -> None: + """End-to-end: yaml[comments] in skip_list/warn_list prevents comment reformatting. + + When yaml[comments] is in skip_list or warn_list, Transformer.run() must not + add a space after '#' in inline comments. Without any skip, it must fix them. + See https://github.com/ansible/ansible-lint/issues/5048. + """ + # --- 1. Default (no skip/warn): fix_comment_spaces=True, comment IS fixed --- + out_default = _run_transformer_on_content( + _PLAYBOOK_WITH_BAD_COMMENT, + tmp_path / "default", + default_rules_collection, + ) + assert "# test-comment" in out_default, "Default run must fix the comment spacing" + assert "#test-comment" not in out_default, "Default run must not leave unfixed form" + + # --- 2. yaml[comments] in skip_list: comment must NOT be touched --- + out_skip = _run_transformer_on_content( + _PLAYBOOK_WITH_BAD_COMMENT, + tmp_path / "skip", + default_rules_collection, + skip_list=["yaml[comments]"], + ) + assert "#test-comment" in out_skip, "skip_list run must leave comment unchanged" + assert "# test-comment" not in out_skip, "skip_list run must not add a space" + + # --- 3. yaml in skip_list: same protection via parent tag --- + out_skip_yaml = _run_transformer_on_content( + _PLAYBOOK_WITH_BAD_COMMENT, + tmp_path / "skip_yaml", + default_rules_collection, + skip_list=["yaml"], + ) + assert "#test-comment" in out_skip_yaml + assert "# test-comment" not in out_skip_yaml + + # --- 4. yaml[comments] in warn_list: same protection --- + out_warn = _run_transformer_on_content( + _PLAYBOOK_WITH_BAD_COMMENT, + tmp_path / "warn", + default_rules_collection, + warn_list=["yaml[comments]"], + ) + assert "#test-comment" in out_warn + assert "# test-comment" not in out_warn + + +def test_transformer_warn_list_yaml_comments_not_marked_fixed( + tmp_path: Path, + default_rules_collection: RulesCollection, +) -> None: + """yaml[comments] matches in warn_list must not be silently marked fixed. + + When fix_comment_spaces=False (yaml[comments] in warn_list), the emitter + does not apply the spacing fix, so Transformer._do_transforms must skip + the transform call entirely. The match must remain unfixed so it is still + visible in the rendered output rather than silently disappearing. + See https://github.com/ansible/ansible-lint/issues/5048. + """ + playbook = tmp_path / "test.yml" + playbook.write_text(_PLAYBOOK_WITH_BAD_COMMENT) + + opts = Options() + opts.write_list = ["yaml"] + opts.warn_list = ["yaml[comments]"] + opts.lintables = [str(playbook)] + + result = get_matches(rules=default_rules_collection, options=opts) + transformer = Transformer(result, opts) + + # Capture the matches before running so we can inspect fixed state after + yaml_comment_matches = [m for m in result.matches if m.tag == "yaml[comments]"] + + transformer.run() + + # None of the yaml[comments] matches should have been marked as fixed — + # the spacing violation is still present on disk. + assert yaml_comment_matches, "Expected at least one yaml[comments] match" + for match in yaml_comment_matches: + assert not match.fixed, ( + f"yaml[comments] match at {match.filename}:{match.lineno} was " + "incorrectly marked fixed while fix_comment_spaces=False" + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/test/test_yaml_utils.py new/ansible-lint-26.10.0/test/test_yaml_utils.py --- old/ansible-lint-26.9.0/test/test_yaml_utils.py 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/test/test_yaml_utils.py 2026-10-07 06:26:51.000000000 +0200 @@ -1128,3 +1128,40 @@ assert " name: my_name" in output_anchor assert " name: my_name" not in output_anchor + + +def test_formatted_yaml_fix_comment_spaces_enabled() -> None: + """Verify that comment spacing is fixed when fix_comment_spaces=True.""" + yaml = ansiblelint.yaml_utils.FormattedYAML(fix_comment_spaces=True) + + # EOL inline comments missing a space after '#' - valid YAML + input_with_bad_spacing = ( + "---\nkey: value #bad spacing\nother: nested #also missing\n" + ) + data = yaml.load(input_with_bad_spacing) + output = yaml.dumps(data) + + # With fix_comment_spaces=True the leading '#' must be followed by a space + assert "#bad spacing" not in output + assert "# bad spacing" in output + assert "#also missing" not in output + assert "# also missing" in output + + +def test_formatted_yaml_fix_comment_spaces_disabled() -> None: + """Verify that comment spacing is preserved when fix_comment_spaces=False.""" + yaml = ansiblelint.yaml_utils.FormattedYAML(fix_comment_spaces=False) + + # Same input - fix_comment_spaces=False means the '#' must NOT be touched + input_with_bad_spacing = ( + "---\nkey: value #bad spacing\nother: nested #also missing\n" + ) + data = yaml.load(input_with_bad_spacing) + output = yaml.dumps(data) + + # With fix_comment_spaces=False the original spacing must be preserved + assert "#bad spacing" in output + assert "#also missing" in output + # Negative: the fixer must not have added spaces + assert "# bad spacing" not in output + assert "# also missing" not in output diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-26.9.0/uv.lock new/ansible-lint-26.10.0/uv.lock --- old/ansible-lint-26.9.0/uv.lock 2026-09-20 16:59:30.000000000 +0200 +++ new/ansible-lint-26.10.0/uv.lock 2026-10-07 06:26:51.000000000 +0200 @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.15'", @@ -105,6 +105,7 @@ [[package]] name = "ansible-lint" source = { editable = "." } +default-groups = "all" dependencies = [ { name = "ansible-compat" }, { name = "ansible-core", version = "2.16.19", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, @@ -3863,28 +3864,28 @@ [[package]] name = "uv" -version = "0.12.10" +version = "0.12.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/48/92/167ad4b0795530383a84560dc8bc8c0afab6b6fb10baba34b2a257fa6894/uv-0.12.10.tar.gz", hash = "sha256:27e8350faffb35d8ecaa5ed39236709809bb9a883f1d11d13c0964d6051b2384", size = 7144864, upload-time = "2026-09-04T23:14:21.301Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/f5/34435c1d9ee52d38bda1d7d2948d8ef48a9ac9ec79e6fbfd81ced8b0ad19/uv-0.12.23.tar.gz", hash = "sha256:e952162a5be6847deaccf3fd5b41a628506fd9ff1ea4363b8c975bd6f927d832", size = 7197708, upload-time = "2026-10-03T17:33:01.864Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/d1/b3752f00e67e5bf141adec0225c62a17c1cf3fb524db463c541c080f1237/uv-0.12.10-py3-none-linux_armv6l.whl", hash = "sha256:efbbc586d40014b9dd3bc37a2ad5803d12919458f0f9d16f122db5d91626f5ab", size = 22182923, upload-time = "2026-09-04T23:13:31.502Z" }, - { url = "https://files.pythonhosted.org/packages/ab/4d/ef846ec0a4dfa8d4f47b96a87a1e331143be5a045c28c8b4b0374946455f/uv-0.12.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7e3a70d9dff95481afccd7d41e7ec42fdc230d53487b3e7e633f9b35610401b5", size = 20494379, upload-time = "2026-09-04T23:13:34.339Z" }, - { url = "https://files.pythonhosted.org/packages/04/2e/5614e9a940fe1bf291342410b2cde9fe35a1430135ae7434ea8fd67033f8/uv-0.12.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5dc26c73826d2119292d49d71c5a9d5ba9dd97dd02459d816b8226f47f3dc6bd", size = 17238363, upload-time = "2026-09-04T23:13:36.905Z" }, - { url = "https://files.pythonhosted.org/packages/d1/03/e71936935b8ac26390b280e102b9db823e90adb1134f7e226538054fdece/uv-0.12.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bd0afae6918795c6a61a649e64d735e339f3d62f8310235da6f19eb3f66f323b", size = 21590025, upload-time = "2026-09-04T23:13:39.588Z" }, - { url = "https://files.pythonhosted.org/packages/b2/c0/c6388a722fb9db8adf8ec8eca762547b5a06ccbd1176571dc584636af5f1/uv-0.12.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:c1fd0fcabc18dccaf541ca44a061c245045c937bec75c0491e94d59cd33ca97f", size = 21677222, upload-time = "2026-09-04T23:13:42.218Z" }, - { url = "https://files.pythonhosted.org/packages/9d/c6/96698aed29f25ff289b28b6312c72e260c56f7e1de2e3f690788bddea19e/uv-0.12.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de4b06934bd025ceeeb48af5c6f9a82407a2fe2b5b35e456cfb3198ef5029de0", size = 21712683, upload-time = "2026-09-04T23:13:44.927Z" }, - { url = "https://files.pythonhosted.org/packages/df/98/5871a2bff93bd6118ae877b874a09202d39e2831af37f56e2070d5c4bc87/uv-0.12.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b610e8cf7c6d51dc119d352e699b674534d0de327b4d2a67eb5d71ec364b8970", size = 22331081, upload-time = "2026-09-04T23:13:47.833Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b6/d690f34901bdc5094645cf75a00381cfb8f1f28ee87b7089af761094bb6f/uv-0.12.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f43c06b19137bb05877b0ec59c4932878db5d1aeb6f7b5c33259c22e0359c4fe", size = 23785643, upload-time = "2026-09-04T23:13:51.111Z" }, - { url = "https://files.pythonhosted.org/packages/90/da/168a8c69f60b9a2c90afb0b9211911ca42a81300c098d545da911bd4ef8f/uv-0.12.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0334577671a65b621faddfdf5f9e9dd4eb08eaa7231c4405c4a7f4f17d224d9f", size = 23337759, upload-time = "2026-09-04T23:13:54.163Z" }, - { url = "https://files.pythonhosted.org/packages/f0/41/f0e14ba1f881f7126152dcaf04119b3a2bd7566ba1cac1d22834bd134cbf/uv-0.12.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7d6248ad9f2d282fea795f248da8fa666ab382df50d8385bd98e01049440a0c", size = 19978237, upload-time = "2026-09-04T23:13:56.994Z" }, - { url = "https://files.pythonhosted.org/packages/7a/20/acebfb5fc01b29cce5e68b4824fa451d5fb1e569bb2579bcc7233583a894/uv-0.12.10-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:5c0bcf0598742eb417f1aa41ec82f0d89bd7b7f42d0a519bea495a9419d8d8ee", size = 19402684, upload-time = "2026-09-04T23:13:59.579Z" }, - { url = "https://files.pythonhosted.org/packages/49/ee/c40dc8b7b143a6f7843994b1b8a13aa8859d8404973704cd6bad7a26ac8d/uv-0.12.10-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:0ac914e9750bb1de2518d444cc1cff084f4eff3eefe9cdd5814b775443a16df1", size = 22450726, upload-time = "2026-09-04T23:14:02.316Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ec/b5df49f571b58e694ca8c3ddadd89939036ac0fe7ddaadc7600225ea8585/uv-0.12.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:46ca83d33bf87a67d0c5aa5b64f5576fc5c8e700a0ecf4900d409f8a1a1c9810", size = 22571602, upload-time = "2026-09-04T23:14:05.088Z" }, - { url = "https://files.pythonhosted.org/packages/4a/3e/f0335142e8a4c6ddc5117dcc9b5fd55c83cdd8e20a7f3be9584282dbfb64/uv-0.12.10-py3-none-musllinux_1_1_i686.whl", hash = "sha256:c49cd1f6e5ded1bd844119da8b184d5c044ae51441c476af2382fdb8af99edb8", size = 21499938, upload-time = "2026-09-04T23:14:08.109Z" }, - { url = "https://files.pythonhosted.org/packages/98/3e/991f08fcab1706175ae30eda6ef483223511679c56fe1032b919ca3ea391/uv-0.12.10-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a34e1be296e6e30fdbfee9b84a45d082ce7df4dd4e588ebcfc44249505c10f02", size = 22879435, upload-time = "2026-09-04T23:14:11.1Z" }, - { url = "https://files.pythonhosted.org/packages/c4/80/8db01aabf9937cbc228003392ee9fe542c4dad5c3c5b26f2e1f136d8e463/uv-0.12.10-py3-none-win32.whl", hash = "sha256:f7f2bc56fbd367b1066e8461a82e51e8886bbab52b1f8d1793af8ce52232348c", size = 19873629, upload-time = "2026-09-04T23:14:13.755Z" }, - { url = "https://files.pythonhosted.org/packages/a6/88/e980985d93283c546374b6b9dfa486a28091c4c056226711e31bb0f722d1/uv-0.12.10-py3-none-win_amd64.whl", hash = "sha256:2ad71395c31b5db20c56327f62ee0299f75833308d4413284aba87324d092afa", size = 18084435, upload-time = "2026-09-04T23:14:16.323Z" }, - { url = "https://files.pythonhosted.org/packages/84/10/fa542546044f783060d09a624f9964b595c0a0713cf2d89ade69c6667d8b/uv-0.12.10-py3-none-win_arm64.whl", hash = "sha256:4f097c6b7f63eceb3faf5102009f9a8cc22fd7d8a341858d2fd540f46a592f7a", size = 19598033, upload-time = "2026-09-04T23:14:18.829Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/ed4bcd2fbebe19d613412d02053af44809d02a1204cb6cf0a7a9af7a02fa/uv-0.12.23-py3-none-linux_armv6l.whl", hash = "sha256:8f021dfbe5b6081021dd47fd8372cfba386fc5d39161e73d4f33cff90ce1760c", size = 22770792, upload-time = "2026-10-03T17:31:15.723Z" }, + { url = "https://files.pythonhosted.org/packages/01/15/a2514d061b92d4b7c0ebefc3da51f3ff5a528e9f4c067ea2cf48c5573e5a/uv-0.12.23-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:4951286e68f116fa41897ecf8e248cc2836cb013be6d4f37afae4049f9ef4df7", size = 21459315, upload-time = "2026-10-03T17:31:18.824Z" }, + { url = "https://files.pythonhosted.org/packages/23/e9/b75db33954e985a763bd3277a477cabd551aaba7d08872b22400838dace2/uv-0.12.23-py3-none-macosx_11_0_arm64.whl", hash = "sha256:99197c022afbd1edd0a295e9fdac5078c61eddf2e77657a77294cfe8ea0d94b9", size = 17158822, upload-time = "2026-10-03T17:31:21.13Z" }, + { url = "https://files.pythonhosted.org/packages/39/77/ff15f878a215b543fd5aa05d2e3f939f3a2c46502ff58362eb5b51434af3/uv-0.12.23-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:895137194d242cc8075c3006288b485af54feeae68512f4ffc96f75b27543cc0", size = 22159208, upload-time = "2026-10-03T17:31:23.624Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2f/94bfc387f1c8169c2f82415f39a1a318d148104053b0efc70d3e15e72da6/uv-0.12.23-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:c4d236bb220856027ba8e28ef693cac472ee2a740a61faef1ac2001165c7b3d5", size = 22254708, upload-time = "2026-10-03T17:31:26.313Z" }, + { url = "https://files.pythonhosted.org/packages/a2/e2/42eba7023a4ab5496c17dacd27834cb0479fbccdadafe406cd4c187c5b33/uv-0.12.23-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:02f2a0fd1cb90b5fc06b52e8cbc3169bdc4e53804e9d66ba0ad516be767424f4", size = 22290428, upload-time = "2026-10-03T17:31:28.895Z" }, + { url = "https://files.pythonhosted.org/packages/19/cb/c68249501d913d3ef35596283acbe0af0f1b388e27c6b46aa402e968c55d/uv-0.12.23-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:855232fd95d456bd5ee17e262f73112967fbbb2803e745f1911c08ceb042e641", size = 23126626, upload-time = "2026-10-03T17:31:31.242Z" }, + { url = "https://files.pythonhosted.org/packages/14/fb/a6cf5eb99a37368ce8ad698ff406997897502eee5cacfd3d9805a02336ff/uv-0.12.23-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b70220be9056bd05908770179101a53687eb5c89f72a3edc1e20df0cd3f157c2", size = 24336288, upload-time = "2026-10-03T17:31:33.73Z" }, + { url = "https://files.pythonhosted.org/packages/c2/73/809af8a6fc97adfce7750b6b6d8c7fdf3e57c6ad40bc99e6b1228cdabe1e/uv-0.12.23-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08b2fc8e250efdfc1e47da0483f3e19f433bb0934282361817f61c0b19cb3674", size = 24092888, upload-time = "2026-10-03T17:31:36.747Z" }, + { url = "https://files.pythonhosted.org/packages/e5/83/85a6c63c24905af4924fddb11a499b934913f59a134248367a1ef1a4716f/uv-0.12.23-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565c6e2874dbeae86c02f3dea97255e878fec672659a73d4930c6b93fcab2fff", size = 20579564, upload-time = "2026-10-03T17:31:39.705Z" }, + { url = "https://files.pythonhosted.org/packages/df/50/84d0424b63718ac6f277c0b77206751e078a0adea16813320508a033e718/uv-0.12.23-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:9346c741175c7fc0d380f30fcfcb8d5e13f5f900b30536230c8d34208524e47a", size = 19859001, upload-time = "2026-10-03T17:31:42.397Z" }, + { url = "https://files.pythonhosted.org/packages/66/b7/03fe205f2f9af0dfa4467e561c7ecc620f03e7f7339d78d16fa38582e207/uv-0.12.23-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:b03b1c35b5f301e888671eb5d0e74b8789558905db1d411cb8e07ea4ec320268", size = 22701871, upload-time = "2026-10-03T17:31:44.804Z" }, + { url = "https://files.pythonhosted.org/packages/f3/17/26862297f6bece90d7f825f78a814580b36a9ac69a139f0385660e1a205c/uv-0.12.23-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5b07cbea635177da0d6b902bcde9ce0304c1fa5b49a37b27ef7aa021c5c31697", size = 22814543, upload-time = "2026-10-03T17:31:47.313Z" }, + { url = "https://files.pythonhosted.org/packages/da/04/31ae46fe42cbdc91b30162e5d430719911339a18f8ab3fb9126ee409fe29/uv-0.12.23-py3-none-musllinux_1_1_i686.whl", hash = "sha256:7a919e3420adf4cc03895b404af655c7229f646bffabbd9a16979683772a7d34", size = 22269008, upload-time = "2026-10-03T17:31:49.911Z" }, + { url = "https://files.pythonhosted.org/packages/71/b7/340260cf1a92017b271869764a68d9a019d796c4a7fa80c6c1bbcf5721eb/uv-0.12.23-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:11d18c1589d7907376b4f3fa31028e46cc609ac4b7d83eabc2b04cd8ca1433cc", size = 23541384, upload-time = "2026-10-03T17:31:52.416Z" }, + { url = "https://files.pythonhosted.org/packages/77/76/3a7ab3ab0bd8ab107b50fe981a3198188c8260e9b17b629e64899eca709b/uv-0.12.23-py3-none-win32.whl", hash = "sha256:f05c5ad8d6cb4b2659cb6368ed02c067539415b24a2b69effd8ada576fdbf303", size = 20101333, upload-time = "2026-10-03T17:31:54.811Z" }, + { url = "https://files.pythonhosted.org/packages/af/fd/816f4e8a76197312ec8037369e5b5c8a5ebde7aa118b6250259e031d3444/uv-0.12.23-py3-none-win_amd64.whl", hash = "sha256:fb8a4117a5224d73abe2204a1e744ae34b544f1b9a0b761576851deaa7215c12", size = 18138726, upload-time = "2026-10-03T17:31:57.498Z" }, + { url = "https://files.pythonhosted.org/packages/d9/74/1906f7f3f785fcf37a72b371d4ab58ec7193c5760923136cca1376209bc8/uv-0.12.23-py3-none-win_arm64.whl", hash = "sha256:9a65258535db432df51ca7d26338c01431820b94b634762f5718fc55895f974e", size = 19208424, upload-time = "2026-10-03T17:31:59.726Z" }, ] [[package]]
