From 4a636cfa3771a42d3fc1b8aba48341d566c3475d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 04:42:25 +0000 Subject: [PATCH 1/3] Bump actions/setup-python from 6 to 7 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yaml | 2 +- .github/workflows/lint.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index dedb5f56..72e63cfa 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -25,7 +25,7 @@ jobs: with: fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 + uses: actions/setup-python@v7 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 05072967..4fd107b6 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v7 - name: Install dependencies run: | python -m pip install --upgrade pip @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v7 - name: Install dependencies run: | python -m pip install --upgrade pip From 4a21ac03d0474321ef6a760ecbf754352829bdb0 Mon Sep 17 00:00:00 2001 From: Sebastian Ramacher Date: Wed, 2 Sep 2026 16:09:37 +0200 Subject: [PATCH 2/3] CI: test with 3.15 and 3.15t --- .github/workflows/build.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 72e63cfa..c7c87aed 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -19,6 +19,8 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.15" + - "3.15t" - "pypy-3.11" steps: - uses: actions/checkout@v7 From 02d86b8f187d281739caf7a6dcf8c490512fd02f Mon Sep 17 00:00:00 2001 From: Hugohong258 <282228220+Hugohong258@users.noreply.github.com> Date: Fri, 30 Oct 2026 13:20:22 +0800 Subject: [PATCH 3/3] Support absolute paths in import completion skip list --- bpython/importcompletion.py | 18 ++++++++--- bpython/test/test_importcompletion.py | 34 +++++++++++++++++++++ doc/sphinx/source/configuration-options.rst | 8 ++++- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/bpython/importcompletion.py b/bpython/importcompletion.py index e22b61f6..e9bff7fd 100644 --- a/bpython/importcompletion.py +++ b/bpython/importcompletion.py @@ -162,12 +162,24 @@ def complete(self, cursor_offset: int, line: str) -> set[str] | None: else: return None + def _is_skipped(self, path: Path) -> bool: + for pattern in self.skiplist: + if Path(pattern).is_absolute(): + if any( + fnmatch.fnmatch(str(parent), pattern) + for parent in (path, *path.parents) + ): + return True + elif fnmatch.fnmatch(path.name, pattern): + return True + return False + def find_modules(self, path: Path) -> Generator[str | None, None, None]: """Find all modules (and packages) for a given directory.""" if not path.is_dir(): # Perhaps a zip file return - if any(fnmatch.fnmatch(path.name, entry) for entry in self.skiplist): + if self._is_skipped(path): # Path is on skiplist return @@ -177,9 +189,7 @@ def find_modules(self, path: Path) -> Generator[str | None, None, None]: if p.name.startswith(".") or p.name == "__pycache__": # Impossible to import from names starting with . and we can skip __pycache__ continue - elif any( - fnmatch.fnmatch(p.name, entry) for entry in self.skiplist - ): + elif self._is_skipped(p): # Path is on skiplist continue elif not any(p.name.endswith(suffix) for suffix in SUFFIXES): diff --git a/bpython/test/test_importcompletion.py b/bpython/test/test_importcompletion.py index 814d3c31..bc513a5c 100644 --- a/bpython/test/test_importcompletion.py +++ b/bpython/test/test_importcompletion.py @@ -192,6 +192,40 @@ def test_simple_symbolic_link_loop(self): self.assertFalse(filepaths) +class TestSkiplist(unittest.TestCase): + def test_absolute_paths(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory).resolve() + for name in ("first", "second"): + (root / name).mkdir() + (root / name / "__init__.py").touch() + (root / name / "inside.py").touch() + + cases = ( + ([root], str(root), set()), + ([root], str(root / "first"), {"second", "second.inside"}), + ([root / "first"], str(root), set()), + ) + for paths, skip, expected in cases: + with self.subTest(paths=paths, skip=skip): + gatherer = ModuleGatherer(paths, [skip]) + while gatherer.find_coroutine(): + pass + self.assertEqual(gatherer.modules, expected) + + def test_relative_name_pattern_remains_supported(self): + with tempfile.TemporaryDirectory() as directory: + root = Path(directory).resolve() + for name in ("first", "second"): + (root / name).mkdir() + (root / name / "__init__.py").touch() + (root / name / "inside.py").touch() + gatherer = ModuleGatherer([root], ["f*"]) + while gatherer.find_coroutine(): + pass + self.assertEqual(gatherer.modules, {"second", "second.inside"}) + + class TestBugReports(unittest.TestCase): def test_issue_847(self): with tempfile.TemporaryDirectory() as import_test_folder: diff --git a/doc/sphinx/source/configuration-options.rst b/doc/sphinx/source/configuration-options.rst index 1521542e..3e8fb0cf 100644 --- a/doc/sphinx/source/configuration-options.rst +++ b/doc/sphinx/source/configuration-options.rst @@ -186,7 +186,13 @@ Whether to use Unicode characters to draw boxes (default: True). import_completion_skiplist ^^^^^^^^^^^^^^^^^^^^^^^^^^ -A `:`-seperated list of patterns to skip when processing modules for import completion. +A ``:``-separated list of patterns to skip when processing modules for import +completion. A name pattern such as ``node_modules`` or ``build*`` matches names +at any level. On POSIX systems, an absolute path such as ``/home/user/projects`` +skips that directory and its descendants, including when a descendant is itself +on the module search path. Paths are matched against resolved filesystem paths. +The colon separator means that Windows drive-letter paths cannot be specified +in this option. .. versionadded:: 0.21