You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TL;DR — a patch release with one headline property: deterministic output. Running canpy twice with the same flags on the same input now produces byte-identical analysis.json. No schema changes; no breaking changes.
Four independent nondeterminism sources were eliminated:
Hash-seed variance in the L2 call graph (the big one). PyCG's capped fixpoint iterates hash-ordered sets, so Python's per-interpreter hash randomization shifted its frontier arbitrarily — the same input could yield 1,527 edges on one run and 4,712 on the next. The CLI now pins PYTHONHASHSEED=0 for itself (and its Ray workers) via a one-time re-exec. Export PYTHONHASHSEED yourself to opt out or pin a different seed.
Random temp paths feeding the analysis. PyCG keys internal state on absolute module paths, and its mini-project root had a random mkdtemp suffix — a different analysis input every run. The root is now derived from the content it mirrors, with a lock so concurrent analyses of the same project serialize safely instead of deleting each other's working tree.
Unstable ordering. Entry points were processed in filesystem order and call-graph edges serialized in backend iteration order; both are now canonically sorted.
Arbitrary Jedi type picks. A union-typed receiver (e.g. a file object that may be _IOBase | BufferedRandom | TextIOWrapper) resolved to a different member per run; candidates are now tie-broken deterministically, and bare-NoneType return inferences no longer mask the informative member of an Optional.
Also in this release:
New verification gates ride the test suite: a byte-identity gate (two full runs must match exactly) and the call-graph quality gate from #87 (≥95% of resolved method calls must bind to the invoked name — the acceptance criterion from the external Odoo audit).
The docs/handoff reference bundle is regenerated against the shipping emitter — the 1.0.0 bundle predated a late merge and was missing analyzer.config, structured call-site arguments, and some callee-resolution improvements that the released binary actually emits.
Known residue (documented on #99, which stays open for it): one call-site's inferred return_type can intermittently be absent when Jedi's compiled-introspection helper subprocess hiccups under load — environmental and upstream; everything the analyzer controls is now deterministic.
Upgrade
pip install -U "codeanalyzer-python==1.0.1"
Or via Homebrew / the shell installer as usual. If you pinned 1.0.0, this is a drop-in upgrade.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
codeanalyzer-python (canpy) v1.0.1
TL;DR — a patch release with one headline property: deterministic output. Running
canpytwice with the same flags on the same input now produces byte-identicalanalysis.json. No schema changes; no breaking changes.What was fixed (#99, PR #101)
Four independent nondeterminism sources were eliminated:
PYTHONHASHSEED=0for itself (and its Ray workers) via a one-time re-exec. ExportPYTHONHASHSEEDyourself to opt out or pin a different seed.mkdtempsuffix — a different analysis input every run. The root is now derived from the content it mirrors, with a lock so concurrent analyses of the same project serialize safely instead of deleting each other's working tree._IOBase | BufferedRandom | TextIOWrapper) resolved to a different member per run; candidates are now tie-broken deterministically, and bare-NoneTypereturn inferences no longer mask the informative member of anOptional.Also in this release:
docs/handoffreference bundle is regenerated against the shipping emitter — the 1.0.0 bundle predated a late merge and was missinganalyzer.config, structured call-sitearguments, and some callee-resolution improvements that the released binary actually emits.Known residue (documented on #99, which stays open for it): one call-site's inferred
return_typecan intermittently be absent when Jedi's compiled-introspection helper subprocess hiccups under load — environmental and upstream; everything the analyzer controls is now deterministic.Upgrade
pip install -U "codeanalyzer-python==1.0.1"Or via Homebrew / the shell installer as usual. If you pinned 1.0.0, this is a drop-in upgrade.
Links
Beta Was this translation helpful? Give feedback.
All reactions