The Same Engine at Smaller Scopes: Python, Scripts, and Tools
uv's shared lifecycle becomes most visible when the thing being managed is smaller than a repository. This chapter focuses on two connected questions: how uv chooses or installs the Python interpreter that makes a workflow possible, and how it keeps a project, a standalone script, and a command-line tool in separate environments. The practical result is a scope decision: the reader should be able to choose who owns a dependency declaration and how long its environment should live.
A project, a script, and a formatter may all need the same package resolver, but they do not want the same environment. A project's dependencies belong to its source tree and should be repeatable for a team. A script's dependencies belong to one file and may be created only when that file runs. A tool such as a linter may need to be available on a user's path without becoming importable by the application being linted. uv's design is coherent when it shares the engine while preserving those ownership boundaries.
Python is part of the request, not a hidden prerequisite
Many package workflows begin with an assumption: a suitable Python interpreter is already installed and someone else has decided which one it should be. uv makes interpreter selection an explicit part of the request. It can discover a compatible system interpreter or an existing virtual environment, and it can install a managed distribution when the local machine cannot satisfy the request. That lets the package and environment lifecycle begin without first assembling a separate interpreter-management workflow.
uv distinguishes managed Python from system Python by ownership. A managed installation is one uv downloaded and stores in its Python data directory. A system installation includes interpreters supplied by the operating system or another tool, such as a version manager. The distinction does not say that a system interpreter is bad or that a managed one is always necessary. It tells uv which installations it may select or download under the configured preference.
By default, uv's preference is managed: it favors a compatible managed installation over a system installation, but it can still use a compatible system interpreter before downloading a new one. A team can choose a stronger policy. An only-managed setting refuses system interpreters; an only-system setting refuses managed ones. Automatic downloads can likewise be allowed, limited to explicit installation commands, or disabled. These are separate controls. Preferring managed Python does not necessarily mean downloading every time, and disabling downloads does not change which already-installed interpreter would be preferred.
A Python request can be broad or exact. A request for 3.12 asks for an appropriate Python 3.12 installation, while a range can express a lower and upper bound. A request can name an implementation such as CPython or PyPy, select a variant such as a free-threaded build, identify a platform-specific managed installation, or point directly to an executable or environment. The more specific the request, the fewer substitutes uv can consider.