René's URL Explorer Experiment
Title: Update Pylint to v4 (major) by renovate[bot] · Pull Request #5000 · python-telegram-bot/python-telegram-bot · GitHub
Open Graph Title: Update Pylint to v4 (major) by renovate[bot] · Pull Request #5000 · python-telegram-bot/python-telegram-bot
X Title: Update Pylint to v4 (major) by renovate[bot] · Pull Request #5000 · python-telegram-bot/python-telegram-bot
Description: This PR contains the following updates:
Package
Type
Update
Change
Age
Confidence
PyCQA/pylint
repository
major
v3.3.9 -> v4.0.1
pylint (changelog)
dependency-groups
major
==3.3.9 -> ==4.0.1
Note: The pre-commit manager in Renovate is not supported by the pre-commit maintainers or community. Please do not report any problems there, instead create a Discussion in the Renovate repository if you have any questions.
Release Notes
PyCQA/pylint (PyCQA/pylint)
v4.0.1
Compare Source
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
Fix false-positive for bare-name-capture-pattern if a case guard is used.
Closes #10647
Check enums created with the Enum() functional syntax to pass against the
--class-rgx for the invalid-name check, like other enums.
Closes #10660
v4.0.0
Compare Source
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
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
The unused pylintrc argument to PyLinter.__init__() is deprecated
and will be removed.
Refs #6052
Commented out code blocks such as # bar() # TODO: remove dead code will no longer emit fixme.
Refs #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
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
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
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
Removed support for nmp.NaN alias for numpy.NaN being recognized in ':ref:nan-comparison'. Use np or numpy instead.
Refs #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
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
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
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
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
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
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
Enhanced support for @property decorator in pyreverse to correctly display return types of annotated properties when generating class diagrams.
Closes #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
Handle deferred evaluation of annotations in Python 3.14.
Closes #10149
Enhanced pyreverse to properly detect aggregations for comprehensions (list, dict, set, generator).
Closes #10236
pyreverse: add support for colorized output when using output format mmd (MermaidJS) and html.
Closes #10242
pypy 3.11 is now officially supported.
Refs #10287
Add support for Python 3.14.
Refs #10467
Add naming styles for ParamSpec and TypeVarTuple that align with the TypeVar style.
Refs #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
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
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
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
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
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
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
Fix :ref:no-name-in-module for members of concurrent.futures with Python 3.14.
Closes #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
Match cases are now counted as edges in the McCabe graph and will increase the complexity accordingly.
Refs #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
Fix false negative where function-redefined (E0102) was not reported for functions with a leading underscore.
Closes #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
Fix false negative for used-before-assignment when a function is defined inside a TYPE_CHECKING guard block and used later.
Closes #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
Fix false negative for deprecated-module when a __import__ method is used instead of import sentence.
Refs #10453
Count match cases for too-many-branches check.
Refs #10542
Fix false-negative where :ref:unused-import was not reported for names referenced in a preceding global statement.
Refs #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
Fixed unidiomatic-typecheck only checking left-hand side.
Closes #10217
Fix a crash caused by malformed format strings when using .format with keyword arguments.
Closes #10282
Fix false positive inconsistent-return-statements when using quit() or exit() functions.
Closes #10508
Fix a crash in :ref:nested-min-max when using builtins.min or builtins.max
instead of min or max directly.
Closes #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
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
Internal Changes
Modified test framework to allow for different test output for different Python versions.
Refs #10382
pylint-dev/pylint (pylint)
v4.0.1
Compare Source
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
Fix false-positive for bare-name-capture-pattern if a case guard is used.
Closes #10647
Check enums created with the Enum() functional syntax to pass against the
--class-rgx for the invalid-name check, like other enums.
Closes #10660
v4.0.0
Compare Source
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
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
The unused pylintrc argument to PyLinter.__init__() is deprecated
and will be removed.
Refs #6052
Commented out code blocks such as # bar() # TODO: remove dead code will no longer emit fixme.
Refs #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
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
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
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
Removed support for nmp.NaN alias for numpy.NaN being recognized in ':ref:nan-comparison'. Use np or numpy instead.
Refs #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
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
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
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
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
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
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
Enhanced support for @property decorator in pyreverse to correctly display return types of annotated properties when generating class diagrams.
Closes #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
Handle deferred evaluation of annotations in Python 3.14.
Closes #10149
Enhanced pyreverse to properly detect aggregations for comprehensions (list, dict, set, generator).
Closes #10236
pyreverse: add support for colorized output when using output format mmd (MermaidJS) and html.
Closes #10242
pypy 3.11 is now officially supported.
Refs #10287
Add support for Python 3.14.
Refs #10467
Add naming styles for ParamSpec and TypeVarTuple that align with the TypeVar style.
Refs #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
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
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
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
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
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
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
Fix :ref:no-name-in-module for members of concurrent.futures with Python 3.14.
Closes #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
Match cases are now counted as edges in the McCabe graph and will increase the complexity accordingly.
Refs #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
Fix false negative where function-redefined (E0102) was not reported for functions with a leading underscore.
Closes #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
Fix false negative for used-before-assignment when a function is defined inside a TYPE_CHECKING guard block and used later.
Closes #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
Fix false negative for deprecated-module when a __import__ method is used instead of import sentence.
Refs #10453
Count match cases for too-many-branches check.
Refs #10542
Fix false-negative where :ref:unused-import was not reported for names referenced in a preceding global statement.
Refs #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
Fixed unidiomatic-typecheck only checking left-hand side.
Closes #10217
Fix a crash caused by malformed format strings when using .format with keyword arguments.
Closes #10282
Fix false positive inconsistent-return-statements when using quit() or exit() functions.
Closes #10508
Fix a crash in :ref:nested-min-max when using builtins.min or builtins.max
instead of min or max directly.
Closes #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
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
Internal Changes
Modified test framework to allow for different test output for different Python versions.
Refs #10382
Configuration
📅 Schedule: Branch creation - Only on Sunday and Saturday ( * * * * 0,6 ) (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
If you want to rebase/retry this PR, check this box
This PR was generated by Mend Renovate. View the repository job log.
Open Graph Description: This PR contains the following updates:
Package
Type
Update
Change
Age
Confidence
PyCQA/pylint
repository
major
v3.3.9 -> v4.0.1
pylint (changelog)
dependency-groups
major
==3.3.9 -&g...
X Description: This PR contains the following updates:
Package
Type
Update
Change
Age
Confidence
PyCQA/pylint
repository
major
v3.3.9 -> v4.0.1
pylint (changelog)
dependency-groups
major
==3.3.9...
Opengraph URL: https://github.com/python-telegram-bot/python-telegram-bot/pull/5000
X: @github
direct link
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:ba84d9f9-9f76-62eb-ac89-b49e5bc4b04a |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | 8F2C:A0835:8A8B6CC:BB5B71C:6A5E56B5 |
| html-safe-nonce | 9738f9f3341fe9ef1fdb9256540ddfc7a3a21f1d422d689899ebb33869a046a9 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4RjJDOkEwODM1OjhBOEI2Q0M6QkI1QjcxQzo2QTVFNTZCNSIsInZpc2l0b3JfaWQiOiIzNjc1Nzc5Nzk4NTAzNjc1NTczIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | e3bcc03fca22641957104f7ee7eb02b3f72d4a2ee8c724fed906b12bdb79026d |
| hovercard-subject-tag | pull_request:2908084623 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | ///pull_requests/show/files |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/python-telegram-bot/python-telegram-bot/pull/5000/files |
| twitter:image | https://avatars.githubusercontent.com/in/2740?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/in/2740?s=400&v=4 |
| og:image:alt | This PR contains the following updates:
Package
Type
Update
Change
Age
Confidence
PyCQA/pylint
repository
major
v3.3.9 -> v4.0.1
pylint (changelog)
dependency-groups
major
==3.3.9 -&g... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 7034b9f0130cdfcbd93bbcf3e8c0f4cc3007af54a2804bfd31f70d472b22852b |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/python-telegram-bot/python-telegram-bot git https://github.com/python-telegram-bot/python-telegram-bot.git |
| octolytics-dimension-user_id | 16178365 |
| octolytics-dimension-user_login | python-telegram-bot |
| octolytics-dimension-repository_id | 38696925 |
| octolytics-dimension-repository_nwo | python-telegram-bot/python-telegram-bot |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 38696925 |
| octolytics-dimension-repository_network_root_nwo | python-telegram-bot/python-telegram-bot |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | e75cd8524a0802713165f77a0088258ff9261683 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width
URLs of crawlers that visited me.