Skip to content

Conversation

Pierre-Sassoulas
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas commented Oct 11, 2025

What's new in Pylint 4.0.0?

Release date: 2025-10-12

  • 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:

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 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:

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:

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:

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

Remember to adjust the regexes and allow lists to your liking.

Breaking Changes

New Features

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 Check for name capture syntax errors #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 False Context manager 'async_generator' doesn't implement __enter__ and __exit__ #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 Update checks for PEP 765 - return/break/continue in finally block #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 Add new checks for match class patterns #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 R0903:too-few-public-methods for private methods #10586

  • 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 [consider-math-not-float] Add a check for float("inf"), float("nan") and float("typos") #10621

False Positives Fixed

False Negatives Fixed

Other Bug Fixes

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 Drop support for Python 3.9 #10405

Internal Changes

@Pierre-Sassoulas Pierre-Sassoulas added this to the 4.0.0 milestone Oct 11, 2025
Copy link

codecov bot commented Oct 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.96%. Comparing base (ea25969) to head (8729244).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main   #10639   +/-   ##
=======================================
  Coverage   95.96%   95.96%           
=======================================
  Files         176      176           
  Lines       19502    19502           
=======================================
  Hits        18715    18715           
  Misses        787      787           
Files with missing lines Coverage Δ
pylint/__pkginfo__.py 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This comment has been minimized.

@cdce8p
Copy link
Member

cdce8p commented Oct 11, 2025

Aiming for tomorrow.

I'm working on some last minute multithreading fixes. It would address #10037 and remove the duplicate messages for dynamic plugins with -j2. The change works already, testing it properly might be a different story though. I hop that I can open the PR for it tomorrow.

@DanielNoord
Copy link
Collaborator

Would be nice to merge #10641 as well as it technically contains a breaking change to our API and version constraints. User impact should be minimal though and a net positive as there won't be issues with installing pylint and the latest version of isort.

@Pierre-Sassoulas Pierre-Sassoulas added Documentation 📗 Skip news 🔇 This change does not require a changelog entry labels Oct 12, 2025
@cdce8p
Copy link
Member

cdce8p commented Oct 12, 2025

@Pierre-Sassoulas Could you run tox -e docs? I do get a small whitespace / line break change here. Not sure if that's just on my system.

:too-many-positional-sub-patterns (E1903): *%s expects %d positional sub-patterns (given %d)*
Emitted when the number of allowed positional sub-patterns exceeds the number
of allowed sub-patterns specified in `__match_args__`.
:multiple-class-sub-patterns (E1904): *Multiple sub-patterns for attribute %s*
Emitted when there is more than one sub-pattern for a specific attribute in a
class pattern.

@Pierre-Sassoulas
Copy link
Member Author

@Pierre-Sassoulas Could you run tox -e docs? I do get a small whitespace / line break change here. Not sure if that's just on my system.

I just did for 4.1.0-dev0, no changes using python 3.12 / ubuntu 24.04 / the enchant system lib I have currently installed. I have those small changes too when it was generated by someone else though.

cdce8p
cdce8p previously approved these changes Oct 12, 2025
@Pierre-Sassoulas
Copy link
Member Author

I'm not that good at reading and following the release documentation. (And will need a new approval 😄)

@Pierre-Sassoulas Pierre-Sassoulas enabled auto-merge (rebase) October 12, 2025 14:51
@Pierre-Sassoulas Pierre-Sassoulas changed the title Release branch 4.0 Release branch for 4.0.0 Oct 12, 2025
@jacobtylerwalls
Copy link
Member

I get these errors:

/Users/jwalls/pylint/doc/user_guide/messages/error/continue-in-finally.rst:26: WARNING: Include file '/Users/jwalls/pylint/doc/data/messages/c/continue-in-finally/pylintrc' not found or reading it failed [docutils]
/Users/jwalls/pylint/doc/user_guide/messages/warning/continue-in-finally.rst:4: WARNING: duplicate label continue-in-finally, other instance in /Users/jwalls/pylint/doc/user_guide/messages/error/continue-in-finally.rst
looking for now-outdated files... none found
pickling environment... done
checking consistency... /Users/jwalls/pylint/doc/user_guide/messages/error/continue-in-finally.rst: WARNING: document isn't included in any toctree [toc.not_included]

@cdce8p
Copy link
Member

cdce8p commented Oct 12, 2025

I get these errors: [...]

@jacobtylerwalls Try removing the docs cache. I just deleted the whole doc folder and restored it from git. That seemed to work.

@Pierre-Sassoulas
Copy link
Member Author

Pierre-Sassoulas commented Oct 12, 2025

I get these errors:

The data message directory keeps old generated messages, after a tox -e docs there's no removal. This morning I had fail for the scientific format checker (not yet merged, work in progress in a local branch), I solved with git clean -dfX (it probably work and it's probably cleaner / safer to just apply make clean from the doc/ directory) (edit: or what Marc said)

@Pierre-Sassoulas Pierre-Sassoulas merged commit 3de1fbc into main Oct 12, 2025
44 checks passed
@Pierre-Sassoulas Pierre-Sassoulas deleted the release-branch-4.0 branch October 12, 2025 15:10
Copy link
Contributor

🤖 According to the primer, this change has no effect on the checked open source code. 🤖🎉

This comment was generated for commit 8729244

@Pierre-Sassoulas
Copy link
Member Author

It's done : https://pypi.org/project/pylint/4.0.0/ 🎉 ! Congratulation everyone involved !

@cdce8p
Copy link
Member

cdce8p commented Oct 12, 2025

It's done : https://pypi.org/project/pylint/4.0.0/ 🎉 ! Congratulation everyone involved !

Thanks @Pierre-Sassoulas for doing the actual release 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment