Forgetting to declare dependencies in Python projects can result in runtime errors like ModuleNotFoundError
or ImportError
.
In contrast, including unnecessary dependencies can unnecessarily bloat your project, particularly when deploying it as a Docker container where size matters.
Tools like FawltyDeps can help manage dependencies effectively, ensuring your project includes only what it needs.
Undeclared dependencies: You import a module in your code, but forget to declare it in your project's depedency files like requirements.txt
or pyproject.toml
.
Your project might fail at runtime when run on a different machine or in a different environment.
Unused dependencies: these are dependencies listed but never used in your project. They take up space, make your project slow to install, and to run in a docker container and also may pose security risks.
FawltyDeps is a tool that helps you find both undeclared and unused dependencies in your python projects. Here's a simple guide how you can integrate it into your projects.
Let's consider a simple python project pycontainer-demo. In this project, we are going to setup FawltyDeps as a pre-commit hooks to ensure our dependencies are in check.
1. Install FawltyDeps
uv add --dev fawltydeps
Then we can run the tool.
2. Configure FawltyDeps
FawltyDeps v0.19.0 incorrectly flags dependencies provided by other declared dependencies as undeclared. For example, it may identify
rich
as undeclared, even though it is a dependency of the declared packagetyper
.
To address this and exclude dependencies not intended for direct import in pycontainer-demo
project,
I added the following configuration to pyproject.toml
...
[tool.fawltydeps]
ignore_undeclared = [
"rich"
]
ignore_unused = [
"bump-my-version",
"psycopg2-binary",
"pre-commit",
"flawtydeps",
]
3. Add to the pre-commit hooks
...
- repo: https://github.com/tweag/FawltyDeps
rev: v0.19.0
hooks:
- id: check-undeclared
- id: check-unused
4. Install the pre-commit hooks
$ pre-commit install
Now when you commit changes, FawltyDeps
will run and report any undeclared or unused dependencies.
If we add a dependency to pyproject.toml
but never used in the code.
For example we add the following code to pyproject.toml
.
# Example numpy that is not used
dependencies = [
...
numpy
]
Then we commit the changes.
$ git add .
$ git commit -m "Add numpy"
FawltyDeps-unused........................................................Failed
- hook id: check-unused
- exit code: 4
These dependencies appear to be unused (i.e. not imported):
- 'numpy' declared in:
pyproject.toml
This approach is helpful because it prevents unused dependencies from being committed. To resolve such issues, you can simply remove the unnecessary dependency from pyproject.toml.
For example if we add the following code to src/robot/cli.py
and install art
with uv pip install art
from art import tprint
header = tprint("Robot Management System")
app = typer.Typer(help=header, no_args_is_help=True)
console = Console()
The update involves adding a header using the art package, enhancing the appearance of the CLI output. When you run the CLI, it will look like this:
$ robot
____ _ _ __ __ _ ____ _
| _ \ ___ | |__ ___ | |_ | \/ | __ _ _ __ __ _ __ _ ___ _ __ ___ ___ _ __ | |_ / ___| _ _ ___ | |_ ___ _ __ ___
| |_) | / _ \ | '_ \ / _ \ | __| | |\/| | / _` || '_ \ / _` | / _` | / _ \| '_ ` _ \ / _ \| '_ \ | __| \___ \ | | | |/ __|| __| / _ \| '_ ` _ \
| _ < | (_) || |_) || (_) || |_ | | | || (_| || | | || (_| || (_| || __/| | | | | || __/| | | || |_ ___) || |_| |\__ \| |_ | __/| | | | | |
|_| \_\ \___/ |_.__/ \___/ \__| |_| |_| \__,_||_| |_| \__,_| \__, | \___||_| |_| |_| \___||_| |_| \__| |____/ \__, ||___/ \__| \___||_| |_| |_|
Then we commit the changes.
git add .
git commit -m "Add header with art"
FawltyDeps-undeclared....................................................Failed
- hook id: check-undeclared
- exit code: 3
These imports appear to be undeclared dependencies:
- 'art' imported at:
src/robot/cli.py:2
Fortunately, the commit fails.
Because we forget to declare art
as a dependency.
This is really nice because with such failure we can prevent undeclared dependencies from being committed.
Next, we can add art to the dependencies and update the pyproject.toml file accordingly.
dependencies = [
"sqlmodel>=0.0.22",
"typer>=0.9.0",
"psycopg2-binary>=2.9.9",
"art>=6.4",
]
We can now commit the changes, and they should pass successfully.
git add .
git commit -m "Add header cli with art"
...
FawltyDeps-undeclared....................................................Passed
FawltyDeps-unused........................................................Passed
Setting up FawltyDeps as a pre-commit hook helps catch undeclared and unused dependencies, ensuring your project stays lean and avoids runtime errors.