*************************** What's New in Pylint 4.0 *************************** .. toctree:: :maxdepth: 2 :Release:4.0 :Date: TBA Summary -- Release highlights ============================= .. towncrier release notes start What's new in Pylint 4.0.0-dev0? -------------------------------- Release date: TBA Breaking Changes ---------------- - `invalid-name` now distinguishes module-level constants that are assigned only once from those that are reassigned and now applies `--variable-rgx` to the latter. Values other than literals (lists, sets, objects) can pass against either the constant or variable regexes (e.g. "LOGGER" or "logger" but not "LoGgEr"). Remember that `--good-names` or `--good-names-rgxs` can be provided to explicitly allow good names. Closes #3585 (`#3585 `_) - Commented out code blocks such as ``# bar() # TODO: remove dead code`` will no longer emit ``fixme``. Refs #9255 (`#9255 `_) - `pyreverse` `Run` was changed to no longer call `sys.exit()` in its `__init__`. You should now call `Run(args).run()` which will return the exit code instead. Having a class that always raised a `SystemExit` exception was considered a bug. Normal usage of pyreverse through the CLI will not be affected by this change. Refs #9689 (`#9689 `_) - The ``suggestion-mode`` option was removed, as pylint now always emits user-friendly hints instead of false-positive error messages. You should remove it from your conf if it's defined. Refs #9962 (`#9962 `_) - The ``async.py`` checker module has been renamed to ``async_checker.py`` since ``async`` is a Python keyword and cannot be imported directly. This allows for better testing and extensibility of the async checker functionality. Refs #10071 (`#10071 `_) - The message-id of ``continue-in-finally`` was changed from ``E0116`` to ``W0136``. The warning is now emitted for every Python version since it will raise a syntax warning in Python 3.14. See `PEP 765 - Disallow return/break/continue that exit a finally block `_. Refs #10480 (`#10480 `_) New Features ------------ - ``comparison-of-constants`` now use the unicode from the ast instead of reformatting from the node's values preventing some bad formatting due to ``utf-8`` limitation. The message now use ``"`` instead of ``'`` to better work with what the python ast returns. Refs #8736 (`#8736 `_) - Enhanced pyreverse to properly distinguish between UML relationship types (association, aggregation, composition) based on object ownership semantics. Type annotations without assignment are now treated as associations, parameter assignments as aggregations, and object instantiation as compositions. Closes #9045 Closes #9267 (`#9045 `_) - The `fixme` check can now search through docstrings as well as comments, by using ``check-fixme-in-docstring = true`` in the ``[tool.pylint.miscellaneous]`` section. Closes #9255 (`#9255 `_) - The `use-implicit-booleaness-not-x` checks now distinguish between comparisons used in boolean contexts and those that are not, enabling them to provide more accurate refactoring suggestions. Closes #9353 (`#9353 `_) - The verbose option now outputs the filenames of the files that have been checked. Previously, it only included the number of checked and skipped files. Closes #9357 (`#9357 `_) - colorized reporter now colorizes messages/categories that have been configured as `fail-on` in red inverse. This makes it easier to quickly find the errors that are causing pylint CI job failures. Closes #9898 (`#9898 `_) - Enhanced support for @property decorator in pyreverse to correctly display return types of annotated properties when generating class diagrams. Closes #10057 (`#10057 `_) - Add --max-depth option to pyreverse to control diagram complexity. A depth of 0 shows only top-level packages, 1 shows one level of subpackages, etc. This helps manage visualization of large codebases by limiting the depth of displayed packages and classes. Refs #10077 (`#10077 `_) - Handle deferred evaluation of annotations in Python 3.14. Closes #10149 (`#10149 `_) - Enhanced pyreverse to properly detect aggregations for comprehensions (list, dict, set, generator). Closes #10236 (`#10236 `_) - `pyreverse`: add support for colorized output when using output format `mmd` (MermaidJS) and `html`. Closes #10242 (`#10242 `_) - pypy 3.11 is now officially supported. Refs #10287 (`#10287 `_) - Add support for Python 3.14. Refs #10467 (`#10467 `_) - Add naming styles for ParamSpec and TypeVarTuples which align with the TypeVar style. Refs #10541 (`#10541 `_) New Checks ---------- - Add ``match-statements`` checker and the following message: ``bare-name-capture-pattern``. This will emit an error message when a name capture pattern is used in a match statement which would make the remaining patterns unreachable. This code is a SyntaxError at runtime. Closes #7128 (`#7128 `_) - Add ``break-in-finally`` warning. Using ``break`` inside the ``finally`` clause will raise a syntax warning in Python 3.14. See `PEP 765 - Disallow return/break/continue that exit a finally block `_. Refs #10480 (`#10480 `_) False Positives Fixed --------------------- - Fix false positives for `possibly-used-before-assignment` when variables are exhaustively assigned within a `match` block. Closes #9668 (`#9668 `_) - Fix used-before-assignment for PEP 695 type aliases and parameters. Closes #9815 (`#9815 `_) - Fix a false positive for `used-before-assignment` when a variable defined under an `if` and via a named expression (walrus operator) is used later when guarded under the same `if` test. Closes #10061 (`#10061 `_) - Fix false positives for `use-implicit-booleaness-not-comparison`, `use-implicit-booleaness-not-comparison-to-string` and `use-implicit-booleaness-not-comparison-to-zero` when chained comparisons are checked. Closes #10065 (`#10065 `_) - Fix false positive for `missing-raises-doc` and `missing-yield-doc` when the method length is less than docstring-min-length. Refs #10104 (`#10104 `_) - Comparisons between two calls to `type()` won't raise an ``unidiomatic-typecheck`` warning anymore, consistent with the behavior applied only for ``==`` previously. Closes #10161 (`#10161 `_) - Fix a false positive for ``invalid-getnewargs-ex-returned`` when the tuple or dict has been assigned to a name. Closes #10208 (`#10208 `_) - Remove `getopt` and `optparse` from the list of deprecated modules. Closes #10211 (`#10211 `_) - Fix a false positive for ``unused-variable`` when multiple except handlers bind the same name under a try block. Closes #10426 (`#10426 `_) False Negatives Fixed --------------------- - Fix false negative for `used-before-assignment` when a `TYPE_CHECKING` import is used as a type annotation prior to erroneous usage. Refs #8893 (`#8893 `_) - Match cases are now counted as edges in the McCabe graph and will increase the complexity accordingly. Refs #9667 (`#9667 `_) - Check module-level constants with type annotations for ``invalid-name``. Remember to adjust ``const-naming-style`` or ``const-rgx`` to your liking. Closes #9770 (`#9770 `_) - We now raise a ``logging-too-few-args`` for format string with no interpolation arguments at all (i.e. for something like ``logging.debug("Awaiting process %s")`` or ``logging.debug("Awaiting process {pid}")``). Previously we did not raise for such case. Closes #9999 (`#9999 `_) - Fix false negative for `used-before-assignment` when a function is defined inside a `TYPE_CHECKING` guard block and used later. Closes #10028 (`#10028 `_) - Fix a false negative for `possibly-used-before-assignment` when a variable is conditionally defined and later assigned to a type-annotated variable. Closes #10421 (`#10421 `_) - Fix false negative for `deprecated-module` when a `__import__` method is used instead of `import` sentence. Refs #10453 (`#10453 `_) - Fix false-negative for ``used-before-assignment`` with ``from __future__ import annotations`` in function definitions. Refs #10482 (`#10482 `_) - Count match cases for ``too-many-branches`` check. Refs #10542 (`#10542 `_) Other Bug Fixes --------------- - When displaying unicode with surrogates (or other potential ``UnicodeEncodeError``), pylint will now display a '?' character (using ``encode(encoding="utf-8", errors="replace")``) instead of crashing. The functional tests classes are also updated to handle this case. Closes #8736. (`#8736 `_) - Fixes "skipped files" count calculation; the previous method was displaying an arbitrary number. Closes #10073 (`#10073 `_) - Fixed conditional import x.y causing false positive possibly-used-before-assignment. Closes #10081 (`#10081 `_) - Fixes a crash that occurred when pylint was run in a container on a host with cgroupsv2 and restrictions on CPU usage. Closes #10103 (`#10103 `_) - Fixed a crash when importing a class decorator that did not exist with the same name than a class attribute after the class definition. Closes #10105 (`#10105 `_) - Fix a crash when something besides a class is found in an except handler. Closes #10106 (`#10106 `_) - Fixed raising invalid-name when using camelCase for private methods with two leading underscores. Closes #10189 (`#10189 `_) - Relaxed the requirements for isort so pylint can benefit from isort 6. Closes #10203 (`#10203 `_) - Fixed unidiomatic-typecheck only checking left-hand side. Closes #10217 (`#10217 `_) - Fix a crash caused by malformed format strings when using `.format` with keyword arguments. Closes #10282 (`#10282 `_) - Using a slice as a class decorator now raise a 'not-callable' message instead of crashing pylint. A lot of checks that dealt with decorators (too many to list) are now shortcut if the decorator can't immediately be inferred to a function or class definition. Closes #10334 (`#10334 `_) - Fix a bug in Pyreverse where aggregations and associations were included in diagrams regardless of the selected --filter-mode (such as PUB_ONLY, ALL, etc.). Closes #10373 (`#10373 `_) - Fix double underscores erroneously rendering as bold in pyreverse's Mermaid output. Closes #10402 (`#10402 `_) - Fixed crash in 'unnecessary-list-index-lookup' when starting an enumeration using minus the length of an iterable inside a dict comprehension when the len call was only made in this dict comprehension, and not elsewhere. Also changed the approach, to use inference in all cases but the simple ones, so we don't have to fix crashes one by one for arbitrarily complex expressions in enumerate. Closes #10510 (`#10510 `_) Other Changes ------------- - Upload release assets to PyPI via Trusted Publishing. Closes #10256 (`#10256 `_) - The algorithm used for ``no-member`` suggestions is now more efficient and cut the calculation when the distance score is already above the threshold. Refs #10277 (`#10277 `_) - Remove support for launching pylint with Python 3.9. Code that supports Python 3.9 can still be linted with the ``--py-version=3.9`` setting. Refs #10405 (`#10405 `_) Internal Changes ---------------- - Modified test framework to allow for different test output for different Python versions. Refs #10382 (`#10382 `_)