Skip to content

Commit

Permalink
Use uv in tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jan 7, 2025
1 parent a365dc5 commit af2a899
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 38 deletions.
3 changes: 2 additions & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ Ruff is installable under any Python version from 3.7 onwards.

## Do I need to install Rust to use Ruff?

Nope! Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI. We recommend installing Ruff with [uv](https://docs.astral.sh/uv/):
Nope! Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI. We recommend installing Ruff with [uv](https://docs.astral.sh/uv/),
though it's also installable with `pip`, `pipx`, and a [variety of other package managers](installation.md).

```console
$ # Install Ruff globally.
Expand Down
2 changes: 0 additions & 2 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI. We recommend installing Ruff with [uv](https://docs.astral.sh/uv/).

To install Ruff globally:

```console
$ # Install Ruff globally.
$ uv tool install ruff@latest
Expand Down
77 changes: 42 additions & 35 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,24 @@ your project. For a more detailed overview, see [_Configuring Ruff_](configurati

## Getting Started

To start, we'll install Ruff from PyPI. You can install Ruff with [uv](https://docs.astral.sh/uv/), or
your [preferred package manager](installation.md):
To start, we'll initialize a project using [uv](https://docs.astral.sh/uv/):

```console
$ # With uv.
$ uv tool install ruff@latest

$ # With pip.
$ pip install ruff

$ # With pipx.
$ pipx install ruff
$ uv init numbers
```

Let's then assume that our project structure looks like:
This command creates a Python project with the following structure:

```text
numbers
├── __init__.py
└── numbers.py
├── pyproject.toml
└── src
└── numbers
├── __init__.py
└── py.typed
```

...where `numbers.py` contains the following code:
We'll then replace the contents of `src/numbers/__init__.py` with the following code:

```python
from typing import Iterable
Expand All @@ -43,28 +38,40 @@ def sum_even_numbers(numbers: Iterable[int]) -> int:
)
```

We can run the Ruff linter over our project via `ruff check`:
Next, we'll add Ruff to our project:

```console
$ uv add --dev ruff
```

We can then run the Ruff linter over our project via `uv run ruff check`:

```console
$ ruff check
numbers/numbers.py:3:8: F401 [*] `os` imported but unused
$ uv run ruff check
src/numbers/__init__.py:3:8: F401 [*] `os` imported but unused
Found 1 error.
[*] 1 fixable with the `--fix` option.
```

!!! note

As an alternative to `uv run`, you can also run Ruff by activating the project's virtual
environment (`source .venv/bin/active` on Linux and macOS, or `.venv\Scripts\activate` on
Windows) and running `ruff check` directly.

Ruff identified an unused import, which is a common error in Python code. Ruff considers this a
"fixable" error, so we can resolve the issue automatically by running `ruff check --fix`:

```console
$ ruff check --fix
$ uv run ruff check --fix
Found 1 error (1 fixed, 0 remaining).
```

Running `git diff` shows the following:

```diff
--- a/numbers/numbers.py
+++ b/numbers/numbers.py
--- a/src/numbers/__init__.py
+++ b/src/numbers/__init__.py
@@ -1,7 +1,5 @@
from typing import Iterable

Expand All @@ -82,13 +89,13 @@ def sum_even_numbers(numbers: Iterable[int]) -> int:
Note Ruff runs in the current directory by default, but you can pass specific paths to check:

```console
$ ruff check numbers/numbers.py
$ uv run ruff check src/numbers/__init__.py
```

Now that our project is passing `ruff check`, we can run the Ruff formatter via `ruff format`:

```console
$ ruff format
$ uv run ruff format
1 file reformatted
```

Expand Down Expand Up @@ -117,7 +124,7 @@ Ruff's behavior.
To determine the appropriate settings for each Python file, Ruff looks for the first
`pyproject.toml`, `ruff.toml`, or `.ruff.toml` file in the file's directory or any parent directory.

To configure Ruff, let's create a configuration file in our project's root directory:
To configure Ruff, we'll add the following to the configuration file in our project's root directory:

=== "pyproject.toml"

Expand Down Expand Up @@ -149,8 +156,8 @@ To configure Ruff, let's create a configuration file in our project's root direc
Running Ruff again, we see that it now enforces a maximum line width, with a limit of 79:

```console
$ ruff check
numbers/numbers.py:5:80: E501 Line too long (90 > 79)
$ uv run ruff check
src/numbers/__init__.py:5:80: E501 Line too long (90 > 79)
Found 1 error.
```

Expand Down Expand Up @@ -231,8 +238,8 @@ If we run Ruff again, we'll see that it now enforces the pyupgrade rules. In par
the use of the deprecated `typing.Iterable` instead of `collections.abc.Iterable`:

```console
$ ruff check
numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable`
$ uv run ruff check
src/numbers/__init__.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable`
Found 1 error.
[*] 1 fixable with the `--fix` option.
```
Expand Down Expand Up @@ -274,10 +281,10 @@ all functions have docstrings:
If we run Ruff again, we'll see that it now enforces the pydocstyle rules:

```console
$ ruff check
$ uv run ruff check
numbers/__init__.py:1:1: D104 Missing docstring in public package
numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable`
numbers/numbers.py:1:1: D100 Missing docstring in public module
src/numbers/__init__.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable`
src/numbers/__init__.py:1:1: D100 Missing docstring in public module
Found 3 errors.
[*] 1 fixable with the `--fix` option.
```
Expand All @@ -299,9 +306,9 @@ def sum_even_numbers(numbers: Iterable[int]) -> int:
Running `ruff check` again, we'll see that it no longer flags the `Iterable` import:

```console
$ ruff check
$ uv run ruff check
numbers/__init__.py:1:1: D104 Missing docstring in public package
numbers/numbers.py:1:1: D100 Missing docstring in public module
src/numbers/__init__.py:1:1: D100 Missing docstring in public module
Found 3 errors.
```

Expand Down Expand Up @@ -330,7 +337,7 @@ line based on its existing violations. We can combine `--add-noqa` with the `--s
flag to add `# noqa` directives to all existing `UP035` violations:

```console
$ ruff check --select UP035 --add-noqa .
$ uv run ruff check --select UP035 --add-noqa .
Added 1 noqa directive.
```

Expand All @@ -339,8 +346,8 @@ Running `git diff` shows the following:
```diff
diff --git a/tutorial/src/main.py b/tutorial/src/main.py
index b9291c5ca..b9f15b8c1 100644
--- a/numbers/numbers.py
+++ b/numbers/numbers.py
--- a/src/numbers/__init__.py
+++ b/src/numbers/__init__.py
@@ -1,4 +1,4 @@
-from typing import Iterable
+from typing import Iterable # noqa: UP035
Expand Down

0 comments on commit af2a899

Please sign in to comment.