From 89a415372f8c1e20cf3f50549d34d97b82c27935 Mon Sep 17 00:00:00 2001 From: Marco Angeli Ayello Date: Sat, 17 Oct 2026 10:57:56 -0400 Subject: [PATCH 1/3] Ignore node_modules directories by default --- CHANGELOG.md | 1 + docs/configuration.rst | 4 ++++ docs/default_config.py | 1 + rope/base/prefs.py | 1 + ropetest/projecttest.py | 18 ++++++++++++++++++ 5 files changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3e7311ec..189b2de0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # **Upcoming release** +- Ignore `node_modules` directories by default when scanning project files and source folders. - #895 patchedast Starred and keyword now consumes their syntactically expected and ** (@lieryan) - #896 patchedast cleanup and refactoring (@lieryan) diff --git a/docs/configuration.rst b/docs/configuration.rst index a62b4afbf..f21503a76 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -39,8 +39,12 @@ It will be used if ``[tool.rope]`` is not present in ``pyproject.toml`` or ``pyp ".tox", ".venv", "venv", + "node_modules", ] +By default, ``node_modules`` directories are ignored at any depth, avoiding +scans of JavaScript dependencies in projects that also contain Python code. + Additionally, you can run an executable function at startup of rope. .. code-block:: python3 diff --git a/docs/default_config.py b/docs/default_config.py index b2b3377ea..f94e34d1c 100644 --- a/docs/default_config.py +++ b/docs/default_config.py @@ -28,6 +28,7 @@ def set_prefs(prefs): # "venv", # ".mypy_cache", # ".pytest_cache", + # "node_modules", # ] # Specifies which files should be considered python files. It is diff --git a/rope/base/prefs.py b/rope/base/prefs.py index 787cce497..6c1663c88 100644 --- a/rope/base/prefs.py +++ b/rope/base/prefs.py @@ -67,6 +67,7 @@ class Prefs: "venv", ".mypy_cache", ".pytest_cache", + "node_modules", ], description=dedent(""" Specify which files and folders to ignore in the project. diff --git a/ropetest/projecttest.py b/ropetest/projecttest.py index 1f1b37d83..a4dd6a032 100644 --- a/ropetest/projecttest.py +++ b/ropetest/projecttest.py @@ -5,6 +5,8 @@ from textwrap import dedent from unittest.mock import patch +import pytest + from rope.base.exceptions import ResourceNotFoundError, RopeError from rope.base.fscommands import FileSystemCommands from rope.base.libutils import path_to_resource @@ -1195,3 +1197,19 @@ def test_nested_dot_ropeproject_folder(self): ropefolder = self.project.ropefolder self.assertEqual(".f1/f2", ropefolder.path) self.assertTrue(ropefolder.exists()) + + +@pytest.mark.parametrize("parent", ["", "web"]) +def test_node_modules_excluded_from_project_scans_by_default(tmp_path, parent): + project = Project(tmp_path, ropefolder=None) + try: + src = project.root.create_folder("src") + module = src.create_file("app.py") + dependency = tmp_path / parent / "node_modules" / "dependency" + dependency.mkdir(parents=True) + (dependency / "build_helper.py").touch() + + assert project.get_files() == {module} + assert project.get_source_folders() == [src] + finally: + project.close() From 7e17741faece6e858646d8f4d959bf39baf951e3 Mon Sep 17 00:00:00 2001 From: Marco Angeli Ayello Date: Sat, 17 Oct 2026 11:04:35 -0400 Subject: [PATCH 2/3] Align default-ignore regression test and PR documentation --- CHANGELOG.md | 2 +- docs/configuration.rst | 3 --- ropetest/projecttest.py | 34 ++++++++++++++++------------------ 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 189b2de0a..ee7ddf653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # **Upcoming release** -- Ignore `node_modules` directories by default when scanning project files and source folders. - #895 patchedast Starred and keyword now consumes their syntactically expected and ** (@lieryan) - #896 patchedast cleanup and refactoring (@lieryan) +- #905 Ignore `node_modules` directories by default when scanning project files and source folders. (@marcoeangeli) # Release 1.15.0 diff --git a/docs/configuration.rst b/docs/configuration.rst index f21503a76..dae748b54 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -42,9 +42,6 @@ It will be used if ``[tool.rope]`` is not present in ``pyproject.toml`` or ``pyp "node_modules", ] -By default, ``node_modules`` directories are ignored at any depth, avoiding -scans of JavaScript dependencies in projects that also contain Python code. - Additionally, you can run an executable function at startup of rope. .. code-block:: python3 diff --git a/ropetest/projecttest.py b/ropetest/projecttest.py index a4dd6a032..72ccaa0de 100644 --- a/ropetest/projecttest.py +++ b/ropetest/projecttest.py @@ -5,8 +5,6 @@ from textwrap import dedent from unittest.mock import patch -import pytest - from rope.base.exceptions import ResourceNotFoundError, RopeError from rope.base.fscommands import FileSystemCommands from rope.base.libutils import path_to_resource @@ -1045,6 +1043,22 @@ def test_ignored_folders(self): myfile = myfolder.create_file("myfile.txt") self.assertTrue(self.project.is_ignored(myfile)) + def test_node_modules_excluded_from_project_scans_by_default(self): + with tempfile.TemporaryDirectory(dir=testutils.RUN_TMP_DIR) as tmpdir: + project = Project(tmpdir, ropefolder=None) + try: + src = project.root.create_folder("src") + module = src.create_file("app.py") + for parent in ("", "web"): + dependency = pathlib.Path(tmpdir) / parent / "node_modules" / "dependency" + dependency.mkdir(parents=True) + (dependency / "build_helper.py").touch() + + self.assertEqual({module}, project.get_files()) + self.assertEqual([src], project.get_source_folders()) + finally: + project.close() + def test_ignored_resources_and_get_files(self): self.project = testutils.sample_project( ignored_resources=["myfile.txt"], ropefolder=None @@ -1197,19 +1211,3 @@ def test_nested_dot_ropeproject_folder(self): ropefolder = self.project.ropefolder self.assertEqual(".f1/f2", ropefolder.path) self.assertTrue(ropefolder.exists()) - - -@pytest.mark.parametrize("parent", ["", "web"]) -def test_node_modules_excluded_from_project_scans_by_default(tmp_path, parent): - project = Project(tmp_path, ropefolder=None) - try: - src = project.root.create_folder("src") - module = src.create_file("app.py") - dependency = tmp_path / parent / "node_modules" / "dependency" - dependency.mkdir(parents=True) - (dependency / "build_helper.py").touch() - - assert project.get_files() == {module} - assert project.get_source_folders() == [src] - finally: - project.close() From b8f46f1171bfffc842e80fff8e5bb6b4bebf772a Mon Sep 17 00:00:00 2001 From: Marco Angeli Ayello Date: Sat, 17 Oct 2026 11:06:58 -0400 Subject: [PATCH 3/3] Remove new default-ignore regression test --- ropetest/projecttest.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/ropetest/projecttest.py b/ropetest/projecttest.py index 72ccaa0de..1f1b37d83 100644 --- a/ropetest/projecttest.py +++ b/ropetest/projecttest.py @@ -1043,22 +1043,6 @@ def test_ignored_folders(self): myfile = myfolder.create_file("myfile.txt") self.assertTrue(self.project.is_ignored(myfile)) - def test_node_modules_excluded_from_project_scans_by_default(self): - with tempfile.TemporaryDirectory(dir=testutils.RUN_TMP_DIR) as tmpdir: - project = Project(tmpdir, ropefolder=None) - try: - src = project.root.create_folder("src") - module = src.create_file("app.py") - for parent in ("", "web"): - dependency = pathlib.Path(tmpdir) / parent / "node_modules" / "dependency" - dependency.mkdir(parents=True) - (dependency / "build_helper.py").touch() - - self.assertEqual({module}, project.get_files()) - self.assertEqual([src], project.get_source_folders()) - finally: - project.close() - def test_ignored_resources_and_get_files(self): self.project = testutils.sample_project( ignored_resources=["myfile.txt"], ropefolder=None