pyfaro add and remove¶
pyfaro add and pyfaro remove edit the project's dependencies through
uv add and uv remove. uv writes pyproject.toml and uv.lock. Use them
instead of editing the file by hand when you want uv to resolve the change.
No implicit sync
Both commands pass --no-sync: they update the declaration and the lock,
but they do not install anything into .venv. Run
pyfaro sync when you want the environment to follow.
Quick example¶
$ pyfaro add "tomli-w>=1,<2"
Resolved 10 packages in 81ms
$ pyfaro sync --locked
+ tomli-w==1.2.0
$ pyfaro remove tomli-w
Resolved 9 packages in 18ms
Scenarios¶
1. Add a runtime dependency¶
add takes PEP 508 requirement specifiers, and several at once. Without
--dev or --group, they go to [project].dependencies:
2. --dev: the development group¶
The requirement lands in the dev dependency group:
3. --group: a named group¶
--dev and --group are mutually exclusive:
$ pyfaro add --dev --group docs mkdocs
error: the argument '--dev' cannot be used with '--group <GROUP>'
4. Prove there is no sync¶
$ pyfaro add rich
Resolved 31 packages in 148ms
$ .venv/bin/python -c "import rich"
ModuleNotFoundError: No module named 'rich'
$ pyfaro sync
+ rich==…
5. Remove dependencies¶
remove takes dependency names, matching the section you used to add
them:
$ pyfaro remove rich tomli-w
Resolved 27 packages in 18ms
$ pyfaro remove --dev pytest-cov
$ pyfaro remove --group docs mkdocs
Removing a name from the wrong section fails:
$ pyfaro remove nothere
error: The dependency `nothere` could not be found in `project.dependencies`
error: uv remove failed (exit status: 2); see uv's output above
Note
Removing the last entry of a group leaves an empty group (docs = [])
in pyproject.toml. That is uv's behavior.
6. Requirements that start with a dash¶
Put -- before them so Pyfaro does not parse them as options. Everything
after it reaches uv untouched, and uv decides whether it accepts it:
$ pyfaro add -- "-e ./x"
error: Failed to parse: `-e ./x`
Caused by: Expected package name starting with an alphanumeric character, found `-`
-e ./x
^
error: uv add failed (exit status: 2); see uv's output above
7. Offline, and choosing uv¶
--offline disables network access, and works when uv's cache can answer.
--uv <path> selects the uv binary. uv 0.9.26 or newer is required.
Project selection¶
Run the commands in a project or any of its subdirectories. Pyfaro uses the
nearest pyproject.toml. --project <PATH> selects an exact directory, which
must contain its own pyproject.toml:
Unlike sync, there is no positional path.
What it writes, and what it never writes¶
Writes (through uv): the matching dependency table in pyproject.toml
(including tool.uv.sources when uv adds one) and uv.lock.
Never writes: .venv or installed packages. Pyfaro itself does not edit
pyproject.toml and does not resolve anything, since uv owns both.
Errors you may hit¶
| Message | Fix |
|---|---|
No solution found when resolving dependencies |
uv could not satisfy the requirement. Read the explanation above the error. A typo in the name is the common cause. |
The dependency … could not be found in … |
Use the same --dev or --group you used to add it. |
Failed to parse: … |
Fix the requirement specifier. |
the following required arguments were not provided: <PACKAGES>... |
Pass at least one package. |
no pyproject.toml found … |
Run inside a project or pass --project. |
Exit codes¶
| Code | Meaning |
|---|---|
0 |
The dependency change was applied. |
1 |
A Pyfaro error, or uv failed with status 1 (for example an unsatisfiable requirement). |
2 |
A usage error, or uv failed with status 2 (for example an unknown dependency). |
130 |
Cancelled. |
uv's numeric status is forwarded unchanged.
See also¶
pyfaro sync: install what you declared.pyfaro run: run commands in the environment.pyfaro create: a new project starts with pinned dev tools.