Commit 7f6d7df
Fix two more lint holes flagged in PR review (M3 follow-up 2)
Two findings from the second-round review:
[P2] The two-pass alias map was last-write-wins, so a later
``import pathlib as os`` erased the earlier ``import os`` binding
for the call-site check. ``import os; os.system("ls"); import
pathlib as os`` therefore passed the lint with zero violations.
Same shape with ``import os as runner; runner.execve(...); import
pathlib as runner`` also passed.
[P3] STABILITY.md claimed ``import importlib*`` forms are
forbidden, but ``import importlib.metadata`` and ``from
importlib.metadata import version`` are intentionally allowed
(the plugin registry under checks/ uses metadata for entry-point
discovery). The documentation overpromised what the lint enforces.
Reproduced both findings against the prior commit (rebind-os and
rebind-aliased returned []; importlib.metadata returned []) before
fixing.
Implementation (tests/test_adapter_static_only.py):
- Convert ``module_aliases: dict[str, str]`` to
``dict[str, set[str]]`` and ``name_aliases:
dict[str, tuple[str, str]]`` to ``dict[str, set[tuple[str, str]]]``.
A local name binds to the *union* of every canonical module/attr
pair it was ever assigned in the file. ``import os; import pathlib
as os`` now yields ``module_aliases["os"] = {"os", "pathlib"}``.
- ``_resolve_attribute_chain`` -> ``_resolve_attribute_chain_all``
returns every canonical chain a call could resolve to. Call sites
flag once if *any* resolution is forbidden.
- Same conservative-union logic for from-import aliases at bare-name
call sites.
- Added 4 negative-control parametrize cases covering both
rebind shapes (module alias + from-import alias) plus the
reverse-order variant where the dangerous binding follows the safe
one. Verified ``import os; import pathlib as os;
os.path.join('a','b')`` does NOT false-positive — ``os.path.join``
is in neither the exact nor prefix sets under either binding.
False-positive trade-off (acknowledged in the docstring): if a local
name is ever bound to a dangerous module *in any branch*, every
attribute chain on that name is checked against the forbidden surface.
For trust-model lint this is the right failure mode — suspicious
aliasing should be a code-review trigger, not a silent pass.
Documentation (STABILITY.md):
- Replace the vague ``import runpy / import subprocess / import
importlib*`` line with an enumerated forbidden-modules list
(``runpy``, ``subprocess``, ``importlib``, ``importlib.util``,
``importlib.machinery``, ``builtins``) and an enumerated
forbidden-attribute list (including the ``os.exec*`` / ``os.spawn*``
/ ``os.posix_spawn*`` prefix families and ``os.system`` /
``os.popen``).
- Explicitly call out that ``importlib.metadata`` is allowed and why
(plugin-discovery surface lives under ``checks/`` not ``inputs/``,
and discovery runs against the installed environment, not user
workspace files).
- Document the conservative union-of-bindings alias resolution so
reviewers know an aliased rebinding cannot defeat the lint.
69 tests pass (up from 65); ruff clean. Production code under src/
unchanged. Baseline scan of current inputs/ still clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 6cacfb6 commit 7f6d7df
2 files changed
Lines changed: 130 additions & 54 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
167 | | - | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
174 | 191 | | |
175 | 192 | | |
176 | 193 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
153 | 153 | | |
154 | | - | |
155 | | - | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
156 | 158 | | |
157 | | - | |
| 159 | + | |
158 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
159 | 167 | | |
160 | 168 | | |
161 | 169 | | |
162 | 170 | | |
163 | 171 | | |
164 | 172 | | |
165 | 173 | | |
166 | | - | |
| 174 | + | |
167 | 175 | | |
168 | 176 | | |
169 | 177 | | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
174 | 188 | | |
175 | 189 | | |
176 | 190 | | |
177 | 191 | | |
178 | 192 | | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
184 | 207 | | |
185 | 208 | | |
186 | 209 | | |
| |||
190 | 213 | | |
191 | 214 | | |
192 | 215 | | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
203 | 229 | | |
204 | 230 | | |
205 | 231 | | |
| |||
210 | 236 | | |
211 | 237 | | |
212 | 238 | | |
213 | | - | |
| 239 | + | |
214 | 240 | | |
215 | 241 | | |
216 | 242 | | |
217 | | - | |
| 243 | + | |
218 | 244 | | |
219 | 245 | | |
220 | 246 | | |
| |||
244 | 270 | | |
245 | 271 | | |
246 | 272 | | |
247 | | - | |
| 273 | + | |
248 | 274 | | |
249 | 275 | | |
250 | 276 | | |
| |||
258 | 284 | | |
259 | 285 | | |
260 | 286 | | |
261 | | - | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
262 | 290 | | |
263 | | - | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | | - | |
268 | | - | |
269 | | - | |
270 | | - | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
271 | 310 | | |
272 | | - | |
273 | | - | |
| 311 | + | |
274 | 312 | | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
| 313 | + | |
281 | 314 | | |
282 | 315 | | |
283 | 316 | | |
| |||
417 | 450 | | |
418 | 451 | | |
419 | 452 | | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
420 | 479 | | |
421 | 480 | | |
422 | 481 | | |
| |||
0 commit comments