Repository navigation
Codacy backlog: 443 issues, mostly Prospector/Pyflakes findings #41
Description
Activity
- addedtech-debtKnown technical debt / deferred cleanup, not a live bugKnown technical debt / deferred cleanup, not a live bug
on Aug 2, 2026 Another
F405instance in the same already-documented pattern: PR #84 (__array__protocol onImage) added a new use ofDtypeatImageCore.py:478, flagged by Codacy as "may be undefined, or defined from star imports" — same root cause as the:352instance already logged above (from machinevisiontoolbox.mvtb_types import *atImageCore.py:49). Not a functional bug, just the star-import convention doing what it always does. No action taken in #84 itself; logging here per the existing note thatF405/F403cleanup is deferred until/unless the star-import convention is reconsidered.Follow-up on the Bandit/Prospector share of this backlog (assert_used, B101): audited it properly during the same session that produced #95 (the
Image()dtype/maxintval bug -- unrelated root cause, but the investigation trail is what surfaced this).tests/(~45 findings): not a real issue, just mis-scoped. Bareassertis idiomatic pytest style, not a security concern. #99 excludestests/from Bandit via[tool.bandit] exclude_dirs = ["tests"]inpyproject.toml(Codacy's Prospector integration honours this natively) -- verified with a throwaway venv that this drops the combinedsrc+testsB101 count from 93 to 48, i.e.tests/'s entire contribution, withsrc/'s count unchanged.src/(~48 findings): audited individually, not a blanket "won't fix." Grouped into three buckets:- Type-narrowing after a prior check (majority) -- e.g.
Camera.py:333'sassert self._imagesize is not Noneright after the code above it guarantees that. Legitimate use ofassert, left as-is. - Optional-dependency guards --
Sources.py's_py7zr/roslibpy/o3d/_Stores/etc. pattern:if not _xxx_available: raise ImportError(...)followed byassert xxx is not Noneto narrow the type for the code below. Also legitimate. 8 near-identical occurrences of this exact pattern inSources.py-- worth eventually consolidating into one small helper (e.g._require_o3d()returning the narrowed module) so there's one assert instead of eight, but that's a real refactor, not urgent; noting it here rather than doing it silently inside a bug-fix PR. - Three real issues -- fixed in fix: assert hygiene -- unreachable assert, two caller-facing checks #100: an
assertleft unreachable inside anif: raiseblock (mis-indented copy of the pattern in (2)), and two caller-facing argument/state checks (BundleAdjust.add_projection,Camera.nu/nv/width/height) that should survivepython -Orather than silently vanish -- converted to explicitraise ValueError(...).
Net: the remaining ~48
src/B101 findings after #100 lands are believed-legitimate, not overlooked. Not adding# nosecpragmas to mark them individually -- that's copy-paste-dangerous (invites pasting the suppression onto a genuinely bad future assert without re-deriving whether it's safe) and duplicates what Codacy's own per-finding dismiss/ignore already does without touching source. If the dashboard noise matters, dismissing them there is the better lever than pragma comments here.- Type-narrowing after a prior check (majority) -- e.g.
Raised 2026-07-29 when the user pointed at the repo's Codacy dashboard
(443 issues total) and asked how much overlaps with the mixin/hygiene
work happening the same day. Verified: only the bare-except finding
(see git history, since fixed) genuinely overlapped. Everything else is
a distinct, much larger body of work, deliberately not tackled in that
pass — logging the real numbers here instead of re-deriving them from
scratch next time.
Codacy's Python analysis engine is Prospector (bundles Pylint +
Pyflakes + Bandit + pycodestyle + pydocstyle + mccabe) — confirmed via
the dashboard's own "Prospector's documentation" tab, and pattern names
like
Avoid Dangerous Mutable Default Arguments/Audit Dangerous Subprocess Usagethat are textbook Pylint/Bandit rule names. Codacy's298-count "Detect Python Source Code..." bucket is all Pyflakes
findings grouped under one umbrella pattern, not broken out by code the
way
ruff/rawpyflakesdo.Reproduced locally with
ruff check --select F src/machinevisiontoolbox testsagainst cleanorigin/main, 2026-07-30: 883 hits (notdirectly comparable to Codacy's 298 — different default
exclusions/config, and this sweep includes
tests/, which Codacy'sdashboard count may not). By code:
F405from X import *)F401F841F403from X import *used (can't verify no undefined names)F811F821F541F405/F403(star-import ambiguity) dominate the count but are mostlya style/tooling-friction issue, not bugs — this codebase leans on
from machinevisiontoolbox.base import *-style re-exportsdeliberately (see the mypy wildcard-re-export issue for the
concrete downside of that pattern).
F401/F841/F811are typicalaccumulated-cruft categories, individually low-risk to clean up but
numerous.
F821(undefined name) is different — this is a real-bug class, notstyle: a name that doesn't exist would raise
NameErrorat runtimeif that code path is ever actually executed. All 29 instances, by
location:
BundleAdjust.py:382,590,592— undefinedc,retain,g2ImageSpatial.py:116,121,328,330-332,340-342,1106— undefined_border_opt,border_value,value,a,kv(kvappears 4times),
connVisualServo.py:186,412,444,1351-1353,1403— undefinedAnimate,plot,history,camera,SphericalCamera,kwargs,ptblocks/camera.py:287,288— undefinedstate(x2)tests/test_camera.py:191,192,194,195,198,200— undefinedx,y(likely a real bug in the test, not production code — check
whether these lines actually run or are dead/unreachable test code)
Codacy's Pylint/Bandit-derived counts (the non-Pyflakes ~145 of the
443) weren't independently reproduced locally — the dashboard is the
source of truth for those categories (mutable default arguments,
assertusage, subprocess/exec/urlopenauditing, etc.).Fix
Not a single pass. Suggested order: (1) triage the 29
F821hits first— for each, determine real bug vs. genuinely dead/unreachable code, fix
or delete accordingly; (2)
F401/F811next, mechanical andruff --fix-automatable for most cases; (3)F841case-by-case (somemay be intentional, e.g. unpacking for side effects); (4)
F405/F403last and only if the codebase-wide star-import convention itself is
ever reconsidered — otherwise these will just regenerate.
Two more concrete instances, PRs #32/#33, 2026-07-30: Codacy
flagged
typeshadowing the builtin atImageWholeFeatures.py:1213(
Histogram.plot's signature, PR #32) and again at:1570(
_compute_plot_series, the extraction in PR #33 that copiedplot'stypeparameter into a new method). Deliberately not renamed ineither PR —
type=is public API (hist.plot(type="pdf")), a renameneeds a proper deprecation cycle. If picked up: this method
already has a precedent for exactly this —
bar=is kept as adeprecated alias for
filled=with aDeprecationWarning(
ImageWholeFeatures.py, same method) — mirror that pattern: addkind=as the real parameter, deprecatetype=as an alias. Do thisas its own PR after #32 and #33 are both merged, not before —
branching the rename off pre-#32
mainwould conflict with both ofthose on the same lines.
PR #33 also surfaced 3 more Codacy findings while extracting
Image.__getitem__'s nested closures (ImageCore.py):maxas aparameter name (
:2792,_lenkey— carried over verbatim from theoriginal nested
lenkey(key, max), not introduced by the extraction)and two
F405star-import-ambiguity hits (:352Dtype,:2812Any, both frommachinevisiontoolbox.mvtb_types's star-import) —already covered by the
F405finding above, not a new pattern.