
***************************
 What's New in Pylint 4.0
***************************

.. toctree::
   :maxdepth: 2

:Release:4.0
:Date: 2025-10-12

Summary -- Release highlights
=============================

- Pylint now supports Python 3.14.

- Pylint's inference engine (``astroid``) is now much more precise,
  understanding implicit booleanness and ternary expressions. (Thanks @zenlyj!)

Consider this example:

.. code-block:: python

    class Result:
        errors: dict | None = None

    result = Result()
    if result.errors:
        result.errors[field_key]
        # inference engine understands result.errors cannot be None
        # pylint no longer raises unsubscriptable-object

The required ``astroid`` version is now 4.0.0. See the
`astroid changelog <https://pylint.readthedocs.io/projects/astroid/en/latest/changelog.html#what-s-new-in-astroid-4-0-0>`_
for additional fixes, features, and performance improvements applicable to pylint.

- Handling of ``invalid-name`` at the module level was patchy. Now,
  module-level constants that are reassigned are treated as variables and checked
  against ``--variable-rgx`` rather than ``--const-rgx``. Module-level lists,
  sets, and objects can pass against either regex.

Here, ``LIMIT`` is reassigned, so pylint only uses ``--variable-rgx``:

.. code-block:: python

    LIMIT = 500  # [invalid-name]
    if sometimes:
        LIMIT = 1  # [invalid-name]

If this is undesired, refactor using *exclusive* assignment so that it is
evident that this assignment happens only once:

.. code-block:: python

    if sometimes:
        LIMIT = 1
    else:
        LIMIT = 500  # exclusive assignment: uses const regex, no warning

Lists, sets, and objects still pass against either ``const-rgx`` or ``variable-rgx``
even if reassigned, but are no longer completely skipped:

.. code-block:: python

    MY_LIST = []
    my_list = []
    My_List = []  # [invalid-name]

Remember to adjust the
`regexes <https://pylint.readthedocs.io/en/latest/user_guide/messages/convention/invalid-name.html>`_
and
`allow lists <https://pylint.readthedocs.io/en/latest/user_guide/configuration/all-options.html#good-names>`_
to your liking.

.. towncrier release notes start

What's new in Pylint 4.0.8?
---------------------------
Release date: 2026-08-29


False Positives Fixed
---------------------

- Fix a false positive for :ref:`unspecified-encoding` when an ``open`` call uses a mode
  argument that cannot be inferred.

  Closes #10201 (`#10201 <https://github.com/pylint-dev/pylint/issues/10201>`_)

- Fix a false positive for ``invalid-name`` (C0103) on names assigned in an
  ``if __name__ == "__main__":`` block. Such a block reads like a script body, so
  a name there is now accepted if it matches either the constant or the variable
  naming style.

  Closes #10766 (`#10766 <https://github.com/pylint-dev/pylint/issues/10766>`_)

- Fix false positives for :ref:`invalid-str-returned`, :ref:`invalid-repr-returned`,
  :ref:`invalid-format-returned`, :ref:`invalid-bytes-returned`, :ref:`invalid-hash-returned`,
  :ref:`invalid-index-returned`, :ref:`invalid-length-returned`,
  :ref:`invalid-length-hint-returned`, :ref:`invalid-getnewargs-returned` and
  :ref:`invalid-getnewargs-ex-returned` when the returned value is an instance of a
  subclass of the expected builtin type, such as ``self`` in a ``str`` subclass or a
  ``namedtuple``.

  Closes #11306 (`#11306 <https://github.com/pylint-dev/pylint/issues/11306>`_)

- Fix false positives for :ref:`bad-string-format-type` when the argument is an
  instance of a subclass of ``int``, ``float`` or ``str``, such as ``bool`` or an
  ``IntEnum`` member formatted with ``%d``.

  Closes #11315 (`#11315 <https://github.com/pylint-dev/pylint/issues/11315>`_)



False Negatives Fixed
---------------------

- ``redundant-unittest-assert`` now also flags ``assertEqual`` and ``assertNotEqual``
  when both compared values are constants, e.g. ``self.assertEqual(5, 5)``.

  Closes #11321 (`#11321 <https://github.com/pylint-dev/pylint/issues/11321>`_)



Other Bug Fixes
---------------

- Fix a crash in the ``docparams`` extension when a raised name does not infer to an exception, such as ``raise sum`` or ``raise some_module``. Such objects have no ``ancestors()``, which aborted the whole file with an ``astroid-error`` fatal message.

  Closes #11228 (`#11228 <https://github.com/pylint-dev/pylint/issues/11228>`_)

- Fix a crash in the ``use-yield-from`` checker (``AttributeError: 'Subscript' object has no attribute 'name'``) when a loop target is a subscript, attribute, or tuple.

  Closes #11286 (`#11286 <https://github.com/pylint-dev/pylint/issues/11286>`_)

- Fix a crash in the ``docparams`` extension (``AttributeError: 'AssignName' object has no attribute 'decorators'``) when a class has non-function attributes sharing the name of a property setter.

  Closes #11287 (`#11287 <https://github.com/pylint-dev/pylint/issues/11287>`_)



Other Changes
-------------

- Upgrade the ``isort`` upper bound so ``isort`` 9 can be installed alongside pylint.

  Closes #11351 (`#11351 <https://github.com/pylint-dev/pylint/issues/11351>`_)



What's new in Pylint 4.0.7?
---------------------------
Release date: 2026-08-09


False Positives Fixed
---------------------

- Fix a false positive for ``invalid-name`` when a module-level variable is assigned
  an instance of a ``TypedDict`` subclass. Such a name is a value, not a type
  definition, so it is now checked against the constant or variable regex instead
  of ``class-rgx``.

  Closes #11231 (`#11231 <https://github.com/pylint-dev/pylint/issues/11231>`_)



Other Bug Fixes
---------------

- Fix a crash in the ``bad-open-mode`` check when the ``mode`` argument of
  ``open`` is the ``NotImplemented`` constant (Python >= 3.14).

  Closes #11099 (`#11099 <https://github.com/pylint-dev/pylint/issues/11099>`_)

- Fix a crash in the ``not-context-manager`` and ``not-async-context-manager``
  checks when the context manager infers to a value without a name, such as the
  ``slice`` returned by ``with slice(...)`` / ``async with slice(...)``.

  Closes #11102 (`#11102 <https://github.com/pylint-dev/pylint/issues/11102>`_)

- Fix a false positive for ``nested-min-max`` (``W3301``) when the inner ``min``/``max`` call carries a keyword argument such as ``key=``. Flattening the call dropped the keyword and changed the result, so nested calls whose inner call has keyword arguments are no longer flagged.

  Closes #11130 (`#11130 <https://github.com/pylint-dev/pylint/issues/11130>`_)

- Fix a false suggestion from ``nested-min-max`` (``W3301``): when rewriting a nested ``min``/``max`` into a splat call, arguments positioned after the splatted call were silently dropped, so the suggested code changed the result.

  Closes #11134 (`#11134 <https://github.com/pylint-dev/pylint/issues/11134>`_)

- Fix a false positive for ``too-many-locals`` (``R0914``): PEP 695 type parameters, i.e. the ``T1`` and ``T2`` in a generic ``def f[T1, T2]`` signature, were counted as local variables. They are type-system constructs, not runtime locals, and are now excluded from the local-variable count.

  Closes #11136 (`#11136 <https://github.com/pylint-dev/pylint/issues/11136>`_)

- Fix `literal-comparison` (`R0123`) emitting a corrupted suggestion for identifiers
  that contain ``is`` (e.g. ``axis is 5`` was rendered ``ax== == 5``). The suggestion
  is now rebuilt from the operands and operator.

  Closes #11146 (`#11146 <https://github.com/pylint-dev/pylint/issues/11146>`_)

- Fix false positives in `bad-string-format-type` (`E1307`) for valid ``%`` formatting:
  ``%i``/``%u`` applied to a float (both truncate like ``%d``) and ``%a`` applied to any
  non-int type (``%a`` is type-agnostic like ``%s``/``%r``).

  Closes #11147 (`#11147 <https://github.com/pylint-dev/pylint/issues/11147>`_)

- Fix a false positive for :ref:`useless-parent-delegation` when an override changes
  the default value of a positional-only parameter.

  Closes #11148 (`#11148 <https://github.com/pylint-dev/pylint/issues/11148>`_)

- Fixed a crash in ``comparison-with-callable`` when comparing a lambda assigned as a class attribute.

  Closes #11175 (`#11175 <https://github.com/pylint-dev/pylint/issues/11175>`_)

- ``too-many-lines`` could be reported at the line of a ``# pylint: disable=too-many-lines``
  pragma found in a previously linted module. Pragma positions are now reset between
  modules, so the message is reported at line 1 (or at the current module's own pragma)
  regardless of which files were linted before.

  Refs #11191 (`#11191 <https://github.com/pylint-dev/pylint/issues/11191>`_)

- Fix a crash when a call unpacks a dictionary whose keys are not string
  constants, e.g. ``copy.copy(**{-1: 1})``.

  Closes #11222 (`#11222 <https://github.com/pylint-dev/pylint/issues/11222>`_)



What's new in Pylint 4.0.6?
---------------------------
Release date: 2026-06-14


False Positives Fixed
---------------------

- ``implicit-str-concat`` is no longer emitted for an implicit concatenation of
  a raw string with a non-raw one (e.g. ``r"\d" "\n"``). Such literals cannot be
  merged into a single string, so the concatenation is intentional rather than a
  forgotten comma.

  Closes #6663 (`#6663 <https://github.com/pylint-dev/pylint/issues/6663>`_)

- Fix a false positive for ``invalid-name`` (C0103) where the default
  ``typevar-rgx`` rejected ``TypeVar`` names containing digits, such as
  ``Ec2T``.

  Closes #8499 (`#8499 <https://github.com/pylint-dev/pylint/issues/8499>`_)

- Fix a false positive for ``too-many-arguments`` in (non-static) methods and classmethods.

  Closes #8675 (`#8675 <https://github.com/pylint-dev/pylint/issues/8675>`_)

- 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 <https://github.com/pylint-dev/pylint/issues/9833>`_)

- 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 <https://github.com/pylint-dev/pylint/issues/10665>`_)

- 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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/10890>`_)

- Fix a false positive for ``bad-dunder-name`` when there is a user-defined ``__suppress_context__`` attribute on exception subclasses.

  Closes #10960 (`#10960 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/10980>`_)

- Check for metaclass __call__ signature when evaluating arguments of a class call.

  Closes #11032 (`#11032 <https://github.com/pylint-dev/pylint/issues/11032>`_)

- Fix false positive ``method-hidden`` when ``cached_property`` is imported directly with ``from functools import cached_property``.

  Refs #11037 (`#11037 <https://github.com/pylint-dev/pylint/issues/11037>`_)



Other Bug Fixes
---------------

- Fix the suggestion of ``unnecessary-comprehension`` for a dict comprehension
  that iterates a dict directly, e.g. ``{a: b for a, b in d}``. Iterating a dict
  yields its keys, so the suggestion is now ``dict(d.keys())`` instead of the
  incorrect ``dict(d)``, which would simply copy ``d``.

  Closes #8256 (`#8256 <https://github.com/pylint-dev/pylint/issues/8256>`_)

- 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 <https://github.com/pylint-dev/pylint/issues/10099>`_)

- Fix crash when checking ``attribute-defined-outside-init`` on classes that inherit from a base class pylint cannot fully analyze.

  Closes #10892 (`#10892 <https://github.com/pylint-dev/pylint/issues/10892>`_)

- 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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/11025>`_)

- Avoided a crash from the implicit booleaness checker for ``len()`` calls without arguments.

  Closes #11028 (`#11028 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/11059>`_)

- Avoid crashing when enum member inference fails while checking enum subclasses.

  Closes #11069 (`#11069 <https://github.com/pylint-dev/pylint/issues/11069>`_)

- Prevent a crash in ``unexpected-keyword-arg`` analysis when
  ``infer_call_result()`` raises ``InferenceError`` while inspecting
  decorator return signatures.

  Closes #11070 (`#11070 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/11071>`_)

- Allow digits in ParamSpec and TypeVarTuple names for `invalid-name` check.

  The default `paramspec-rgx` and `typevartuple-rgx` patterns rejected names
  containing digits (e.g. ``Ec2P``, ``S3Ts``), emitting a false ``invalid-name``
  (C0103). Allow digits in the lowercase segments, consistent with the
  ``typevar`` and ``typealias`` patterns.

  Closes #11090 (`#11090 <https://github.com/pylint-dev/pylint/issues/11090>`_)



Performance Improvements
------------------------

- 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 <https://github.com/pylint-dev/pylint/issues/3443>`_)



What's new in Pylint 4.0.5?
---------------------------
Release date: 2026-02-20


False Positives Fixed
---------------------

- Fix possibly-used-before-assignment false positive when using self.fail() in tests.

  Closes #10743 (`#10743 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/10752>`_)

- 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 <https://github.com/pylint-dev/pylint/issues/10790>`_)

- Avoid emitting `unspecified-encoding` (W1514) when `py-version` is 3.15+.

  Refs #10791 (`#10791 <https://github.com/pylint-dev/pylint/issues/10791>`_)



Other Bug Fixes
---------------

- Fix `--known_third_party` config being ignored.

  Closes #10801 (`#10801 <https://github.com/pylint-dev/pylint/issues/10801>`_)

- Fixed dynamic color mapping for "fail-on" messages when using multiple reporter/output formats.

  Closes #10825 (`#10825 <https://github.com/pylint-dev/pylint/issues/10825>`_)

- dependency on isort is now set to <9, permitting to use isort 8.

  Closes #10857 (`#10857 <https://github.com/pylint-dev/pylint/issues/10857>`_)



What's new in Pylint 4.0.4?
--------------------------------
Release date: 2025-11-30


False Positives Fixed
---------------------

- Fixed false positive for ``invalid-name`` where module-level constants were incorrectly classified as variables when a class-level attribute with the same name exists.

  Closes #10719 (`#10719 <https://github.com/pylint-dev/pylint/issues/10719>`_)

- Fix a false positive for ``invalid-name`` on an UPPER_CASED name inside an ``if`` branch that assigns an object.

  Closes #10745 (`#10745 <https://github.com/pylint-dev/pylint/issues/10745>`_)



What's new in Pylint 4.0.3?
---------------------------
Release date: 2025-11-13


False Positives Fixed
---------------------

- Add Enum dunder methods ``_generate_next_value_``, ``_missing_``, ``_numeric_repr_``, ``_add_alias_``, and ``_add_value_alias_`` to the list passed to ``--good-dunder-names``.

  Closes #10435 (`#10435 <https://github.com/pylint-dev/pylint/issues/10435>`_)

- Fixed false positive for ``invalid-name`` with ``typing.Annotated``.

  Closes #10696 (`#10696 <https://github.com/pylint-dev/pylint/issues/10696>`_)

- Fix false positive for ``f-string-without-interpolation`` with template strings
  when using format spec.

  Closes #10702 (`#10702 <https://github.com/pylint-dev/pylint/issues/10702>`_)

- Fix a false positive when an UPPER_CASED class attribute was raising an
  ``invalid-name`` when typed with ``Final``.

  Closes #10711 (`#10711 <https://github.com/pylint-dev/pylint/issues/10711>`_)

- Fix a false positive for ``unbalanced-tuple-unpacking`` when a tuple is assigned to a function call and the structure of the function's return value is ambiguous.

  Closes #10721 (`#10721 <https://github.com/pylint-dev/pylint/issues/10721>`_)



Other Bug Fixes
---------------

- Make 'ignore' option work as expected again.

  Closes #10669 (`#10669 <https://github.com/pylint-dev/pylint/issues/10669>`_)

- Fix crash for ``consider-using-assignment-expr`` when a variable annotation without assignment
  is used as the ``if`` test expression.

  Closes #10707 (`#10707 <https://github.com/pylint-dev/pylint/issues/10707>`_)

- Fix crash for ``prefer-typing-namedtuple`` and ``consider-math-not-float`` when
  a ``slice`` object is called.

  Closes #10708 (`#10708 <https://github.com/pylint-dev/pylint/issues/10708>`_)



What's new in Pylint 4.0.2?
--------------------------------
Release date: 2025-10-20


False Positives Fixed
---------------------

- Fix false positive for :ref:`invalid-name` on a partially uninferable module-level constant.

  Closes #10652 (`#10652 <https://github.com/pylint-dev/pylint/issues/10652>`_)

- Fix a false positive for :ref:`invalid-name` on exclusive module-level assignments
  composed of three or more branches. We won't raise :ref:`disallowed-name` on module-level names that can't be inferred
  until a further refactor to remove this false negative is done.

  Closes #10664 (`#10664 <https://github.com/pylint-dev/pylint/issues/10664>`_)

- Fix false positive for :ref:`invalid-name` for ``TypedDict`` instances.

  Closes #10672 (`#10672 <https://github.com/pylint-dev/pylint/issues/10672>`_)



What's new in Pylint 4.0.1?
---------------------------
Release date: 2025-10-14


False Positives Fixed
---------------------

- Exclude ``__all__`` and ``__future__.annotations`` from ``unused-variable``.

  Closes #10019 (`#10019 <https://github.com/pylint-dev/pylint/issues/10019>`_)

- Fix false-positive for ``bare-name-capture-pattern`` if a case guard is used.

  Closes #10647 (`#10647 <https://github.com/pylint-dev/pylint/issues/10647>`_)

- Check enums created with the ``Enum()`` functional syntax to pass against the
  ``--class-rgx`` for the :ref:`invalid-name` check, like other enums.

  Closes #10660 (`#10660 <https://github.com/pylint-dev/pylint/issues/10660>`_)



What's new in Pylint 4.0.0?
---------------------------
Release date: 2025-10-12


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 <https://github.com/pylint-dev/pylint/issues/3585>`_)

- The unused ``pylintrc`` argument to ``PyLinter.__init__()`` is deprecated
  and will be removed.

  Refs #6052 (`#6052 <https://github.com/pylint-dev/pylint/issues/6052>`_)

- Commented out code blocks such as ``#    bar() # TODO: remove dead code`` will no longer emit ``fixme``.

  Refs #9255 (`#9255 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://peps.python.org/pep-0765/>`_.

  Refs #10480 (`#10480 <https://github.com/pylint-dev/pylint/issues/10480>`_)

- Removed support for ``nmp.NaN`` alias for ``numpy.NaN`` being recognized in ':ref:`nan-comparison`'. Use ``np`` or ``numpy`` instead.

  Refs #10583 (`#10583 <https://github.com/pylint-dev/pylint/issues/10583>`_)

- Version requirement for ``isort`` has been bumped to >=5.0.0.
  The internal compatibility for older ``isort`` versions exposed via ``pylint.utils.IsortDriver`` has
  been removed.

  Refs #10637 (`#10637 <https://github.com/pylint-dev/pylint/issues/10637>`_)



New Features
------------

- ``comparison-of-constants`` now uses 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 uses
   ``"`` instead of ``'`` to better work with what the python ast returns.

  Refs #8736 (`#8736 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/9898>`_)

- Enhanced support for @property decorator in pyreverse to correctly display return types of annotated properties when generating class diagrams.

  Closes #10057 (`#10057 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/10077>`_)

- Handle deferred evaluation of annotations in Python 3.14.

  Closes #10149 (`#10149 <https://github.com/pylint-dev/pylint/issues/10149>`_)

- Enhanced pyreverse to properly detect aggregations for comprehensions (list, dict, set, generator).

  Closes #10236 (`#10236 <https://github.com/pylint-dev/pylint/issues/10236>`_)

- ``pyreverse``: add support for colorized output when using output format ``mmd`` (MermaidJS) and ``html``.

  Closes #10242 (`#10242 <https://github.com/pylint-dev/pylint/issues/10242>`_)

- pypy 3.11 is now officially supported.

  Refs #10287 (`#10287 <https://github.com/pylint-dev/pylint/issues/10287>`_)

- Add support for Python 3.14.

  Refs #10467 (`#10467 <https://github.com/pylint-dev/pylint/issues/10467>`_)

- Add naming styles for ``ParamSpec`` and ``TypeVarTuple`` that align with the ``TypeVar`` style.

  Refs #10541 (`#10541 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/7128>`_)

- Add new check ``async-context-manager-with-regular-with`` to detect async context managers used with regular ``with`` statements instead of ``async with``.

  Refs #10408 (`#10408 <https://github.com/pylint-dev/pylint/issues/10408>`_)

- 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 <https://peps.python.org/pep-0765/>`_.

  Refs #10480 (`#10480 <https://github.com/pylint-dev/pylint/issues/10480>`_)

- Add new checks for invalid uses of class patterns in :keyword:`match`.

  * :ref:`invalid-match-args-definition` is emitted if :py:data:`object.__match_args__` isn't a tuple of strings.
  * :ref:`too-many-positional-sub-patterns` if there are more positional sub-patterns than specified in :py:data:`object.__match_args__`.
  * :ref:`multiple-class-sub-patterns` if there are multiple sub-patterns for the same attribute.

  Refs #10559 (`#10559 <https://github.com/pylint-dev/pylint/issues/10559>`_)

- Add additional checks for suboptimal uses of class patterns in :keyword:`match`.

  * :ref:`match-class-bind-self` is emitted if a name is bound to ``self`` instead of
    using an ``as`` pattern.
  * :ref:`match-class-positional-attributes` is emitted if a class pattern has positional
    attributes when keywords could be used.

  Refs #10587 (`#10587 <https://github.com/pylint-dev/pylint/issues/10587>`_)

- Add a ``consider-math-not-float`` message. ``float("nan")`` and ``float("inf")`` are slower
  than their counterpart ``math.inf`` and ``math.nan`` by a factor of 4 (notwithstanding
  the initial import of math) and they are also not well typed when using mypy.
  This check also catches typos in float calls as a side effect.

  The :ref:`pylint.extensions.code_style` need to be activated for this check to work.

  Refs #10621 (`#10621 <https://github.com/pylint-dev/pylint/issues/10621>`_)



False Positives Fixed
---------------------

- 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 <https://github.com/pylint-dev/pylint/issues/10061>`_)

- Fix :ref:`no-name-in-module` for members of ``concurrent.futures`` with Python 3.14.

  Closes #10632 (`#10632 <https://github.com/pylint-dev/pylint/issues/10632>`_)



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 <https://github.com/pylint-dev/pylint/issues/8893>`_)

- Match cases are now counted as edges in the McCabe graph and will increase the complexity accordingly.

  Refs #9667 (`#9667 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/9770>`_)

- Fix false negative where function-redefined (E0102) was not reported for functions with a leading underscore.

  Closes #9894 (`#9894 <https://github.com/pylint-dev/pylint/issues/9894>`_)

- 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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/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 <https://github.com/pylint-dev/pylint/issues/10421>`_)

- Fix false negative for ``deprecated-module`` when a ``__import__`` method is used instead of ``import`` sentence.

  Refs #10453 (`#10453 <https://github.com/pylint-dev/pylint/issues/10453>`_)

- Count match cases for ``too-many-branches`` check.

  Refs #10542 (`#10542 <https://github.com/pylint-dev/pylint/issues/10542>`_)

- Fix false-negative where :ref:`unused-import` was not reported for names referenced in a preceding ``global`` statement.

  Refs #10633 (`#10633 <https://github.com/pylint-dev/pylint/issues/10633>`_)



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 <https://github.com/pylint-dev/pylint/issues/8736>`_)

- Fixed unidiomatic-typecheck only checking left-hand side.

  Closes #10217 (`#10217 <https://github.com/pylint-dev/pylint/issues/10217>`_)

- Fix a crash caused by malformed format strings when using ``.format`` with keyword arguments.

  Closes #10282 (`#10282 <https://github.com/pylint-dev/pylint/issues/10282>`_)

- Fix false positive ``inconsistent-return-statements`` when using ``quit()`` or ``exit()`` functions.

  Closes #10508 (`#10508 <https://github.com/pylint-dev/pylint/issues/10508>`_)

- Fix a crash in :ref:`nested-min-max` when using ``builtins.min`` or ``builtins.max``
  instead of ``min`` or ``max`` directly.

  Closes #10626 (`#10626 <https://github.com/pylint-dev/pylint/issues/10626>`_)

- Fixed a crash in :ref:`unnecessary-dict-index-lookup` when the index of an enumerated list
  was deleted inside a for loop.

  Closes #10627 (`#10627 <https://github.com/pylint-dev/pylint/issues/10627>`_)



Other Changes
-------------

- 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 <https://github.com/pylint-dev/pylint/issues/10405>`_)



Internal Changes
----------------

- Modified test framework to allow for different test output for different Python versions.

  Refs #10382 (`#10382 <https://github.com/pylint-dev/pylint/issues/10382>`_)
