From 59f712a566edb679c20c100fe14e100a17253d5f Mon Sep 17 00:00:00 2001 From: eth3lbert Date: Mon, 12 Aug 2024 15:17:32 +0800 Subject: [PATCH] Improvements to documentation (#12712) Co-authored-by: Micha Reiser --- .markdownlint.yaml | 3 ++ docs/configuration.md | 16 +++++----- docs/faq.md | 8 ++--- docs/installation.md | 60 +++++++++++++++++++------------------- docs/js/extra.js | 59 +++++++++++++++++++++++++++++++++++++ docs/linter.md | 24 +++++++-------- docs/stylesheets/extra.css | 6 ++++ docs/tutorial.md | 40 ++++++++++++------------- mkdocs.template.yml | 2 ++ 9 files changed, 144 insertions(+), 74 deletions(-) create mode 100644 docs/js/extra.js diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 15656efe736ec..bdad15c5a58cc 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -14,6 +14,9 @@ MD041: false # MD013/line-length MD013: false +# MD014/commands-show-output +MD014: false + # MD024/no-duplicate-heading MD024: # Allow when nested under different parents e.g. CHANGELOG.md diff --git a/docs/configuration.md b/docs/configuration.md index 02c9dae92bf19..8571c5e23af3e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -457,8 +457,8 @@ Some configuration options can be provided or overridden via dedicated flags on This includes those related to rule enablement and disablement, file discovery, logging level, and more: -```shell -ruff check path/to/code/ --select F401 --select F403 --quiet +```console +$ ruff check path/to/code/ --select F401 --select F403 --quiet ``` All other configuration options can be set via the command line @@ -469,8 +469,8 @@ using the `--config` flag, detailed below. The `--config` flag has two uses. It is most often used to point to the configuration file that you would like Ruff to use, for example: -```shell -ruff check path/to/directory --config path/to/ruff.toml +```console +$ ruff check path/to/directory --config path/to/ruff.toml ``` However, the `--config` flag can also be used to provide arbitrary @@ -484,8 +484,8 @@ since this setting has no dedicated CLI flag. The `per-file-ignores` setting could also have been overridden via the `--per-file-ignores` dedicated flag, but using `--config` to override the setting is also fine: -```shell -ruff check path/to/file --config path/to/ruff.toml --config "lint.dummy-variable-rgx = '__.*'" --config "lint.per-file-ignores = {'some_file.py' = ['F841']}" +```console +$ ruff check path/to/file --config path/to/ruff.toml --config "lint.dummy-variable-rgx = '__.*'" --config "lint.per-file-ignores = {'some_file.py' = ['F841']}" ``` Configuration options passed to `--config` are parsed in the same way @@ -500,8 +500,8 @@ a dedicated flag and by the `--config` flag, the dedicated flag takes priority. In this example, the maximum permitted line length will be set to 90, not 100: -```shell -ruff format path/to/file --line-length=90 --config "line-length=100" +```console +$ ruff format path/to/file --line-length=90 --config "line-length=100" ``` Specifying `--config "line-length=90"` will override the `line-length` diff --git a/docs/faq.md b/docs/faq.md index ebc4f9ebd8915..6a4153601ea80 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -228,8 +228,8 @@ Ruff is installable under any Python version from 3.7 onwards. Nope! Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI: -```shell -pip install ruff +```console +$ pip install ruff ``` Ruff ships with wheels for all major platforms, which enables `pip` to install Ruff without relying @@ -427,8 +427,8 @@ code formatters over Jupyter Notebooks. After installing `ruff` and `nbqa`, you can run Ruff over a notebook like so: -```shell -> nbqa ruff Untitled.ipynb +```console +$ nbqa ruff Untitled.ipynb Untitled.ipynb:cell_1:2:5: F841 Local variable `x` is assigned to but never used Untitled.ipynb:cell_2:1:1: E402 Module level import not at top of file Untitled.ipynb:cell_2:1:8: F401 `os` imported but unused diff --git a/docs/installation.md b/docs/installation.md index 57101e8156c68..d73fafa1c1e80 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -2,81 +2,81 @@ Ruff is available as [`ruff`](https://pypi.org/project/ruff/) on PyPI: -```shell -pip install ruff +```console +$ pip install ruff ``` Once installed, you can run Ruff from the command line: -```shell -ruff check # Lint all files in the current directory. -ruff format # Format all files in the current directory. +```console +$ ruff check # Lint all files in the current directory. +$ ruff format # Format all files in the current directory. ``` Starting with version `0.5.0`, Ruff can be installed with our standalone installers: -```shell -# On macOS and Linux. -curl -LsSf https://astral.sh/ruff/install.sh | sh +```console +$ # On macOS and Linux. +$ curl -LsSf https://astral.sh/ruff/install.sh | sh -# On Windows. -powershell -c "irm https://astral.sh/ruff/install.ps1 | iex" +$ # On Windows. +$ powershell -c "irm https://astral.sh/ruff/install.ps1 | iex" -# For a specific version. -curl -LsSf https://astral.sh/ruff/0.5.0/install.sh | sh -powershell -c "irm https://astral.sh/ruff/0.5.0/install.ps1 | iex" +$ # For a specific version. +$ curl -LsSf https://astral.sh/ruff/0.5.0/install.sh | sh +$ powershell -c "irm https://astral.sh/ruff/0.5.0/install.ps1 | iex" ``` For **macOS Homebrew** and **Linuxbrew** users, Ruff is also available as [`ruff`](https://formulae.brew.sh/formula/ruff) on Homebrew: -```shell -brew install ruff +```console +$ brew install ruff ``` For **Conda** users, Ruff is also available as [`ruff`](https://anaconda.org/conda-forge/ruff) on `conda-forge`: -```shell -conda install -c conda-forge ruff +```console +$ conda install -c conda-forge ruff ``` For **pkgx** users, Ruff is also available as [`ruff`](https://pkgx.dev/pkgs/github.com/charliermarsh/ruff/) on the `pkgx` registry: -```shell -pkgx install ruff +```console +$ pkgx install ruff ``` For **Arch Linux** users, Ruff is also available as [`ruff`](https://archlinux.org/packages/extra/x86_64/ruff/) on the official repositories: -```shell -pacman -S ruff +```console +$ pacman -S ruff ``` For **Alpine** users, Ruff is also available as [`ruff`](https://pkgs.alpinelinux.org/package/edge/testing/x86_64/ruff) on the testing repositories: -```shell -apk add ruff +```console +$ apk add ruff ``` For **openSUSE Tumbleweed** users, Ruff is also available in the distribution repository: -```shell -sudo zypper install python3-ruff +```console +$ sudo zypper install python3-ruff ``` On **Docker**, it is published as `ghcr.io/astral-sh/ruff`, tagged for each release and `latest` for the latest release. -```shell -docker run -v .:/io --rm ghcr.io/astral-sh/ruff check -docker run -v .:/io --rm ghcr.io/astral-sh/ruff:0.3.0 check +```console +$ docker run -v .:/io --rm ghcr.io/astral-sh/ruff check +$ docker run -v .:/io --rm ghcr.io/astral-sh/ruff:0.3.0 check -# Or, for Podman on SELinux. -docker run -v .:/io:Z --rm ghcr.io/astral-sh/ruff check +$ # Or, for Podman on SELinux. +$ docker run -v .:/io:Z --rm ghcr.io/astral-sh/ruff check ``` [![Packaging status](https://repology.org/badge/vertical-allrepos/ruff-python-linter.svg?exclude_unsupported=1)](https://repology.org/project/ruff-python-linter/versions) diff --git a/docs/js/extra.js b/docs/js/extra.js new file mode 100644 index 0000000000000..0d3f69177b642 --- /dev/null +++ b/docs/js/extra.js @@ -0,0 +1,59 @@ +function cleanupClipboardText(targetSelector) { + const targetElement = document.querySelector(targetSelector); + + // exclude "Generic Prompt" and "Generic Output" spans from copy + const excludedClasses = ["gp", "go"]; + + const clipboardText = Array.from(targetElement.childNodes) + .filter( + (node) => + !excludedClasses.some((className) => + node?.classList?.contains(className), + ), + ) + .map((node) => node.textContent) + .filter((s) => s !== ""); + return clipboardText.join("").trim(); +} + +// Sets copy text to attributes lazily using an Intersection Observer. +function setCopyText() { + // The `data-clipboard-text` attribute allows for customized content in the copy + // See: https://www.npmjs.com/package/clipboard#copy-text-from-attribute + const attr = "clipboardText"; + // all "copy" buttons whose target selector is a element + const elements = document.querySelectorAll( + 'button[data-clipboard-target$="code"]', + ); + + if (elements.length === 0) { + return; + } + + const observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + // target in the viewport that have not been patched + if ( + entry.intersectionRatio > 0 && + entry.target.dataset[attr] === undefined + ) { + entry.target.dataset[attr] = cleanupClipboardText( + entry.target.dataset.clipboardTarget, + ); + } + }); + }); + + elements.forEach((elt) => { + observer.observe(elt); + }); +} + +// Using the document$ observable is particularly important if you are using instant loading since +// it will not result in a page refresh in the browser +// See `How to integrate with third-party JavaScript libraries` guideline: +// https://squidfunk.github.io/mkdocs-material/customization/?h=javascript#additional-javascript +document$.subscribe(function () { + setCopyText(); +}); + diff --git a/docs/linter.md b/docs/linter.md index a3956c1d8d4e0..66e90bc83a8d7 100644 --- a/docs/linter.md +++ b/docs/linter.md @@ -10,11 +10,11 @@ and more. `ruff check` is the primary entrypoint to the Ruff linter. It accepts a list of files or directories, and lints all discovered Python files, optionally fixing any fixable errors: -```shell -ruff check # Lint all files in the current directory. -ruff check --fix # Lint all files in the current directory, and fix any fixable errors. -ruff check --watch # Lint all files in the current directory, and re-lint on change. -ruff check path/to/code/ # Lint all files in `path/to/code` (and any subdirectories). +```console +$ ruff check # Lint all files in the current directory. +$ ruff check --fix # Lint all files in the current directory, and fix any fixable errors. +$ ruff check --watch # Lint all files in the current directory, and re-lint on change. +$ ruff check path/to/code/ # Lint all files in `path/to/code` (and any subdirectories). ``` For the full list of supported options, run `ruff check --help`. @@ -151,8 +151,8 @@ imports, reformat docstrings, rewrite type annotations to use newer Python synta To enable fixes, pass the `--fix` flag to `ruff check`: -```shell -ruff check --fix +```console +$ ruff check --fix ``` By default, Ruff will fix all violations for which safe fixes are available; to determine @@ -167,26 +167,26 @@ For example, [`unnecessary-iterable-allocation-for-first-element`](rules/unneces (`RUF015`) is a rule which checks for potentially unperformant use of `list(...)[0]`. The fix replaces this pattern with `next(iter(...))` which can result in a drastic speedup: -```shell +```console $ python -m timeit "head = list(range(99999999))[0]" 1 loop, best of 5: 1.69 sec per loop ``` -```shell +```console $ python -m timeit "head = next(iter(range(99999999)))" 5000000 loops, best of 5: 70.8 nsec per loop ``` However, when the collection is empty, this changes the raised exception from an `IndexError` to `StopIteration`: -```shell +```console $ python -c 'list(range(0))[0]' Traceback (most recent call last): File "", line 1, in IndexError: list index out of range ``` -```shell +```console $ python -c 'next(iter(range(0)))[0]' Traceback (most recent call last): File "", line 1, in @@ -197,7 +197,7 @@ Since this could break error handling, this fix is categorized as unsafe. Ruff only enables safe fixes by default. Unsafe fixes can be enabled by settings [`unsafe-fixes`](settings.md#unsafe-fixes) in your configuration file or passing the `--unsafe-fixes` flag to `ruff check`: -```shell +```console # Show unsafe fixes ruff check --unsafe-fixes diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index f22129ecb1c9a..b3c35723d854e 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -103,3 +103,9 @@ color: var(--md-code-fg-color); background-color: var(--md-code-bg-color); } + +/* See: https://mkdocstrings.github.io/recipes/#prevent-selection-of-prompts-and-output-in-python-code-blocks */ +.highlight .gp, .highlight .go { /* Generic.Prompt, Generic.Output */ + user-select: none; +} + diff --git a/docs/tutorial.md b/docs/tutorial.md index 39906ca6784bf..313745f985a2b 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -7,8 +7,8 @@ your project. For a more detailed overview, see [_Configuring Ruff_](configurati To start, we'll install Ruff through PyPI (or with your [preferred package manager](installation.md)): -```shell -pip install ruff +```console +$ pip install ruff ``` Let's then assume that our project structure looks like: @@ -37,8 +37,8 @@ def sum_even_numbers(numbers: Iterable[int]) -> int: We can run the Ruff linter over our project via `ruff check`: -```shell -❯ ruff check +```console +$ ruff check numbers/numbers.py:3:8: F401 [*] `os` imported but unused Found 1 error. [*] 1 fixable with the `--fix` option. @@ -47,8 +47,8 @@ Found 1 error. 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`: -```shell -❯ ruff check --fix +```console +$ ruff check --fix Found 1 error (1 fixed, 0 remaining). ``` @@ -73,14 +73,14 @@ 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: -```shell -❯ ruff check numbers/numbers.py +```console +$ ruff check numbers/numbers.py ``` Now that our project is passing `ruff check`, we can run the Ruff formatter via `ruff format`: -```shell -❯ ruff format +```console +$ ruff format 1 file reformatted ``` @@ -140,8 +140,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: -```shell -❯ ruff check +```console +$ ruff check numbers/numbers.py:5:80: E501 Line too long (90 > 79) Found 1 error. ``` @@ -222,8 +222,8 @@ rules, we can set our configuration file to the following: If we run Ruff again, we'll see that it now enforces the pyupgrade rules. In particular, Ruff flags the use of the deprecated `typing.Iterable` instead of `collections.abc.Iterable`: -```shell -❯ ruff check +```console +$ ruff check numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable` Found 1 error. [*] 1 fixable with the `--fix` option. @@ -265,8 +265,8 @@ all functions have docstrings: If we run Ruff again, we'll see that it now enforces the pydocstyle rules: -```shell -❯ ruff check +```console +$ 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 @@ -290,8 +290,8 @@ def sum_even_numbers(numbers: Iterable[int]) -> int: Running `ruff check` again, we'll see that it no longer flags the `Iterable` import: -```shell -❯ ruff check +```console +$ ruff check numbers/__init__.py:1:1: D104 Missing docstring in public package numbers/numbers.py:1:1: D100 Missing docstring in public module Found 3 errors. @@ -321,8 +321,8 @@ Ruff enables this workflow via the `--add-noqa` flag, which will add a `# noqa` line based on its existing violations. We can combine `--add-noqa` with the `--select` command-line flag to add `# noqa` directives to all existing `UP035` violations: -```shell -❯ ruff check --select UP035 --add-noqa . +```console +$ ruff check --select UP035 --add-noqa . Added 1 noqa directive. ``` diff --git a/mkdocs.template.yml b/mkdocs.template.yml index a34a8881ca9e5..89b64855adfd0 100644 --- a/mkdocs.template.yml +++ b/mkdocs.template.yml @@ -63,6 +63,8 @@ plugins: - typeset extra_css: - stylesheets/extra.css +extra_javascript: + - js/extra.js not_in_nav: | /rules/* /formatter/*