|
| 1 | += GCI110 — Avoid wildcard imports in Python (`from module import *`) |
| 2 | + |
| 3 | +== Why this rule? |
| 4 | + |
| 5 | +Wildcard imports bind many names into the current namespace and execute all top‑level module initialization. |
| 6 | +This can slightly increase import time, parsing, and memory. Multiplied across many modules or cold starts, |
| 7 | +this adds avoidable CPU/energy. It also hurts analyzability and maintainability by obscuring where names come from. |
| 8 | + |
| 9 | +This rule is advisory for eco‑design: the effect is modest compared to algorithmic issues, so severity is Info. |
| 10 | + |
| 11 | +== Rule scope |
| 12 | + |
| 13 | +- Flags top‑level statements: `from module import *`. |
| 14 | +- Focuses on readability/maintainability with secondary eco‑impact (CPU/memory at import time). |
| 15 | + |
| 16 | +== Exceptions (when it’s acceptable) |
| 17 | + |
| 18 | +- Package aggregation files (`__init__.py`) that re‑export a curated API. |
| 19 | +- If the target module defines `__all__`, making the export surface explicit. |
| 20 | +- Generated code, quick scripts/REPL/notebooks, or educational material. |
| 21 | + |
| 22 | +== Non‑compliant |
| 23 | + |
| 24 | +[source,python] |
| 25 | +---- |
| 26 | +from utils import * |
| 27 | +process(data) |
| 28 | +---- |
| 29 | + |
| 30 | +== Compliant alternatives |
| 31 | + |
| 32 | +[source,python] |
| 33 | +---- |
| 34 | +# Explicit named imports |
| 35 | +from utils import parse, process |
| 36 | +
|
| 37 | +# Or module import with alias |
| 38 | +import utils as u |
| 39 | +u.process(data) |
| 40 | +---- |
| 41 | + |
| 42 | +== Public API re‑exports |
| 43 | + |
| 44 | +[source,python] |
| 45 | +---- |
| 46 | +# In package/__init__.py |
| 47 | +from .parse import parse |
| 48 | +from .process import process |
| 49 | +__all__ = ["parse", "process"] |
| 50 | +---- |
| 51 | + |
| 52 | +== Configuration parameters (recommended) |
| 53 | + |
| 54 | +- `allowInInit` (default: true): don’t report in `__init__.py`. |
| 55 | +- `ignoreTests` (default: true): ignore paths like `tests/**`, `**/test_*.py`. |
| 56 | +- `ignoreMigrations` (default: true): ignore `**/migrations/**`. |
| 57 | +- `ignoreIfHasAll` (default: true): don’t report if imported module defines `__all__`. |
| 58 | + |
| 59 | +== References |
| 60 | + |
| 61 | +- PEP 8 — imports: discourages `from module import *` in most cases. |
| 62 | +- Real Python — Python imports and `__all__`. |
| 63 | + |
0 commit comments