609 Commits
Author SHA1 Message Date
Dimitri Papadopoulos bcb2e697f2 CI: Add support for Python 3.15 2026-07-20 10:03:59 +02:00
Dimitri Papadopoulos Orfanos 4d9fb87822 empty-values: Fix a typo in tests 2026-07-20 07:46:25 +02:00
Dimitri Papadopoulos 4dbd9c9a93 CI: Update GitHub Actions 2026-07-20 07:45:35 +02:00
Sarath Francis 754ccb9992 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.
2026-06-26 09:14:18 +02:00
Sarath Francis 122853fd37 linter: Report non-printable characters as a syntax error
Prevent yamllint crash upon unescaped (embedded) non-printable
characters:

    $ printf 'key: val\000ue\n' | yamllint -
    …
    yaml.reader.ReaderError: unacceptable character #x0000: special characters are not allowed
      in "<unicode string>", position 8

PyYAML raises a ReaderError for control characters such as NUL or DEL.
It is a YAMLError but, unlike the parser/scanner errors yamllint already
handles, not a MarkedYAMLError, so it escaped get_syntax_error() and
crashed the whole run. The same input also broke the token generator,
since BaseLoader() itself raises the error before any token is produced.

Catch ReaderError in get_syntax_error() and derive its line/column from
the flat buffer position, and tolerate it in token_or_comment_generator()
the same way ScannerError is, so cosmetic rules still run on the
printable lines. Such input is now reported as a regular syntax error.
2026-06-18 16:46:58 +02:00
Dimitri Papadopoulos Orfanos 30a25fe087 build: Use 'dev' dependency group for PEP 735 compliance
Only for development and build time dependencies, not run time dependencies
that are meant to be published with the package.
2026-02-23 08:56:09 +01:00
Adrien Vergé cba56bcde1 yamllint version 1.38.0 v1.38.0 2026-01-13 08:45:53 +01:00
Adrien Vergé 9dc506b5a1 Require pathspec ≥ 1.0.0 and follow Git's gitignore implementation
To follow Git's implementation, use `GitIgnoreSpec.from_lines(…)`. The
change for using this is Git allows including files from excluded
directories which directly contradicts the gitignore docs.

Thanks to Wong Hoi Sing Edison for the initial proposal.

Fixes https://github.com/adrienverge/yamllint/issues/800.
2026-01-13 08:42:00 +01:00
Adrien Vergé 73b9c0b542 Drop support for Python 3.9
Python 3.9 is officially "end-of-life" since 2025-10-31.

Note: Python 3.14 is officially supported since commit 823a96e "CI: Test
more versions of Python".
2025-12-03 08:38:01 +01:00
Adam Huganir 22d07edd49 indentation: Fix error message for check-multi-line-strings
A space character managed to escape while developing commit f63e56f.
2025-11-13 11:23:54 +01:00
Harsh Deep cfbfe9b076 README: Add Alpine Linux installation instructions
https://pkgs.alpinelinux.org/package/edge/community/x86/yamllint

Looks like this exists and is regularly updated. Adding this in the
quickstart guide can help people find it, especially in Docker contexts.
2025-11-13 08:52:11 +01:00
Adrien Vergé a3b3bb31bb README: Enhance wording of recursive directory lint 2025-11-13 08:49:38 +01:00
Ryan Finnie e3b72f585b quoted-strings: Add missing quote-type: consistent docs
Commit e3d54cc was missing a reference to the new `consistent`
functionality in `quote-type`.

Thanks to @kleinschrader in adrienverge/yamllint#776 for noticing this.
2025-09-30 18:17:53 +02:00
Ryan Finnie e3d54cc100 quoted-strings: Add quote-type: consistent
Strings in a document may be single or double, but must be consistent.
The first string found is assumed to be the canonical quote type, and
any subsequent quotes will be compared to it.

Closes: adrienverge/yamllint#763
2025-09-13 07:20:36 +02:00
Dimitri Papadopoulos 0b4ddc88c0 CI: Update GitHub Actions
Update actions to use Node.js 24:
- https://github.com/actions/checkout
- https://github.com/actions/setup-python

Fix a bug:
- https://github.com/actions/download-artifact
2025-09-08 16:01:29 +02:00
Dimitri Papadopoulos Orfanos 866f805cbf build: Remove license-files from pyproject.toml
This reverts commit 0cb7b0d.

Most if not all build backends pick up files with standard names by
default, especially `LICEN[CS]E*`. That's the case with setuptools:
https://setuptools.pypa.io/en/latest/userguide/miscellaneous.html

No need to explicitly specify licence files, implicit is fine.
2025-08-03 16:26:13 +02:00
Dimitri Papadopoulos 6c7b155fc5 build: time to retire setup.py 2025-07-31 18:04:37 +02:00
Dimitri Papadopoulos 8809f3b393 build: PEP 639 support requires setuptools ≥ 77
https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license-and-license-files
2025-07-31 13:48:26 +02:00
Dimitri Papadopoulos Orfanos 0cb7b0d4e1 build: Add license-files to pyproject.toml 2025-07-25 10:59:52 +02:00
Dimitri Papadopoulos 6d64d617f7 style: Enforce ruff rules 2025-07-25 10:47:40 +02:00
Dimitri Papadopoulos 3fda7f9e42 style: Apply ruff/pyupgrade rule UP031
P031 Use format specifiers instead of percent format
2025-07-25 10:47:40 +02:00
Dimitri Papadopoulos be82936f56 style: Apply ruff/pyupgrade rule UP015
UP015 Unnecessary mode argument
2025-07-25 10:47:40 +02:00
Dimitri Papadopoulos 73b035d152 style: Ignore ruff/Perflint rule PERF203
PERF203 `try`-`except` within a loop incurs performance overhead
2025-07-25 10:47:40 +02:00
Dimitri Papadopoulos 231841dd66 style: Apply ruff/isort rule I001
I001 Import block is un-sorted or un-formatted
2025-07-25 10:47:40 +02:00
Dimitri Papadopoulos 1f29d91551 style: Apply ruff/flake8-implicit-str-concat rule ISC001
ISC001 Implicitly concatenated string literals on one line
2025-07-25 10:47:40 +02:00
Dimitri Papadopoulos 823a96ee41 CI: Test more versions of Python 2025-07-25 10:45:23 +02:00
Dimitri Papadopoulos 74ad528c3a CI: Specify the latest version of Python 3
Without specifying a version of Python, actions/setup-python is a no-op,
as it fall backs to the version installed in the runner image.
2025-07-25 10:45:23 +02:00
Yuki Kobayashi 2698ca4f08 build: Fix deprecated license specification format 2025-06-26 15:58:54 +02:00
Dimitri Papadopoulos f190f2dbe1 doc: Update the name of BSD ports
Both FreeBSD and OpenBSD ports have new names:
- https://www.freshports.org/devel/py-yamllint
- https://openports.pl/path/devel/py-yamllint
2025-06-24 10:01:29 +02:00
Dimitri Papadopoulos ecde82e5e4 README: Python 3 is obvious nowadays 2025-06-24 10:01:29 +02:00
Dimitri Papadopoulos 2ccfe0c2fe style: Apply ruff rule RUF010
RUF010 Use explicit conversion flag
2025-06-23 07:48:14 +02:00
Dimitri Papadopoulos c0c1a80feb style: Apply ruff/Pylint rule PLC0206
PLC0206 Extracting value from dictionary without calling `.items()`
2025-06-23 07:48:14 +02:00
Dimitri Papadopoulos 0c05587143 style: Apply ruff/flake8-simplify rule SIM118
SIM118 Use `key in dict` instead of `key in dict.keys()`
2025-06-23 07:48:14 +02:00
Dimitri Papadopoulos 999d5fd69f style: Apply ruff/flake8-simplify rule SIM110
SIM110 Use `return any(...)` instead of `for` loop
2025-06-23 07:48:14 +02:00
Adrien Vergé 16430e9d0a config: Use "mapping" instead of "dict" for user-facing errors
Previously, these errors used the word "dict" because it's the common
term in the Python world. But the YAML term is rather "mapping". The
present commit fixes this wording.

This originates from this discussion [^2].

[^1]: https://yaml.org/spec/1.2.2/#3211-nodes
[^2]: https://github.com/adrienverge/yamllint/pull/747#pullrequestreview-2813393998
2025-05-05 18:34:39 +02:00
Adrien Vergé 79a6b2b139 yamllint version 1.37.1 v1.37.1 2025-05-04 10:24:35 +02:00
Yuki Kobayashi b6fe397aef config: Report if 'rules' is not a dict
In the current version, the error message states `TypeError: 'NoneType' object
is not iterable` when the 'rules' in the config file is not a dict (gh-274.) It
would be helpful to improve the error message.

Additionally, it is for consistency, as other elements (`ignore`, `locale`,
etc.) have similar error checks.
2025-05-04 10:20:02 +02:00
Yuki Kobayashi 2ec2d7a786 docs: Fix GitLab integration link
Append a missing underscore so the link works correctly.
2025-05-04 10:13:48 +02:00
Adrien Vergé 1a6542c58a quoted-strings: Fix only-when-needed on multiline with backslash
On double-quoted multiline strings, quotes aren't needed if lines are
broken on spaces, e.g.:

    multiline:
      "this is a sentence
      cut into words"

But quotes are needed when at least one line ends with a backslash
character (`\`), meaning that the next spaces should be removed:

    multiline:
      "https://example.com/a/very/very\
      /very/very/long/URL"

This commit fixes that.

Fixes https://github.com/adrienverge/yamllint/issues/275
2025-05-04 10:10:47 +02:00
Tobias Heinze 2d10aaa9dc docs: Fix GitLab integration example 2025-04-15 10:34:26 +02:00
Yuki Kobayashi 263fb88437 README: Fix the tests badge link
Update the link to the test ci status, according to the changes made
in commit 1c3bbb2.
2025-04-11 07:57:20 +02:00
Jason Yundt a942f5cd20 Rename tests.common.test_codec_built_in_equivalent()
Some of the functions in the test package are automatically run by test
frameworks and some functions in the test package are not. How do test
frameworks determine which functions should get run automatically? The
answer to that question depends on what test framework you are using.

Python’s built-in unittest framework uses the unittest.TestCase class to
figure out which which function should get run automatically. You have
to put your functions in subclasses or instances of the
unittest.TestCase class or else unittest won’t automatically run your
code [1].

The pytest framework works differently. By default, pytest will still
look for unittest.TestCase subclasses and instances, but it will also
run functions with names that begin with “test” even if those functions
aren’t inside any classes or instances [2].

When I had first written the test_codec_built_in_equivalent() function,
I had only tested it with the unittest framework. The unittest framework
does not run that function automatically because it’s not inside a
unittest.TestCase subclass or instance. The pytest framework, on the
other hand, will try to run test_codec_built_in_equivalent()
automatically because it’s name starts with “test”.
test_codec_built_in_equivalent() has one mandatory parameter, but pytest
doesn’t know what value to use for that parameter, so pytest will fail
to run that function.

This change prevents pytest from failing to run that function by
renaming it to built_in_equivalent_of_test_codec(). The function was
never supposed to be run automatically anyway.

Fixes #734.

[1]: <https://docs.python.org/3/library/unittest.html#organizing-test-code>
[2]: <https://docs.pytest.org/en/stable/explanation/goodpractices.html#conventions-for-python-test-discovery>
2025-04-09 16:48:24 +02:00
Mikal Sande 639a7c69c6 comments: Tell how many spaces are expected in 'min-spaces-from-content'
When telling someone that there are too few spaces before a comment it
can be useful to include how many were expected.
2025-04-09 14:35:44 +02:00
Adrien Vergé 0f2fbb03c7 docs: Add links to GitHub repository and releases
Closes https://github.com/adrienverge/yamllint/issues/733.
2025-04-09 11:22:01 +02:00
Adrien Vergé bce26d68a8 CI: Fix TestPyPI "dev0" versions for master commits on tags
This fixes a problem in the custom versions `v1.37.0.devN` built for
publishing on TestPyPI since commit 325fafa "Publish each master commit
with a unique version on TestPyPI".

Such versions are constructed by suffixing `.devN`, where `N` is the
number of commits since last tags. In the `N = 0` case, we need to add
`--long` to `git describe --tags`. Otherwise it yields `v1.37.0` instead
of `v1.37.0-0-gbe92e15`, and the CI fails, e.g. on
https://github.com/adrienverge/yamllint/actions/runs/14017589005/job/39245225221

    packaging.version.InvalidVersion: Invalid version: '1.37.0.devv1.37.0'
2025-03-23 10:41:27 +01:00
Adrien Vergé be92e15345 yamllint version 1.37.0 v1.37.0 2025-03-23 10:20:46 +01:00
Jason Yundt 832339492d CI: Fail when open()’s default encoding is used
The previous few commits have removed all calls to open() that use its
default encoding. That being said, it’s still possible that code added
in the future will contain that same mistake. This commit makes it so
that the CI test job will fail if that mistake is made again.

Unfortunately, it doesn’t look like coverage.py allows you to specify -X
options [1] or warning filters [2] when running your tests [3]. To work
around this problem, I’m running all of the Python code, including
coverage.py itself, with -X warn_default_encoding and
-W error::EncodingWarning. As a result, the CI test job will also fail
if coverage.py uses open()’s default encoding. Hopefully, coverage.py
won’t do that. If it does, then we can always temporarily revert this
commit.

[1]: <https://docs.python.org/3.12/using/cmdline.html#cmdoption-X>
[2]: <https://docs.python.org/3.12/using/cmdline.html#cmdoption-W>
[3]: <https://coverage.readthedocs.io/en/7.4.0/cmd.html#execution-coverage-run>
2025-03-23 10:16:35 +01:00
Jason Yundt 4d7be6d887 tests: Stop using open()’s default encoding
In general, using open()’s default encoding is a mistake [1]. This
change makes sure that every time open() is called, the encoding
parameter is specified. Specifically, it makes it so that all tests
succeed when run like this:

	python -X warn_default_encoding -W error::EncodingWarning -m unittest discover

[1]: <https://peps.python.org/pep-0597/#using-the-default-encoding-is-a-common-mistake>
2025-03-23 10:16:35 +01:00
Jason Yundt fd58e6b84e decoder: Autodetect encoding for ignore-from-file
Before this change, yamllint would decode files on the ignore-from-file
list using open()’s default encoding [1][2]. This can cause decoding to
fail in some situations (see the previous commit message for details).

This change makes yamllint automatically detect the encoding for files
on the ignore-from-file list. It uses the same algorithm that it uses
for detecting the encoding of YAML files, so the same limitations apply:
files must use UTF-8, UTF-16 or UTF-32 and they must begin with either a
byte order mark or an ASCII character.

[1]: <https://docs.python.org/3.12/library/fileinput.html#fileinput.input>
[2]: <https://docs.python.org/3.12/library/fileinput.html#fileinput.FileInput>
2025-03-23 10:16:35 +01:00
Jason Yundt 8e3a3b3f71 decoder: Autodetect decoding of stdin
Before this change, yamllint would use a character encoding
autodetection algorithm in order to determine the character encoding of
all YAML files that it processed, unless the YAML file was sent to
yamllint via stdin. This change makes it so that yamllint always uses
the character encoding detection algorithm, even if the YAML file is
sent to yamllint via stdin.

Before this change, one of yamllint’s tests would replace sys.stdin with
a StringIO object. This change makes it so that that test replaces
sys.stdin with a file object instead of a StringIO object. Before this
change, it was OK to use a StringIO object because yamllint never tried
to access sys.stdin.buffer. It’s no longer OK to use a StringIO because
yamllint now tries to access sys.stdin.buffer. File objects do have a
buffer attribute, so we can use a file object instead.
2025-03-23 10:16:35 +01:00