Skip to content

Commit 4629155

Browse files
authored
Merge pull request #52 from codellm-devkit/fix/uv-bin-no-path-fallback
fix(venv): use only the vendored uv, drop system-PATH fallback
2 parents 7089acc + 7dabdc5 commit 4629155

2 files changed

Lines changed: 22 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.3.0] - 2026-06-27
9+
10+
### Added
11+
- **`--analysis-level {1,2}`** (reintroduced): 1 is symbol table + Jedi call graph, 2 adds the PyCG call graph.
12+
- **Coupling-aware PyCG sharding** (`--pycg-shard`) so level 2 scales to large apps. Shards are chosen by Jedi module coupling (strongly-connected-component condensation, so import cycles never split, plus Louvain community detection) instead of a flat file count, so few call edges are severed between shards. PyCG runs on each shard inside a symlink mini-project that bounds it to that shard's files. Ray-parallel.
13+
- **Iterative decomposition of runaway shards.** PyCG's fixpoint can diverge on heavy metaclass / mixin code. A shard that hits the wall-clock timeout is re-sharded at half the budget and re-run, down to a floor (10 files). The residue that still diverges, or an atomic cycle that will not split, falls back to Jedi-only coverage. On the Odoo benchmark (1028 modules) this recovered 22210 PyCG edges versus 17149 for the best uniform ceiling, losing only 20 of 1028 files instead of a whole shard.
14+
- **New flags**: `--pycg-shard-strategy {jedi,package}` (default `jedi`), `--pycg-shard-ceiling` (default 100, the starting per-shard budget), `--pycg-shard-timeout` (default 120, per-shard wall clock), `--pycg-max-iter` (default 50, caps PyCG fixpoint passes so a divergent shard returns a partial graph instead of hanging).
15+
16+
### Changed
17+
- **BREAKING: CodeQL is replaced by PyCG as the level 2 call graph backend.** `--codeql/--no-codeql` is removed in favor of `--analysis-level`. Edge `provenance` literal `codeql` becomes `pycg`. New dependency: `pycg` (Apache 2.0). The `codeanalyzer.semantic_analysis.codeql` package is removed.
18+
19+
### Fixed
20+
- The shard planner keys its module graph by file path. `PyModule.module_name` is only the file stem (every `__init__.py`, `models.py`, ...), so keying by name collided and silently dropped files from shards.
21+
- PyCG no longer follows imports into an in-tree dependency venv (e.g. `.codeanalyzer/`) during the whole-project level 2 run: it runs in a symlink mini-project whose root holds project source only, so dependencies resolve outside the bound and stay ghost nodes.
22+
- `_uv_bin` uses only the vendored `uv` from the `uv` PyPI dependency and no longer falls back to a `uv` on `PATH`, so the analyzer always uses the pinned binary. Returns `None` only if the package is missing, in which case callers fall back to pip.
23+
824
## [0.2.1] - 2026-06-22
925

1026
### Added

codeanalyzer/core.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,15 +238,16 @@ def _get_base_interpreter() -> Path:
238238

239239
@staticmethod
240240
def _uv_bin() -> Optional[str]:
241-
"""Path to a uv binary: the one bundled with the ``uv`` PyPI package (a
242-
dependency, so normally always present -- including inside a Docker image),
243-
else a uv on PATH, else ``None`` (callers fall back to pip)."""
241+
"""Path to the uv binary bundled with the ``uv`` PyPI package (a declared
242+
dependency, so always present in our install -- including inside a Docker
243+
image). We deliberately ignore any uv on PATH so the analyzer always uses
244+
the pinned, vendored uv. Returns ``None`` only if the package is somehow
245+
missing (callers fall back to pip)."""
244246
try:
245247
from uv import find_uv_bin
246-
247248
return str(find_uv_bin())
248249
except Exception:
249-
return shutil.which("uv")
250+
return None
250251

251252
def _install_into_venv(self, venv_python: Path, args: List[str]) -> None:
252253
"""Install packages into the target venv, preferring uv for speed (parallel

0 commit comments

Comments
 (0)