For AI agentsA Markdown index of these docs is at /llms.txt. Every page is also Markdown: add .md to its address.

Agent Rules / Names and imports

Why do star imports make my coding agent miss callers?

Rule AR-01

Import names explicitly. Don't use from module import * in code that agents edit.

A star import binds every public name of another module without writing any of them down. A coding agent looking for who uses parse_date finds no import parse_date line in the files that call it. If the agent changes parse_date, those calls are easy to miss. Name each import, and every tool can trace the use back to its definition.

Why it happens

The Python language reference defines exactly what the star form binds:

  • With __all__ defined, the star import binds exactly the names in __all__.
  • Without __all__, it binds every name in the module that doesn't start with an underscore. That includes names the module itself imported from elsewhere.
  • The star form is only allowed at module level; inside a function or class it's a SyntaxError.

The result is that the list of names arriving in a file is decided in another file, possibly by a computed __all__ and possibly differently after the next edit there. A reader of the importing file, human or agent, can't see which names came from where. Tools must resolve the other module, then its __all__, before they can connect a call to its definition. When that resolution fails or is ambiguous, the call becomes a blind spot.

Two more effects make it worse in real code:

  • Silent shadowing. from a import * followed by from b import * lets b.format replace a.format with no error. Code calls whichever came last.
  • Leaked imports. Without __all__, a star import also re-exports what the source module imported (os, json, helper functions), so files start depending on names their author never meant to publish.

In TypeScript and JavaScript the closest equivalent is export * from "./x" in barrel files. See AR-02. (import * as ns from "./x" is different: every use is written ns.name, so tools can follow it.)

Bad and good

python# bad: billing/report.py from billing.dates import * from billing.money import * def monthly_total(rows): start = month_start(rows[0].when) # from dates? money? both? return format_amount(sum_rows(rows, start))
python# good: billing/report.py from billing.dates import month_start from billing.money import format_amount, sum_rows def monthly_total(rows): start = month_start(rows[0].when) return format_amount(sum_rows(rows, start))

The good version tells any reader where each name lives. Renaming month_start now has a findable import line in every file that uses it.

Trade-offs and when a star import is acceptable

  • Interactive sessions and notebooks: fine. Nobody edits them through an agent workflow.
  • **A package __init__.py that deliberately re-exports a submodule's API:** acceptable only if the submodule defines __all__. Even then, an explicit list in __init__.py is clearer (see AR-02).
  • Generated constant modules (thousands of constants): prefer import constants as c and c.NAME. It's as short at the call site and fully traceable.

Enforce it

ToolSettingWhat it catchesChecked
ruffF403 (undefined-local-with-import-star)any from x import *2026-10-30
ruffF405 (undefined-local-with-import-star-usage)names that may come from a star import2026-10-30
pyrightreportWildcardImportFromLibrary (on in strict mode)star imports from external libraries2026-10-30

In pyproject.toml:

toml[tool.ruff.lint] extend-select = ["F403", "F405"]

Rule block for AGENTS.md / CLAUDE.md

markdown- Import names explicitly (`from pkg.mod import name`). Never add `from x import *`. - When you meet an existing star import in a file you edit, replace it with explicit imports of the names the file uses, and run the linter to confirm nothing else depended on it.

Edge cases

  • **__all__ built at runtime** (__all__ = [n for n in dir() if ...]): the public names then depend on execution, so no static tool can list them. Write the list out.
  • A name defined in both modules: the later star import wins without warning. This is the source of chimera CH-10.
  • Relative star imports in packages (from .models import *): same rule. The fix is the same.

What LLMGRAPH shows

For calls through the star import, LLMGRAPH's type checker still links each call (certain); grep and readers are the ones who lose it.

References

  • Python Language Reference, "The import statement" (wildcard form and __all__): https://docs.python.org/3/reference/simple_stmts.html#the-import-statement
  • PEP 8, "Imports": wildcard imports should be avoided.
  • Ruff rules F403 and F405: https://docs.astral.sh/ruff/rules/undefined-local-with-import-star/ · https://docs.astral.sh/ruff/rules/undefined-local-with-import-star-usage/
  • Pyright configuration: https://github.com/microsoft/pyright/blob/main/docs/configuration.md

Changelog

  • 2026-10-30: draft 1.
  • AR-02 Do barrel files hide calls from coding agents?
  • AR-03 What happens when two functions share a name?
  • AR-04 Do import aliases confuse coding agents?

Last verified

For agentsthis page as Markdown/agent-readable/ar-01.mdllms.txt