# Behavior traces — astral-sh/uv

> Canonical page: https://codevetter.com/unpack/uv/behavior-traces

# Behavior traces — astral-sh/uv

Scanned commit a9e231a7e377342084d1c0b6009409bdec41acc5 (2026-09-21). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Process startup always parses the CLI before the async runtime starts, loads configuration, and only then dispatches. uv lock discovers a workspace or PEP 723 script, solves with the universal resolver, and writes uv.lock. uv sync reuses that lock operation and then installs into the project environment. uv run syncs unless asked not to, rebuilds PATH, and waits on the child while forwarding signals. These three paths share interpreter discovery, the cache, and the registry client, but they differ in whether they mutate the lockfile, the environment, or both.
- Startup sequence: uv binary main calls uv::main; that sets UV, parses Cli, and on a clap error calls suggest_subcommand then Error::exit. The main2 thread builds the runtime and block_on(run). run applies color, enables warnings unless --quiet, honors UV_WORKING_DIRECTORY by set_current_dir, loads EnvironmentOptions, resolves early preview flags, and calls uv_preview::set and logging::setup_logging before workspace discovery. — [crates/uv/src/bin/uv.rs#L10-L14](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/bin/uv.rs#L10-L14) [crates/uv/src/lib.rs#L134-L203](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/lib.rs#L134-L203) [crates/uv/src/lib.rs#L3026-L3067](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/lib.rs#L3026-L3067)
- After discovery, run validates that an explicit --project path exists and is a directory except for uv init. It refuses to operate when the project directory is inside the cache. It builds base_client_builder and matches *cli.command. User errors print via diagnostics::write_error_chain and exit Failure; argument and unexpected errors exit Error. — [crates/uv/src/lib.rs#L231-L250](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/lib.rs#L231-L250) [crates/uv/src/lib.rs#L598-L637](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/lib.rs#L598-L637) [crates/uv/src/lib.rs#L3084-L3122](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/lib.rs#L3084-L3122)
- uv lock calls commands::project::lock::lock. For a script path it runs init_script_python_requirement and Pep723Script::init. Otherwise VirtualProject::discover selects LockTarget::Workspace. Frozen mode skips interpreter selection; otherwise ProjectInterpreter::discover runs with ActiveEnvironment::Ignore and ProjectEnvironmentPolicy::Optional, then do_lock. — [crates/uv/src/commands/project/lock.rs#L89-L180](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/lock.rs#L89-L180)
- do_lock reads target.requirements, overrides, constraints, dependency_groups, and conflicts. It rejects overlapping environment markers as ProjectError::OverlappingMarkers. It warns when package-level conflicts are used without PreviewFeature::PackageConflicts. It prefers versions and fork markers from a validated existing lock via read_lock_requirements and ResolverEnvironment::universal. — [crates/uv/src/commands/project/lock.rs#L505-L703](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/lock.rs#L505-L703) [crates/uv/src/commands/project/lock.rs#L1005-L1053](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/lock.rs#L1005-L1053)
- The lock solve calls ExtrasResolver::resolve on member requirements, chains group and dependency-group requirements, then pip::operations::resolve. That function builds Resolver::new(...).with_reporter(...).resolve(). On success, Lock::from_resolution plus with_conflicts and with_required_environments produces the lock. If PreviewFeature::MissingExcludeNewerPackageLock is set, without_unused_exclude_newer_packages runs. If the serialized lock changed, the caller commits it. — [crates/uv/src/commands/project/lock.rs#L1055-L1153](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/lock.rs#L1055-L1153) [crates/uv/src/commands/project/lock.rs#L397-L474](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/lock.rs#L397-L474) [crates/uv/src/commands/pip/operations.rs#L389-L410](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/pip/operations.rs#L389-L410)
- uv sync starts in commands::project::sync::sync. It discovers a VirtualProject (Existing members when frozen, or a single package via discover_with_package) or uses a Pep723Script. It computes default groups, then ProjectEnvironment::get_or_init or ScriptEnvironment::get_or_init, and takes an environment lock. A script with no lockfile cannot use --frozen or --locked. — [crates/uv/src/commands/project/sync.rs#L66-L247](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/sync.rs#L66-L247)
- sync then builds a LockTarget and runs LockOperation::new(...).execute(lock_target). Lock mismatches in dry-run become Outcome::LockMismatch and still sync; otherwise they return UvError::user. It warns when a non-packaged member defines project.scripts. do_sync receives the install target, environment, extras, groups, and malware settings. — [crates/uv/src/commands/project/sync.rs#L350-L438](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/sync.rs#L350-L438)
- do_sync lowers extra build dependencies, clones the client builder with the keyring provider, and errors with ProjectError::LockedPythonIncompatibility when the environment interpreter is outside lock.requires_python. It calls detect_conflicts for the requested extras and groups before planning installations. — [crates/uv/src/commands/project/sync.rs#L625-L738](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/sync.rs#L625-L738)
- uv run enters commands::project::run::run, reads UV_RUN_RECURSION_DEPTH, and returns RecursionLimitError above max_recursion_depth (the usual cause is a shebang of #!/usr/bin/env -S uv run). It rejects requirements taken from pyproject.toml, setup.py, or setup.cfg, and rejects using stdin for both the script and a requirements file. — [crates/uv/src/commands/project/run.rs#L90-L167](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/run.rs#L90-L167)
- When a command is present, run builds it with command.as_command(interpreter), applies env-file variables, prepends environment Scripts directories and the base interpreter to PATH, increments UV_RUN_RECURSION_DEPTH, sets VIRTUAL_ENV when the interpreter is a virtualenv, optionally calls uv_unix::set_open_file_limit, spawns the process with inherited stdio, and waits in child::run_to_completion. — [crates/uv/src/commands/project/run.rs#L1271-L1329](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/project/run.rs#L1271-L1329)
- child::run_to_completion documents Unix signal policy: in a TTY, SIGINT is not forwarded immediately because the terminal already signals the process group; outside a TTY, SIGINT is forwarded. SIGTERM is forwarded so that uv as Docker PID 1 remains killable. The handler is only safe when the child is the last work in the process. — [crates/uv/src/child.rs#L6-L37](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/child.rs#L6-L37)
- uv pip install enters pip_install with requirements, constraints, overrides, excludes, build constraints, index locations, link mode, and hash-checking mode. The shared install tail is pip::operations::install, which diffs the resolution against SitePackages via InstallationPlan::build and then plan.execute. — [crates/uv/src/commands/pip/install.rs#L79-L118](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/pip/install.rs#L79-L118) [crates/uv/src/commands/pip/operations.rs#L684-L747](https://github.com/astral-sh/uv/blob/a9e231a7e377342084d1c0b6009409bdec41acc5/crates/uv/src/commands/pip/operations.rs#L684-L747)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
