*************************** What's New in Pylint 4.1 *************************** .. toctree:: :maxdepth: 2 :Release:4.1 :Date: TBA Summary -- Release highlights ============================= The duplicate-code checker and ``symilar`` received optimizations that result in considerable performance improvements and memory use reduction on larger codebases. For example, pandas analysis went from 20 min to 55 s and pylint does not get OOM-killed when analyzing cpython anymore. The required ``astroid`` version is now 4.1.1. See the `astroid changelog `_ for additional fixes, features, and performance improvements applicable to pylint. .. towncrier release notes start What's new in Pylint 4.0.0-dev0? -------------------------------- Release date: TBA Breaking Changes ---------------- - The ``confidence`` parameter is no longer nullable on any APIs except for ``is_message_enabled`` (where ``confidence=None`` means "don't filter by confidence"). The default became ``interfaces.UNDEFINED`` (an immutable value); the behavior is unchanged unless you were passing an explicit ``None``. This avoids a runtime check in multiple function to set the default value conditionally. The ``constants.MSG_STATE_*`` integer were replaced by a ``MessageDisableReason`` enum. The old names remain as deprecated aliases pointing at the enum members. ``MessageDisableReason`` is an ``IntEnum`` so existing code comparing the return of ``_get_message_state_scope`` to the literal ``0`` / ``1`` / ``2`` keeps working. Refs #11018 (`#11018 `_) New Features ------------ - Add support for ``ignore-pattern-in-long-lines`` to allow ignoring specific parts of a line when checking line length. Refs #3352 (`#3352 `_) - The dict-init-mutate message now includes a suggested dictionary literal showing how to combine the initialization and subsequent mutations into a single statement. Closes #7819 (`#7819 `_) - pyreverse: add ``--no-signatures`` to show method names without parameter lists or return type annotations in class diagrams. Closes #10772 (`#10772 `_) - Add support for `--known-first-party` similar to `--known-third-party`. Refs #10803 (`#10803 `_) False Positives Fixed --------------------- - Fix a false positive for ``too-many-arguments`` in (non-static) methods and classmethods. Closes #8675 (`#8675 `_) - Fix a false positive for ``inconsistent-return-statements`` when an instance method annotated with ``NoReturn`` (or ``Never``) is called via the class rather than an instance (e.g. ``MyClass.raise_method(obj)``). The unbound method form is now recognised as never returning, matching the existing behaviour for the bound-method form. Closes #9692 (`#9692 `_) - Fix a false positive for ``no-member`` when a value is inferred to several possible types and at least one of them defines a dynamic ``__getattr__``. Closes #9833 (`#9833 `_) - Fix ``used-before-assignment`` false positive for names bound in only some arms of an ``if/elif/else`` chain. Closes #9879 (`#9879 `_) - Fix a false positive for ``function-redefined`` (E0102) when reusing names that match ``dummy-variables-rgx`` (such as ``_``), which is common for ``pytest-bdd`` step definitions. This restores the behavior from before pylint 4.0.0; as a consequence the false negative fixed in #9894 is reintroduced for functions whose name matches ``dummy-variables-rgx``. Closes #10665 (`#10665 `_) - Fix a false positive for ``unexpected-keyword-arg`` for dataclasses using generic type aliases (PEP 695). Closes #10703 (`#10703 `_) - Fix possibly-used-before-assignment false positive when using self.fail() in tests. Closes #10743 (`#10743 `_) - Fixed false positive for ``logging-unsupported-format`` when no arguments are provided to logging functions. According to Python's logging documentation, no formatting is performed when no arguments are supplied, so strings like ``logging.error("%test")`` are valid. Closes #10752 (`#10752 `_) - Fix false positive ``unreachable`` when calling a function with ``@overload`` where one signature returns ``NoReturn``. Closes #10785 (`#10785 `_) - Fix a false positive for ``too-many-function-args`` for dataclasses using generic type aliases (PEP 695). Closes #10788 (`#10788 `_) - Fix a false positive for ``invalid-name`` where a dataclass field typed with ``Final`` was evaluated against the ``class_const`` regex instead of the ``class_attribute`` regex. Closes #10790 (`#10790 `_) - Avoid emitting `unspecified-encoding` (W1514) when `py-version` is 3.15+. Refs #10791 (`#10791 `_) - Fix a false positive ``relative-beyond-top-level`` error when linting specific files in namespace packages in parallel mode by augmenting ``sys.path`` before loading plugins and expanding files consistently for parallel workers. Closes #10794 (`#10794 `_) - Fix ``undefined-variable`` false positive when a name used as a ``metaclass`` argument in a nested class is referenced again later in the module. Closes #10823 (`#10823 `_) - Fix a false positive for ``unused-variable`` where global variables matching ``dummy-variables-rgx`` were still reported as unused when ``allow-global-unused-variables`` was disabled. Closes #10890 (`#10890 `_) - Fix ``# pylint: enable`` inside a ``try`` block leaking into the ``except`` handler. For example in the following code, ``no-member`` is no longer incorrectly re-enabled in the ``except`` block: .. code-block:: python class Basket: # pylint: disable=no-member def pick(self): try: # pylint: enable=no-member print(self.apple) # no-member emitted here except KeyError: print(self.banana) # no-member NOT emitted here (correct) Requires astroid 4.2. Refs #10933 (`#10933 `_) - Fix a false positive for ``bad-dunder-name`` when there is a user-defined ``__suppress_context__`` attribute on exception subclasses. Closes #10960 (`#10960 `_) - Fix ``used-before-assignment`` false positive for names bound by ``from X import *`` in every branch of an ``if``/``elif``/``else`` chain. Refs #10980 (`#10980 `_) - Fix ``access-member-before-definition`` false positive for bare type annotations (``self.x: Type``) that don't assign a value. Refs #11015 (`#11015 `_) - Check for metaclass __call__ signature when evaluating arguments of a class call. Closes #11032 (`#11032 `_) - Fix false positive ``method-hidden`` when ``cached_property`` is imported directly with ``from functools import cached_property``. Refs #11037 (`#11037 `_) False Negatives Fixed --------------------- - ``missing-param-doc`` and ``missing-type-doc`` no longer false-negative on NumPy-style parameters whose type line includes a default value, e.g. ``number : int, default 0``. Any text after the colon on the type line is now accepted as the type, matching the NumPy style guide. Closes #6211 (`#6211 `_) - Fix a false negative for ``abstract-method`` where a concrete subclass inheriting from an abstract class (without redeclaring ``abc.ABC`` or ``ABCMeta``) was treated as abstract and silently exempted from the check. A class is now only considered abstract when it opts in explicitly, via direct ``abc.ABC`` inheritance, ``metaclass=ABCMeta``, an ``@abstractmethod`` defined on the class, or being a ``Protocol``. Closes #7950 (`#7950 `_) Other Bug Fixes --------------- - ``dangerous-default-value`` now detects mutable default values in ``typing.NamedTuple`` field definitions. Closes #3716 (`#3716 `_) - Fix enabling checks from extensions which are disabled by default if multiple jobs are used. Closes #10037 (`#10037 `_) - Fix a crash in ``consider-using-enumerate`` when the ``for`` loop target is an attribute (e.g. ``for self.idx in range(len(x))``) rather than a simple variable name. Closes #10099 (`#10099 `_) - ``wrong-import-position`` now exempts ``try``, ``if``, ``with``, and ``match`` blocks from marking the import boundary. Fixed ``async def`` not being detected as an import boundary. Pragma on non-import lines now suppresses following imports until the next non-import. Closes #10589 (`#10589 `_) - Fix duplicate messages for extension checks if multiple jobs are used. Refs #10642 (`#10642 `_) - Fix `--known_third_party` config being ignored. Closes #10801 (`#10801 `_) - Fixed dynamic color mapping for "fail-on" messages when using multiple reporter/output formats. Closes #10825 (`#10825 `_) - dependency on isort is now set to <9, permitting to use isort 8. Closes #10857 (`#10857 `_) - Fix crash when checking ``attribute-defined-outside-init`` on classes that inherit from a base class pylint cannot fully analyze. Closes #10892 (`#10892 `_) - Fix an issue where discovery can miss a similarly named directory if a shorter named directory is processed first. Closes #10969 (`#10969 `_) - Fixed inflated message occurrence counts in the final ``Messages`` report when running pylint in parallel mode with ``--jobs`` greater than 1. Closes #10996 (`#10996 `_) - Fix ``add_message`` silently overwriting an explicit ``col_offset=0`` (or any other zero-valued ``line``/``end_lineno``/``end_col_offset``) with the AST node's value. The internal ``_add_one_message`` helper used a falsey check (``if not col_offset:``) to detect an omitted argument, which incorrectly treated a legitimate ``0`` the same as ``None``. It now uses an identity check against ``None``. Refs #11020 (`#11020 `_) - Fix a crash in the name checker when a non-constant value is passed as the ``covariant`` or ``contravariant`` argument of a ``TypeVar``. Closes #11022 (`#11022 `_) - Fix a crash in the variable checker when a name resolves to a dataclass-synthesized ``__init__``, which has no line number. Closes #11023 (`#11023 `_) - Fix a crash in the variables checker when ``NotImplemented`` is used as the test of an ``if`` statement, which raised a ``TypeError`` in a boolean context on Python 3.14. Closes #11025 (`#11025 `_) - Avoided a crash from the implicit booleaness checker for ``len()`` calls without arguments. Closes #11028 (`#11028 `_) - Fix a crash in the variables checker when a class declares a metaclass whose attribute-access chain does not bottom out at a name (e.g. ``class C(metaclass=None._)``). Originally reported as ``pylint-dev/astroid#3066``. Refs #11031 (`#11031 `_) - Fix a crash in the name checker when a chained assignment of a ``TypeAlias`` value has a non-name target such as a ``Subscript`` (for example ``a[0] = b = TypeAlias``). Closes #11056 (`#11056 `_) - Fix a crash in the deprecated checker when ``__import__`` is called with a non-string constant argument (for example ``__import__(1)``). Closes #11059 (`#11059 `_) - Prevent a crash in ``unexpected-keyword-arg`` analysis when ``infer_call_result()`` raises ``InferenceError`` while inspecting decorator return signatures. Closes #11070 (`#11070 `_) - Fix a crash in the typecheck checker when a class uses a non-class object (for example a function) as its ``metaclass=`` argument. Closes #11071 (`#11071 `_) Other Changes ------------- - You can now set the ``files`` option in configuration files and on the command line. Passing files without the ``--files`` flag is still supported. This allows to set ``files`` to ``files = my_source_directory`` and invoking ``pylint`` with only the ``pylint`` command similar to how other CLI tools allow to do so. The help message can always be invoked with ``pylint -h`` or ``pylint --help``. Closes #5701 (`#5701 `_) - Document that the ``wrong-import-order`` (C0411) classification of imports as third-party vs first-party depends on the current working directory and recommend ``known-first-party`` as the deterministic workaround. Closes #8801 (`#8801 `_) Internal Changes ---------------- - Add ``assertDoesNotAddMessages`` to ``CheckerTestCase`` to assert that specific messages are not emitted, while allowing other messages to be present. This complements ``assertNoMessages`` which asserts that no messages at all are emitted. Refs #9598 (`#9598 `_) Performance Improvements ------------------------ - Lazily import ``isort``, ``dill``, ``multiprocessing``/``concurrent.futures``, and ``tomlkit`` so they are only loaded when actually needed. This reduces startup time by ~25% (e.g. ``--version``: 91 => 67 ms, ``--help``: 176 => 133 ms, single-file lint: 272 => 226 ms). Closes #2866 (`#2866 `_) - The duplicate-code checker no longer runs when its message (R0801) is disabled, even if ``reports=yes`` is set. Previously, the checker's report (RP0801) would cause the expensive similarity computation to run regardless. Closes #3443 (`#3443 `_) - Sped up the ``duplicate-code`` checker. When run inside pylint the checker now reuses the already-parsed AST instead of re-parsing every file like it has to do when launched via ``symilar``, and it uses a rolling hash window with caching across file pairs. Additionally, a quadratic blow-up in the hash-matching phase is avoided by switching algorithm at a threshold, which previously caused the checker to hang on files with many repeated lines. Speedup scales with codebase size from 1.5x on small projects (~10k lines), to 20x on large ones (500k+ lines). Memory usage also drops 12-27%. Codebases that previously hung or were OOM-killed could now complete. Refs #10881 (`#10881 `_) - Skip isort classification in the import checker when no import-ordering message is enabled, and cache the isort configuration so it is built once instead of once per import statement. Skipping the isort processing become a negligible improvement once the caching is applied. pylint became ~17% faster on ansible (~=4500 imports) even with isort enabled. Refs #10886, #2866, #10637 (`#10886 `_)