Skip to content

[codex] Add Python feature mapping#2

Open
xiamx wants to merge 8 commits into
openclaw:mainfrom
xiamx:codex/python-mapper-support
Open

[codex] Add Python feature mapping#2
xiamx wants to merge 8 commits into
openclaw:mainfrom
xiamx:codex/python-mapper-support

Conversation

@xiamx
Copy link
Copy Markdown

@xiamx xiamx commented May 16, 2026

Summary

Adds first-pass Python support to clawpatch feature mapping.

This includes:

  • Python project detection from pyproject.toml, setup files, requirements, and common Python source layouts
  • package manager detection for uv, Poetry, PDM, Hatch, pip, and direct Python projects
  • conservative validation defaults for pytest, ruff, pyright, and mypy when clearly configured or declared
  • a deterministic Python mapper for project metadata, console scripts, source groups, and pytest suites
  • tests for Python mapping, command defaults, mixed-repo precedence, non-src roots, and colocated tests

Notes

Framework-specific Python route mapping for FastAPI, Flask, and Django remains out of scope for this first pass.

Validation

  • corepack pnpm typecheck
  • corepack pnpm lint
  • corepack pnpm format:check
  • corepack pnpm test

@xiamx xiamx marked this pull request as ready for review May 16, 2026 01:15
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0cc9ed57a9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/detect.ts Outdated
@xiamx xiamx force-pushed the codex/python-mapper-support branch from 0cc9ed5 to 99d8316 Compare May 16, 2026 01:52
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 65c5339720

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/detect.ts
Comment on lines +269 to +272
if (await pathExists(join(root, "pdm.lock"))) {
return "pdm";
}
return null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add Hatch runner when forming Python default commands

detectPackageManagers classifies repos with hatch.toml as using the hatch package manager, but pythonRunner only recognizes uv, poetry, and pdm, so defaults like pytest/ruff are emitted without a runner prefix. In Hatch-managed projects where tools are only available inside Hatch environments, these suggested commands will fail even though manager detection succeeded; this makes command detection internally inconsistent for the same repo.

Useful? React with 👍 / 👎.

Comment thread src/detect.ts Outdated
Comment on lines +313 to +314
const toolMatch = /^\s*\[(mypy|pyright|ruff)\]/mu.exec(source);
if (toolMatch?.[1] !== undefined) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Parse all setup.cfg tool sections before deriving commands

This reads only the first [mypy|pyright|ruff] section in setup.cfg because exec is used once on the whole file. If [mypy] appears before [ruff] (or vice versa), later tool sections are ignored, which can suppress expected defaults (for example, missing Ruff lint/format commands despite an explicit [ruff] section). Iterating all matches or checking each tool independently avoids this false negative.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43b2147fee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/mappers/python.ts
Comment on lines +185 to +188
if (await pathExists(join(root, "pdm.lock"))) {
return "pdm run pytest";
}
return "pytest";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prefix Hatch-managed test commands with hatch run

pythonTestCommand only special-cases uv.lock, poetry.lock, and pdm.lock, then falls back to plain pytest. In Hatch projects (hatch.toml present), detectProject already reports hatch run pytest, but Python feature seeds (CLI/source/test-suite tests fields) will still carry bare pytest, which can fail when pytest is only available inside Hatch environments. Add a Hatch branch here so mapper test commands stay executable and consistent with detected defaults.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ebc27108e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/detect.ts
Comment on lines +310 to +314
for (const file of ["requirements.txt", "setup.cfg"]) {
if (await pathExists(join(root, file))) {
const source = await readFile(join(root, file), "utf8");
for (const dependency of pythonRequirementNames(source)) {
info.dependencies.add(dependency);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Ignore setup.cfg extras keys in dependency detection

The setup.cfg path currently runs every line through pythonRequirementNames, so extras group keys (for example [options.extras_require] entries like ruff = ... or pytest = ...) are treated as installed dependencies even when those packages are not declared. In that case pythonDefaultCommands will incorrectly enable ruff/pytest defaults for projects that only define similarly named extras groups, which violates the intended conservative command detection.

Useful? React with 👍 / 👎.

Comment thread src/mappers/python.ts
Comment on lines +194 to +200
async function dependencyFileHas(root: string, dependency: string): Promise<boolean> {
for (const file of ["requirements.txt", "setup.cfg"]) {
if (!(await pathExists(join(root, file)))) {
continue;
}
const source = await readFile(join(root, file), "utf8");
if (requirementNames(source).has(dependency)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop inferring pytest from setup.cfg group names

The mapper’s dependencyFileHas checks setup.cfg with requirementNames, which also interprets extras group keys as dependencies. A project with [options.extras_require] and a group named pytest will get pytest test commands in mapped features even if pytest is not installed or configured, causing non-executable suggested test commands.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f6b42d397b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/mappers/python.ts
Comment on lines +436 to +437
[...dirs].some((dir) => pathMatchesPrefix(test, dir)) ||
(fileStems.has(testStem) && /^(tests?|__tests__)\//u.test(test))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Associate root tests when source file is at repo root

associatedTests misses root-level pytest files for root modules because dirname("app.py") is ".", and pathMatchesPrefix(test, ".") never matches paths like test_app.py; the fallback stem check also requires tests to live under tests?/. In projects with flat layouts and console scripts targeting root modules, this drops obvious colocated tests from the CLI/source feature context.

Useful? React with 👍 / 👎.

Comment thread src/detect.ts
for (const dependency of pythonRequirementNames(source)) {
info.dependencies.add(dependency);
}
if (/^\s*\[tool:pytest\]|\[pytest\]/mu.test(source)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Anchor pytest section regex to avoid comment false positives

The pytest-config check uses ^\s*\[tool:pytest\]|\[pytest\], where only the first alternative is start-anchored. Any incidental "[pytest]" text (for example in comments or sample snippets) sets hasPytestConfig = true, which can incorrectly enable default pytest commands in projects that are not actually configured for pytest.

Useful? React with 👍 / 👎.

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.

2 participants