From e127630cea37fafd6ccdc754661a190fab128f7f Mon Sep 17 00:00:00 2001 From: "pylint-backport[bot]" <212256041+pylint-backport[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 07:19:46 +0000 Subject: [PATCH 1/4] [Backport maintenance/4.0.x] feat: add HTTPMethod enum support to brain_http (#2879) feat: add HTTPMethod enum support to brain_http (#2878) Closes #2877 (cherry picked from commit ff7205c1616df44119ef1a598c95b31977ba8620) Co-authored-by: Joao Faria --- ChangeLog | 4 ++++ astroid/brain/brain_http.py | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e317c5d3d..fa9e5bcaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,10 @@ What's New in astroid 4.1.0? Release date: TBA +* Add ``HTTPMethod`` enum support to brain module for Python 3.11+. + + Closes #4135 + What's New in astroid 4.0.2? ============================ diff --git a/astroid/brain/brain_http.py b/astroid/brain/brain_http.py index e4b6bca63..9802c0f7e 100644 --- a/astroid/brain/brain_http.py +++ b/astroid/brain/brain_http.py @@ -14,10 +14,21 @@ def _http_transform() -> nodes.Module: code = textwrap.dedent( """ - from enum import IntEnum + from enum import IntEnum, StrEnum from collections import namedtuple _HTTPStatus = namedtuple('_HTTPStatus', 'value phrase description') + class HTTPMethod(StrEnum): + GET = "GET" + POST = "POST" + PUT = "PUT" + DELETE = "DELETE" + HEAD = "HEAD" + OPTIONS = "OPTIONS" + PATCH = "PATCH" + TRACE = "TRACE" + CONNECT = "CONNECT" + class HTTPStatus(IntEnum): @property From d71bfacb94c934753c0600a9963aa77697f5c1bb Mon Sep 17 00:00:00 2001 From: "pylint-backport[bot]" <212256041+pylint-backport[bot]@users.noreply.github.com> Date: Sat, 8 Nov 2025 08:43:29 +0000 Subject: [PATCH 2/4] [Backport maintenance/4.0.x] Handle FunctionDef blockstart_tolineno edge cases (#2881) Handle FunctionDef blockstart_tolineno edge cases (#2880) Getting the lineno of the start of the block for function definition(`FunctionDef.blockstart_tolineno`) can be quite tricky. Take below example: ```python # Case A def foo(bar: str) -> None: pass # should returns line=1 # Case B def foo( bar:str): pass # should returns line=2 # Case C def foo( bar:str ) -> None: pass # should returns line=3 # Case D def foo( bar:str ): # should returns line=3 pass ``` Currently we only handled Case A, B. With this commit we can cover case C. But for Case D, we will need a better solution (cherry picked from commit 8fa18c7fe307bc86b53c1ba442a96cfb26b9ed8f) Co-authored-by: Low, Zhi Hao --- astroid/nodes/scoped_nodes/scoped_nodes.py | 2 ++ tests/test_scoped_nodes.py | 40 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/astroid/nodes/scoped_nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes/scoped_nodes.py index 885562393..f232db32b 100644 --- a/astroid/nodes/scoped_nodes/scoped_nodes.py +++ b/astroid/nodes/scoped_nodes/scoped_nodes.py @@ -1401,6 +1401,8 @@ def blockstart_tolineno(self): :type: int """ + if self.returns: + return self.returns.tolineno return self.args.tolineno def implicit_parameters(self) -> Literal[0, 1]: diff --git a/tests/test_scoped_nodes.py b/tests/test_scoped_nodes.py index c95f53fd3..875ee057b 100644 --- a/tests/test_scoped_nodes.py +++ b/tests/test_scoped_nodes.py @@ -982,6 +982,46 @@ def foo(): with pytest.raises(AttributeInferenceError): func.getattr("") + @staticmethod + def test_blockstart_tolineno() -> None: + code = textwrap.dedent( + """\ + def f1(bar: str) -> None: #@ + pass + + def f2( #@ + bar: str) -> None: + pass + + def f3( #@ + bar: str + ) -> None: + pass + + def f4( #@ + bar: str + ): + pass + + def f5( #@ + bar: str): + pass + """ + ) + ast_nodes: list[nodes.FunctionDef] = builder.extract_node(code) # type: ignore[assignment] + assert len(ast_nodes) == 5 + + assert ast_nodes[0].blockstart_tolineno == 1 + + assert ast_nodes[1].blockstart_tolineno == 5 + + assert ast_nodes[2].blockstart_tolineno == 10 + + # Unimplemented, will return line 14 for now. + # assert ast_nodes[3].blockstart_tolineno == 15 + + assert ast_nodes[4].blockstart_tolineno == 19 + class ClassNodeTest(ModuleLoader, unittest.TestCase): def test_dict_interface(self) -> None: From a5ce4b06033ef92acdd3d8cca1df3f947936e26d Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Mon, 27 Oct 2025 21:05:31 +0100 Subject: [PATCH 3/4] Upgrade pylint to 4.0.0, add mypy to the allowlist --- astroid/interpreter/_import/util.py | 1 - pylintrc | 2 +- requirements_dev.txt | 2 +- tests/test_raw_building.py | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/astroid/interpreter/_import/util.py b/astroid/interpreter/_import/util.py index 976fc005b..8b8725f91 100644 --- a/astroid/interpreter/_import/util.py +++ b/astroid/interpreter/_import/util.py @@ -83,7 +83,6 @@ def is_namespace(modname: str) -> bool: # Repair last_submodule_search_locations if last_submodule_search_locations: - # pylint: disable=unsubscriptable-object last_item = last_submodule_search_locations[-1] # e.g. for failure example above, add 'a/b' and keep going # so that find_spec('a.b.c', path=['a', 'a/b']) succeeds diff --git a/pylintrc b/pylintrc index 63db8dd52..2957fffb6 100644 --- a/pylintrc +++ b/pylintrc @@ -42,7 +42,7 @@ unsafe-load-any-extension=no # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code -extension-pkg-whitelist= +extension-pkg-whitelist=mypy # Minimum supported python version py-version = 3.10.0 diff --git a/requirements_dev.txt b/requirements_dev.txt index 77a6fd9f6..9f5ea5659 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -3,5 +3,5 @@ # Tools used during development, prefer running these with pre-commit black pre-commit -pylint>=3.2.7 +pylint>=4.0.0 ruff diff --git a/tests/test_raw_building.py b/tests/test_raw_building.py index bb7c733e5..969178c30 100644 --- a/tests/test_raw_building.py +++ b/tests/test_raw_building.py @@ -10,7 +10,7 @@ from __future__ import annotations -import _io +import _io # pylint: disable=wrong-import-order import logging import os import sys From a068430290b375a06f6eccdcea7d5026995172ba Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Sun, 9 Nov 2025 21:29:42 +0100 Subject: [PATCH 4/4] Bump astroid to 4.0.2, update changelog --- CONTRIBUTORS.txt | 2 +- ChangeLog | 15 ++++++++++++--- astroid/__pkginfo__.py | 2 +- tbump.toml | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 65c6499d2..67068c0c0 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -14,8 +14,8 @@ Ex-maintainers Maintainers ----------- - Pierre Sassoulas -- Jacob Walls - Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com> +- Jacob Walls - Marc Mueller <30130371+cdce8p@users.noreply.github.com> - Hippo91 - Bryce Guinta diff --git a/ChangeLog b/ChangeLog index fa9e5bcaf..60bca91fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,16 +8,25 @@ What's New in astroid 4.1.0? Release date: TBA -* Add ``HTTPMethod`` enum support to brain module for Python 3.11+. - Closes #4135 +What's New in astroid 4.0.3? +============================ +Release date: TBA + What's New in astroid 4.0.2? ============================ -Release date: TBA +Release date: 2025-11-09 + +* Handle FunctionDef blockstart_tolineno edge cases correctly. + Refs #2880 + +* Add ``HTTPMethod`` enum support to brain module for Python 3.11+. + Refs pylint-dev/pylint#10624 + Closes #2877 What's New in astroid 4.0.1? ============================ diff --git a/astroid/__pkginfo__.py b/astroid/__pkginfo__.py index 465f2f8ad..8ef239549 100644 --- a/astroid/__pkginfo__.py +++ b/astroid/__pkginfo__.py @@ -2,5 +2,5 @@ # For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE # Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt -__version__ = "4.0.1" +__version__ = "4.0.2" version = __version__ diff --git a/tbump.toml b/tbump.toml index 358a9a1c0..251afc5c6 100644 --- a/tbump.toml +++ b/tbump.toml @@ -1,7 +1,7 @@ github_url = "https://github.com/pylint-dev/astroid" [version] -current = "4.0.1" +current = "4.0.2" regex = ''' ^(?P0|[1-9]\d*) \.