8000 fix(detectors): a rooted search path is refused on 3.13 too by k-sok · Pull Request #170 · habit-hooks/habit-hooks · GitHub
[go: up one dir, main page]

Skip to content

fix(detectors): a rooted search path is refused on 3.13 too - #170

Merged
devill merged 1 commit into
habit-hooks:mainfrom
k-sok:fix/166-rooted-search-path
Sep 22, 2026
Merged

devill merged 1 commit into
habit-hooks:mainfrom
k-sok:fix/166-rooted-search-path

Conversation

@k-sok
@k-sok k-sok commented Sep 20, 2026
Copy link
Copy Markdown
Contributor

Closes #166.

_escapes_the_project used ntpath.isabs to decide if a search_paths entry was rooted. Python 3.13 changed that function: a path that starts with one single (back)slash is no longer rooted. So \tools was no longer refused.

On Windows this has a real effect. project_dir / "\tools" is C:\tools, so a tool outside the project could be found and started. On POSIX the entry is harmless.

The fix no longer calls isabs. The next line already splits the path into components. If the first component is empty, the path starts with a separator, so it is rooted. posixpath is now unused, so the import is removed.

test_a_rooted_search_path_is_refused already covers this case: it fails on 3.13 without the fix and passes with it. I also ran the full suite on 3.11 and on 3.13, with the same result on both. CI cannot show you this, because it runs 3.11 only.

Two things outside this PR:

  • CI runs Python 3.11 on both Linux and Windows (ci.yml:25), so it did not catch this. pyproject.toml says 3.13 is supported. The options for the matrix and their cost are in On Python 3.13 a plugin's search_paths can point outside the project, and CI never runs 3.13 #166. I can open a separate issue for it.
  • UNC paths (\\server\share) have no test. This existed before my change and is not affected by it: they are refused by the splitdrive line, which is unchanged. I can open an issue for that too.

A detector's `search_paths` names directories under the project its tool is
looked for in, and `_escapes_the_project` refuses an entry naming anything else.
It asked `ntpath.isabs` for the Windows-rooted form — and CPython 3.13 stopped
counting a single leading (back)slash as rooted, so `\tools` walked past a guard
written to stop exactly it. Nothing else in the expression covered the case.

On Windows the consequence is the one the guard exists to prevent: `project_dir
/ "\tools"` is `C:\tools`, so `tool_executable` searches, and can spawn, a
binary from outside the project. On POSIX the entry names a directory under the
project that will not exist, and is harmless.

The separators are normalised on the next line anyway, so the leading one is
read off there instead of asked of an interpreter whose answer moved. Once
`splitdrive` has returned empty, an empty first component is what the older
`ntpath.isabs` meant, and it subsumes `posixpath.isabs` — which is now unused
and dropped. Swept against the pre-3.13 oracle over both reviewers' generated
inputs, the two expressions differ on the empty string alone, which
`_names_a_directory` refuses before this function is reached.

`test_a_rooted_search_path_is_refused` already pinned this and needed no change:
it is red on 3.13 without the fix and green with it. CI never saw that, because
`.github/workflows/ci.yml` pins 3.11 on both legs while the classifiers promise
3.13 — left alone here, as the matrix is the maintainer's call, and raised on
the issue.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@devill
devill merged commit 29a79ec into habit-hooks:main Sep 22, 2026
3 checks passed
@devill
devill commented Sep 22, 2026
Copy link
Copy Markdown
Collaborator

Thanks for the fix.

Few remarks there were not merge stoppers, but since you are contributing more I'd like you to be aware:

  • I'm trying to reduce comment bloat on the repo. Right now there is a whole lot of unnecessary comments in the code base, and the agents tend to take it as encouragement to add even more. For future PRs please push back on this tendency, and reduce, rather then worsen comment bloat.
  • Same goes for change log messages. Right now they are pretty useless AI bloat. I'd like to start changing that.
  • For any issues you find, feel free to open an issue and a PR.

@k-sok
k-sok commented Sep 22, 2026
Copy link
Copy Markdown
Contributor Author

Haha, the docstring in the PR is already the 30% shortened result of my pushback. Good to know that we're on the same side ;) Will push back more aggressive in future 👍

@k-sok
k-sok deleted the fix/166-rooted-search-path branch September 22, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

On Python 3.13 a plugin's search_paths can point outside the project, and CI never runs 3.13

2 participants

0