Skip to content

Commit d56cafc

Browse files
committed
enh: updates to deps page
1 parent 6b9d3ca commit d56cafc

File tree

4 files changed

+87
-110
lines changed

4 files changed

+87
-110
lines changed
-49.8 KB
Loading

package-structure-code/declare-dependencies.md

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@
33
:og:description: A Python package dependency refers to an external package or software that your Python project requires to function properly. Learn how to add different types of dependencies to your Python package.
44
```
55

6-
76
# Dependencies for your Python Package
87

9-
108
In the [pyproject.toml overview page](pyproject-toml-python-package-metadata),
119
you learned how to set up a **pyproject.toml** file with basic metadata
1210
for your package. On this page, you will learn how to specify different types of
1311
dependencies in your `pyproject.toml`.
1412

15-
16-
1713
## What is a package dependency?
1814

1915
A Python package dependency refers to an external package or
@@ -58,13 +54,11 @@ tests = [
5854

5955
There are three different types of dependencies that you will learn about on this page:
6056

61-
1. **Required dependencies:** These are dependencies that need to be installed for your package to work correctly in a user's environment. You add these dependencies to the `project.dependencies` table in your pyproject.toml file.
62-
2. **Feature Dependencies:** These are dependencies that are required if a user wants to access additional functionality (that is not core) to your package.
63-
3. **Development Dependencies:** These dependencies are required is someone wants to develop or work on your package. For instance linters, testing tools like pytest and mypy are examples of development dependencies.
57+
1. **Required dependencies:** These are dependencies that need to be installed for your package to work correctly in a user's environment. You add these dependencies to the `[project.dependencies]` table in your pyproject.toml file.
58+
2. **Feature Dependencies:** These are dependencies that are required if a user wants to access additional functionality (that is not core) to your package. Store these in the `[project.optional.dependencies]` table or your pyproject.toml file.
59+
3. **Development Dependencies:** These dependencies are required if someone wants to develop or work on your package. These include instance linters, testing tools like pytest and mypy are examples of development dependencies. Store these in the `[project.dependency.groups]` table or your pyproject.toml file.
6460

6561
:::{admonition}
66-
:class: tip
67-
6862
A dependency is not part of your project's codebase. It is a package or software called
6963
within the code of your project or used during the development of your package.
7064
:::
@@ -74,10 +68,10 @@ within the code of your project or used during the development of your package.
7468
Required dependencies are imported and called directly within your package's code.
7569
They are needed for your package to run.
7670

77-
You can add your core dependencies to the `dependencies` array in the
71+
You can add your required dependencies to the `dependencies` array in the
7872
`[project]` table of your **pyproject.toml** file. When users install
7973
your package with uv, pip, or conda, these dependencies will be
80-
automatically installed alongside your package.
74+
automatically installed alongside your package in their environment.
8175

8276
```toml
8377
[project]
@@ -126,22 +120,22 @@ dependencies = [
126120
:class: tip
127121

128122
If you have dependencies that need to be installed directly from GitHub,
129-
you can specify them in your pyproject.toml file:
123+
you can specify them in your pyproject.toml file like this:
130124

131125
```toml
132126
dependencies = [
133-
"my_dependency >= 1.0.1 @ git+https://git.server.example.com/mydependency.git"
127+
"my_dependency >= 1.0.1 @ git+https://git.server.example.com/mydependency.git@commitHashHere"
134128
]
135129
```
136-
IMPORTANT: For security reasons, if your library depends on a
137-
GitHub-hosted project, you will need to point to a specific
138-
commit/tag/hash of that repository in order to upload your project to
139-
PyPI.
130+
IMPORTANT: If your library depends on a GitHub-hosted project,
131+
you should point to a specific commit/tag/hash of that repository before you upload your project to
132+
PyPI. You never know how the project might change over time. Commit hashes
133+
are more reliable as they can't be changed
140134
:::
141135

142136
## 2. Optional dependencies
143137

144-
Optional (sometimes referred to as feature) dependencies can be installed by users as needed. Optional dependencies add specific features to your package that not all users need. For example, if your package has an optional interactive plotting feature that uses Bokeh, you would list Bokeh as an `[optional.dependency]`. Users who want interactive plotting will install it. Users who don't need plotting don't have to install it.
138+
Optional (also referred to as feature) dependencies can be installed by users as needed. Optional dependencies add specific features to your package that not all users need. For example, if your package has an optional interactive plotting feature that uses Bokeh, you would list Bokeh as an `[optional.dependency]`. Users who want interactive plotting will install it. Users who don't need plotting don't have to install it.
145139

146140
Place these dependencies in the `[project.optional-dependencies]` table.
147141

@@ -150,15 +144,12 @@ Place these dependencies in the `[project.optional-dependencies]` table.
150144
...
151145
...
152146
...
153-
# Below you see a optional. A dependency array called plot that lists packages a user needs to access the plotting functionality, which is a feature of your project.
154147
[optional.dependencies]
155148
plot = ["bokeh"]
156149
```
157150

158151
When a user installs your package, uv, pip, or conda automatically installs all required dependencies. Optional dependencies are only installed if the user explicitly requests them.
159152

160-
161-
162153
:::{dropdown} How to Add optional.dependencies using UV
163154
:icon: eye
164155
:color: primary
@@ -273,7 +264,7 @@ dependencies for development work or additional features.
273264

274265
### Install dependency groups
275266

276-
When users install your package, only core dependencies are installed by
267+
When someone installs your package, only core dependencies are installed by
277268
default. To install optional dependencies, you
278269
need to specify which groups to include when installing the package.
279270

@@ -288,97 +279,102 @@ core dependencies, and the test dependencies from the
288279
`[project.optional-dependencies]` table.
289280
:::
290281

291-
### Using uv
282+
### Using uv or pip for installation
292283

293284
UV streamlines this process, allowing you to sync a venv in your project directory
294285
with both an editable install of your package and its dependencies automatically.
286+
You can also use pip and install dependencies into the environment of your choice.
295287

296288
:::{todo}
297289
We shouldn't show UV pip install, so how do you add optional feature deps with UV??
298290
:::
299291

300-
**Install optional dependencies:**
301-
```bash
302-
# FIXME
303-
uv pip install -e ".[docs]" # Single group
304-
uv pip install -e ".[docs,tests,lint]" # Multiple groups
305-
```
306292

307293
**Install development groups:**
308294

309-
You can use uv sync to sync dependency groups too
310-
```bash
311-
# TEST ME
312-
uv sync --group docs # Single group
313-
uv sync --group docs --group test # Multiple groups
314-
uv sync --all-groups # All development groups
295+
:::::{tab-set}
296+
297+
::::{tab-item} Use UV
298+
You can use uv sync to sync dependency groups in your uv-managed venv
299+
300+
```console
301+
$ uv sync --group docs # Single group
302+
$ uv sync --group docs --group test # Multiple groups
303+
$ uv sync --all-groups # All development groups
315304
```
316305

317-
**Install everything (package + all dependencies):**
318-
```bash
319-
uv sync --all-extras --all-groups
306+
**Install optional dependencies:**
307+
308+
```console
309+
# uv pip install is not idea if you are using uv supported venvs for your project
310+
$ uv pip install -e ".[docs]" # Single group
311+
$ uv pip install -e ".[docs,tests,lint]" # Multiple groups
320312
```
321313

322-
:::{admonition} uv sync vs uv pip install
323-
:class: tip
314+
**Install everything (package + all dependencies):**
315+
316+
```console
317+
$ uv sync --all-extras --all-groups
318+
```
324319

325320
`uv sync` is the recommended command for development workflows. It
326321
manages your virtual environment and keeps your lockfile up to date.
327322
Use `uv pip install` when you need pip-compatible behavior.
328-
:::
323+
::::
329324

330-
### Using pip
325+
::::{tab-item} Use pip (version >=25.1)
331326

332327
**Install optional dependencies:**
333-
```bash
328+
329+
```console
334330
python -m pip install -e ".[docs]" # Single group
335331
python -m pip install -e ".[docs,tests,lint]" # Multiple groups
336332
```
333+
**Install dependency groups:**
337334

338-
:::{admonition} Using `python -m pip install` vs. `pip install`
335+
```console
336+
python -m pip install --group test # Single group
337+
python -m pip install --group docs # Multiple groups
338+
```
339339

340-
We recommend calling pip using `python -m pip` to ensure you're using
340+
Always call pip using `python -m pip` to ensure you're using
341341
the pip from your current active Python environment. This helps avoid
342342
installation conflicts.
343-
:::
344-
345-
346-
:::{admonition} For zsh shell users
347-
:class: tip
348343

349-
Some shells (like zsh on Mac and certain Windows shells) require quotes
350-
around brackets:
344+
**Note:** Some shells (like zsh on Mac) require quotes around brackets to run successfully:
351345

352346
`python -m pip install ".[tests]"`
353347

354-
Without quotes, the command may fail in these shells.
355348
:::
349+
::::
350+
351+
:::::
352+
353+
356354

357355
### Combining dependency groups
358356

359-
You can create combined groups that reference other groups:
357+
You can also create combined groups that reference other groups:
358+
360359
```toml
361360
[project.optional-dependencies]
362361
test = ["pytest", "pytest-cov"]
363362
docs = ["sphinx", "pydata-sphinx-theme"]
364363
dev = ["your-package[test,docs]", "build", "twine"]
365364
```
366365

367-
Then install everything with:
366+
Then install everything with pip install or uv sync as needed:
368367
```bash
369368
uv pip install -e ".[dev]"
370369
# or
371370
python -m pip install ".[dev]"
372371
```
373372

374373
:::{tip}
375-
When you install optional dependencies, pip and uv also install your
374+
When you install optional dependencies, pip and uv install your
376375
package and its core dependencies automatically.
377376
:::
378377

379-
:::{tip}
380-
You can control which versions of dependencies are compatible with your package using specifiers. You will learn more about dependency specifiers in the sections below.
381-
:::
382378

383379
## Version specifiers for dependencies
384380

@@ -388,11 +384,11 @@ set version ranges.
388384

389385
### Common operators
390386

391-
- **`>=`** - Minimum version set: `numpy>=1.20` (This is the most common approach and is recommended)
392-
- **`==`** - Exact version: `requests==2.28.0` (Avoid pinning dependencies like this unless absolutely necessary)
393-
- **`~=`** - Compatible release: `django~=4.2.0` (Allows patches: >=4.2.0,<4.3.0)
387+
- **`>=`** Minimum version set: `numpy>=1.20` (This is the most common approach and is recommended)
388+
- **`==`** Exact version: `requests==2.28.0` (Avoid pinning dependencies like this unless necessary)
389+
- **`~=`** Compatible release: `django~=4.2.0` (Allows patches: >=4.2.0,<4.3.0)
394390
- **`<` or `>`** - Upper/lower bounds: `pandas>=1.0,<3.0`
395-
- **`!=`** - Exclude version: `scipy>=1.7,!=1.8.0` (Rare but allows you to skip a buggy release version)
391+
- **`!=`** Exclude version: `scipy>=1.7,!=1.8.0` (Rare but allows you to skip a buggy release version)
396392

397393
:::{tip}
398394
**Best practice:** Use `>=` to specify your minimum tested version and
@@ -410,10 +406,14 @@ dependencies = [
410406

411407
### Using conda and pixi
412408

409+
:::{todo}
410+
Ask matthew to review this section...
411+
:::
412+
413413
The `pyproject.toml` file works great for pure-Python packages. However,
414414
some packages (particularly in the scientific Python ecosystem) require
415415
dependencies written in other languages like C or Fortran. Conda was
416-
created to support distribution of tools with non-Python dependencies.
416+
created to support the distribution of tools with non-Python dependencies.
417417

418418
**For conda users:**
419419

0 commit comments

Comments
 (0)