From 39a2afd682a83f00a3d1b74657b93bfb8f0719b5 Mon Sep 17 00:00:00 2001 From: CareF Date: Wed, 1 Nov 2023 00:31:34 +0800 Subject: [PATCH 1/6] [bugfix] Find files with ./ as input with a __init__.py file --- doc/whatsnew/fragments/9210.bugfix | 4 ++ pylint/lint/expand_modules.py | 3 +- tests/lint/unittest_expand_modules.py | 71 ++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 doc/whatsnew/fragments/9210.bugfix diff --git a/doc/whatsnew/fragments/9210.bugfix b/doc/whatsnew/fragments/9210.bugfix new file mode 100644 index 0000000000..ca9bf414b3 --- /dev/null +++ b/doc/whatsnew/fragments/9210.bugfix @@ -0,0 +1,4 @@ +Fix bug for not being able to walk through files when work on `./` as input +at a directory with a `__init__.py` file. + +Closes #9210 diff --git a/pylint/lint/expand_modules.py b/pylint/lint/expand_modules.py index 1e8fd032f8..d42c798c9d 100644 --- a/pylint/lint/expand_modules.py +++ b/pylint/lint/expand_modules.py @@ -144,8 +144,9 @@ def expand_modules( ) if has_init or is_namespace or is_directory: for subfilepath in modutils.get_module_files( - os.path.dirname(filepath), ignore_list, list_all=is_namespace + os.path.dirname(filepath) or ".", ignore_list, list_all=is_namespace ): + subfilepath = os.path.normpath(subfilepath) if filepath == subfilepath: continue if _is_in_ignore_list_re( diff --git a/tests/lint/unittest_expand_modules.py b/tests/lint/unittest_expand_modules.py index 7120a17480..19d0054132 100644 --- a/tests/lint/unittest_expand_modules.py +++ b/tests/lint/unittest_expand_modules.py @@ -4,8 +4,12 @@ from __future__ import annotations -import re +from contextlib import contextmanager +import copy +import os from pathlib import Path +import re +from typing import Iterator import pytest @@ -28,7 +32,8 @@ def test__is_in_ignore_list_re_match() -> None: TEST_DIRECTORY = Path(__file__).parent.parent INIT_PATH = str(TEST_DIRECTORY / "lint/__init__.py") -EXPAND_MODULES = str(TEST_DIRECTORY / "lint/unittest_expand_modules.py") +EXPAND_MODULES_BASE = "unittest_expand_modules.py" +EXPAND_MODULES = str(TEST_DIRECTORY / "lint" / EXPAND_MODULES_BASE) this_file = { "basename": "lint.unittest_expand_modules", "basepath": EXPAND_MODULES, @@ -37,6 +42,14 @@ def test__is_in_ignore_list_re_match() -> None: "path": EXPAND_MODULES, } +this_file_relative_to_parent = { + "basename": "lint.unittest_expand_modules", + "basepath": EXPAND_MODULES_BASE, + "isarg": True, + "name": "lint.unittest_expand_modules", + "path": EXPAND_MODULES_BASE, +} + this_file_from_init = { "basename": "lint", "basepath": INIT_PATH, @@ -117,6 +130,25 @@ def _list_expected_package_modules( ) +def _list_expected_package_modules_relative() -> tuple[dict[str, object], ...]: + """Generates reusable list of modules for our package with relative path input.""" + abs_result = copy.deepcopy(_list_expected_package_modules()) + for item in abs_result: + item["basepath"] = os.path.relpath(item["basepath"], str(Path(__file__).parent)) + item["path"] = os.path.relpath(item["path"], str(Path(__file__).parent)) + return abs_result + + +@contextmanager +def pushd(path: Path) -> Iterator[str]: + prev = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(prev) + + class TestExpandModules(CheckerTestCase): """Test the expand_modules function while allowing options to be set.""" @@ -159,6 +191,41 @@ def test_expand_modules( assert modules == expected assert not errors + @pytest.mark.parametrize( + "files_or_modules,expected", + [ + ([Path(__file__).name], { + this_file_relative_to_parent["path"]: this_file_relative_to_parent + }), + ( + ['./'], + { + module["path"]: module # pylint: disable=unsubscriptable-object + for module in _list_expected_package_modules_relative() + }, + ), + ], + ) + @set_config(ignore_paths="") + def test_expand_modules_relative_path( + self, files_or_modules: list[str], expected: dict[str, ModuleDescriptionDict] + ) -> None: + """Test expand_modules with the default value of ignore-paths and relative path as input.""" + ignore_list: list[str] = [] + ignore_list_re: list[re.Pattern[str]] = [] + with pushd(Path(__file__).parent): + modules, errors = expand_modules( + files_or_modules, + [], + ignore_list, + ignore_list_re, + self.linter.config.ignore_paths, + ) + print(modules) + print(expected) + assert modules == expected + assert not errors + @pytest.mark.parametrize( "files_or_modules,expected", [ From 201756dfa2ceff9742e170f7a4373cd29224ec0c Mon Sep 17 00:00:00 2001 From: CareF Date: Wed, 1 Nov 2023 01:01:41 +0800 Subject: [PATCH 2/6] Fix mypy type --- tests/lint/unittest_expand_modules.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/lint/unittest_expand_modules.py b/tests/lint/unittest_expand_modules.py index 19d0054132..7debd0581f 100644 --- a/tests/lint/unittest_expand_modules.py +++ b/tests/lint/unittest_expand_modules.py @@ -4,11 +4,11 @@ from __future__ import annotations -from contextlib import contextmanager import copy import os -from pathlib import Path import re +from contextlib import contextmanager +from pathlib import Path from typing import Iterator import pytest @@ -134,13 +134,15 @@ def _list_expected_package_modules_relative() -> tuple[dict[str, object], ...]: """Generates reusable list of modules for our package with relative path input.""" abs_result = copy.deepcopy(_list_expected_package_modules()) for item in abs_result: + assert isinstance(item["basepath"], str) + assert isinstance(item["path"], str) item["basepath"] = os.path.relpath(item["basepath"], str(Path(__file__).parent)) item["path"] = os.path.relpath(item["path"], str(Path(__file__).parent)) return abs_result @contextmanager -def pushd(path: Path) -> Iterator[str]: +def pushd(path: Path) -> Iterator[None]: prev = os.getcwd() os.chdir(path) try: @@ -194,11 +196,12 @@ def test_expand_modules( @pytest.mark.parametrize( "files_or_modules,expected", [ - ([Path(__file__).name], { - this_file_relative_to_parent["path"]: this_file_relative_to_parent - }), ( - ['./'], + [Path(__file__).name], + {this_file_relative_to_parent["path"]: this_file_relative_to_parent}, + ), + ( + ["./"], { module["path"]: module # pylint: disable=unsubscriptable-object for module in _list_expected_package_modules_relative() From 40e5058934ec134c61dae1d052a808b8e91d4623 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 17:04:21 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/lint/unittest_expand_modules.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lint/unittest_expand_modules.py b/tests/lint/unittest_expand_modules.py index 7debd0581f..2d195ab446 100644 --- a/tests/lint/unittest_expand_modules.py +++ b/tests/lint/unittest_expand_modules.py @@ -136,8 +136,8 @@ def _list_expected_package_modules_relative() -> tuple[dict[str, object], ...]: for item in abs_result: assert isinstance(item["basepath"], str) assert isinstance(item["path"], str) - item["basepath"] = os.path.relpath(item["basepath"], str(Path(__file__).parent)) - item["path"] = os.path.relpath(item["path"], str(Path(__file__).parent)) + item["basepath"] = os.path.relpath(item["basepath"], str(Path(__file__).parent)) + item["path"] = os.path.relpath(item["path"], str(Path(__file__).parent)) return abs_result From 0bb97a37c5e01eae316dd7c3f30513d04fe292ec Mon Sep 17 00:00:00 2001 From: CareF Date: Wed, 1 Nov 2023 01:08:50 +0800 Subject: [PATCH 4/6] fix pylint --- tests/lint/unittest_expand_modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lint/unittest_expand_modules.py b/tests/lint/unittest_expand_modules.py index 2d195ab446..9ad0cc6244 100644 --- a/tests/lint/unittest_expand_modules.py +++ b/tests/lint/unittest_expand_modules.py @@ -7,9 +7,9 @@ import copy import os import re +from collections.abc import Iterator from contextlib import contextmanager from pathlib import Path -from typing import Iterator import pytest From 371149240ba009dde44edbb0441314d189bf82df Mon Sep 17 00:00:00 2001 From: Ming Lyu Date: Thu, 7 Dec 2023 09:59:17 +0800 Subject: [PATCH 5/6] Update tests/lint/unittest_expand_modules.py Co-authored-by: Pierre Sassoulas --- tests/lint/unittest_expand_modules.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/lint/unittest_expand_modules.py b/tests/lint/unittest_expand_modules.py index 9ad0cc6244..34133d759b 100644 --- a/tests/lint/unittest_expand_modules.py +++ b/tests/lint/unittest_expand_modules.py @@ -224,8 +224,6 @@ def test_expand_modules_relative_path( ignore_list_re, self.linter.config.ignore_paths, ) - print(modules) - print(expected) assert modules == expected assert not errors From d804da2fb21224e7aa6e537bcd80ad43e7963724 Mon Sep 17 00:00:00 2001 From: Ming Lyu Date: Thu, 7 Dec 2023 19:46:34 +0800 Subject: [PATCH 6/6] Update doc/whatsnew/fragments/9210.bugfix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com> --- doc/whatsnew/fragments/9210.bugfix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/whatsnew/fragments/9210.bugfix b/doc/whatsnew/fragments/9210.bugfix index ca9bf414b3..c1d0835712 100644 --- a/doc/whatsnew/fragments/9210.bugfix +++ b/doc/whatsnew/fragments/9210.bugfix @@ -1,4 +1,4 @@ -Fix bug for not being able to walk through files when work on `./` as input -at a directory with a `__init__.py` file. +Fix a bug where pylint was unable to walk recursively through a directory if the +directory has an `__init__.py` file. Closes #9210