Skip to content

Commit

Permalink
fix some outdated info in the docs, improve some wording and add some…
Browse files Browse the repository at this point in the history
… more info about baseline
  • Loading branch information
DetachHead committed Sep 30, 2024
1 parent d2e043b commit ed150be
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 37 deletions.
9 changes: 8 additions & 1 deletion docs/benefits-over-pyright/baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ have you ever wanted to adopt a new tool or enable new checks in an existing pro

to enable baseline, run `basedpyright --writebaseline` in your terminal or run the _"basedpyright: Write new errors to baseline"_ task in vscode. this will generate a `./basedpyright/baseline.json` for your project. you should commit this file so others working on your project can benefit from it too.

this file gets automatically updated as errors are removed over time in both the CLI and the language server. if you ever need to baseline new errors or an error that resurfaced because you've modified the same line of code it was on, just run that command again.
## how often do i need to update the baseline file?

this file gets automatically updated as errors are removed over time in both the CLI and the language server. you should only manually run the write baseline command in the following scenarios:

- a baselined error incorrectly resurfaces when updating unrelated code
- you're enabling a new diagnostic rule and want to baseline all the new errors it reported

if you need to suppress a diagnostic for another reason, consider using [a `# pyright: ignore` comment](../configuration/comments.md#prefer-pyrightignore-comments) instead.

## how does it work?

Expand Down
38 changes: 25 additions & 13 deletions docs/benefits-over-pyright/new-diagnostic-rules.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
# new diagnostic rules

this section lists all of the new diagnostic rules that are exclusive to basedpyright and the motivationbehind them. for a complete list of all diagnostic rules, [see here](../configuration/config-files.md#type-check-rule-overrides).

## `reportUnreachable`

pyright often incorrectly marks code as unreachable. in most cases, unreachable code is a mistake and therefore should be an error, but pyright does not have an option to report unreachable code. in fact, unreachable code is not even type-checked at all:
pyright often incorrectly marks code as unreachable. in most cases, unreachable code is a mistake and therefore should be an error, but pyright does not have an option to report unreachable code as an error, only as agreyed-out hint in your IDE:

```py
if sys.platform == "win32":
1 + "" # no error
do_thing() # no error
```

![](unreachable-hint.png)

this is very easy to miss, especially since it doesn't cause the CLI to fail so such a mistake could easily pass your CI.

by default, pyright will treat the body in the code above as unreachable if pyright itself was run on an operating system other than windows. this is bad of course, because chances are if you write such a check, you intend for your code to be executed on multiple platforms.

to make things worse, unreachable code is not even type-checked, so the obviously invalid `1 + ""` above will go completely unnoticed by the type checker.
to make things worse, unreachable code is not even type-checked at all! so if the code is reached, and the `do_thing` function isn't being called with the correct arguments, pyright will not complain!

`reportUnreachable` solves this problem by reporting unreachable code as an error by default.

basedpyright solves this issue with a `reportUnreachable` option, which will report an error on such unchecked code. in this example, you can [update your pyright config to specify more platforms using the `pythonPlatform` option](https://github.com/detachhead/basedpyright/blob/main/docs/configuration.md#main-configuration-options) if you intend for the code to be reachable.
!!! note

the above example with `sys.platform` won't happen by default in basedpyright anyway, because [we've changed the default `pythonPlatform` to `"All"`](./better-defaults.md#pythonplatform). but other cases such as python version checks will still benefit from this rule.

## `reportAny`

Expand All @@ -37,7 +47,9 @@ it's good practice to specify an error code in your `pyright: ignore` comments:

this way, if the error changes or a new error appears on the same line in the future, you'll get a new error because the comment doesn't account for the other error.

note that `type: ignore` comments (`enableTypeIgnoreComments`) are unsafe and are disabled by default (see [#330](https://github.com/DetachHead/basedpyright/issues/330) and [#55](https://github.com/DetachHead/basedpyright/issues/55)). we recommend using `pyright: ignore` comments instead.
!!! note

`type: ignore` comments ([`enableTypeIgnoreComments`](../configuration/config-files.md#enableTypeIgnoreComments)) are unsafe and are disabled by default (see [#330](https://github.com/DetachHead/basedpyright/issues/330) and [#55](https://github.com/DetachHead/basedpyright/issues/55)). we recommend using `pyright: ignore` comments instead.

## `reportPrivateLocalImportUsage`

Expand Down Expand Up @@ -106,18 +118,18 @@ cast(str, foo)

in this example, it's impossible to be `foo` to be a `str` if it's also an `int`, because the `int` and `str` types do not overlap. the `reportInvalidCast` rule will report invalid casts like these.

### note about casting with `TypedDict`s
!!! note "note about casting with `TypedDict`s"

a common use case of `cast` is to convert a regular `dict` into a `TypedDict`:
a common use case of `cast` is to convert a regular `dict` into a `TypedDict`:

```py
foo: dict[str, int | str]
bar = cast(dict[{"foo": int, "bar": str}], foo)
```
```py
foo: dict[str, int | str]
bar = cast(dict[{"foo": int, "bar": str}], foo)
```

unfortunately, this will cause a `reportInvalidCast` error when this rule is enabled, because although at runtime `TypedDict` is a `dict`, type checkers treat it as an unrelated subtype of `Mapping` that doesn't have a `clear` method, which would break its type-safety if it were to be called on a `TypedDict`.
unfortunately, this will cause a `reportInvalidCast` error when this rule is enabled, because although at runtime `TypedDict` is a `dict`, type checkers treat it as an unrelated subtype of `Mapping` that doesn't have a `clear` method, which would break its type-safety if it were to be called on a `TypedDict`.

this means that although casting between them is a common use case, `TypedDict`s and `dict`s technically do not overlap.
this means that although casting between them is a common use case, `TypedDict`s and `dict`s technically do not overlap.

## `reportUnsafeMultipleInheritance`

Expand Down
Binary file added docs/benefits-over-pyright/unreachable-hint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 18 additions & 6 deletions docs/configuration/command-line.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Command-Line
## Command-Line

Usage: basedpyright [options] [files...] (1)

Pyright can be run as either a VS Code extension or as a command-line tool. The command-line version allows for the following options:
basedpyright can be run as either a VS Code extension or as a command-line tool. The command-line version allows for the following options:

| Flag | Description |
| :--------------------------------- | :--------------------------------------------------- |
Expand Down Expand Up @@ -43,7 +43,7 @@ Pyright can be run as either a VS Code extension or as a command-line tool. The
(6) When running in watch mode, pyright will reanalyze only those files that have been modified. These “deltas” are typically much faster than the initial analysis, which needs to analyze all files in the source tree.


# Pyright Exit Codes
## Pyright Exit Codes

| Exit Code | Meaning |
| :---------- | :--------------------------------------------------------------- |
Expand All @@ -54,7 +54,7 @@ Pyright can be run as either a VS Code extension or as a command-line tool. The
| 4 | Illegal command-line parameters specified |


# JSON Output
## JSON Output

If the “--outputjson” option is specified on the command line, diagnostics are output in JSON format. The JSON structure is as follows:
```javascript
Expand Down Expand Up @@ -97,7 +97,7 @@ Diagnostic line and character numbers are zero-based.

Not all diagnostics have an associated diagnostic rule. Diagnostic rules are used only for diagnostics that can be disabled or enabled. If a rule is associated with the diagnostic, it is included in the output. If it’s not, the rule field is omitted from the JSON output.

# Gitlab code quality report
## Gitlab code quality report

the `--gitlabcodequality` argument will output a [gitlab code quality report](https://docs.gitlab.com/ee/ci/testing/code_quality.html).

Expand All @@ -109,4 +109,16 @@ basedpyright:
artifacts:
reports:
codequality: report.json
```
```
## Regenerating the baseline file
if you're using [baseline](../benefits-over-pyright/baseline.md), as baselined errors are removed from your code, the CLI will automatically update the `./.basedpyright/baseline.json` file to remove them:

```
>basedpyright
updated ./.basedpyright/baseline.json with 200 errors (went down by 5)
0 errors, 0 warnings, 0 notes
```
the `--writebaseline` argument is only required if you are intentionally writing new errors to the baseline file. for more information about when to use this argument, [see here](../benefits-over-pyright/baseline.md#how-often-do-i-need-to-update-the-baseline-file).
16 changes: 15 additions & 1 deletion docs/configuration/comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,24 @@ Diagnostic levels are also supported.

## Line-level Diagnostic Suppression

PEP 484 defines a special comment `# type: ignore` that can be used at the end of a line to suppress all diagnostics emitted by a type checker on that line. Pyright supports this mechanism.
PEP 484 defines a special comment `# type: ignore` that can be used at the end of a line to suppress all diagnostics emitted by a type checker on that line. Pyright supports this mechanism. this is disabled by default in basedpyright. [see below](#prefer-pyrightignore-comments) for more information.

Pyright also supports a `# pyright: ignore` comment at the end of a line to suppress all Pyright diagnostics on that line. This can be useful if you use multiple type checkers on your source base and want to limit suppression of diagnostics to Pyright only.

The `# pyright: ignore` comment accepts an optional list of comma-delimited diagnostic rule names surrounded by square brackets. If such a list is present, only diagnostics within those diagnostic rule categories are suppressed on that line. For example, `# pyright: ignore [reportPrivateUsage, reportGeneralTypeIssues]` would suppress diagnostics related to those two categories but no others.

If the `reportUnnecessaryTypeIgnoreComment` configuration option is enabled, any unnecessary `# type: ignore` and `# pyright: ignore` comments will be reported so they can be removed.

### prefer `# pyright:ignore` comments

`# pyright:ignore` comments are preferred over `# type:ignore` comments because they are more strict than `#type:ignore` comments:

- `# type:ignore` comments will always suppress all errors on the line, regardless of what diagnostic rules are specified in brackets
- `# type:ignore` comments are not checked to ensure that the specified rule is valud:
```py
# no error here, even though you are suppressing an invalid diagnostic code.
1 + "" # type:ignore[asdf]
```
this decision was probably made to support other type checkers like mypy which use different codes to pyright, but in that case you should just disable `enableTypeIgnoreComments` to prevent pyright from looking at them.

in basedpyright, `enableTypeIgnoreComments` is disabled by default to avoid these issues.
10 changes: 7 additions & 3 deletions docs/configuration/config-files.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
## Pyright Configuration

Pyright offers flexible configuration options specified in a JSON-formatted text configuration. By default, the file is called “pyrightconfig.json” and is located within the root directory of your project. Multi-root workspaces (“Add Folder to Workspace…”) are supported, and each workspace root can have its own “pyrightconfig.json” file. For a sample pyrightconfig.json file, see [below](../configuration/config-files.md#sample-config-file).
basedpyright offers flexible configuration options specified in a JSON-formatted text configuration. By default, the file is called “pyrightconfig.json” and is located within the root directory of your project. Multi-root workspaces (“Add Folder to Workspace…”) are supported, and each workspace root can have its own “pyrightconfig.json” file. For a sample pyrightconfig.json file, see [below](../configuration/config-files.md#sample-config-file).

Pyright settings can also be specified in a `[tool.basedpyright]` section of a “pyproject.toml” file. A “pyrightconfig.json” file always takes precedent over “pyproject.toml” if both are present. For a sample pyproject.toml file, see [below](../configuration/config-files.md#sample-pyprojecttoml-file).
basedpyright settings can also be specified in a `[tool.basedpyright]` section of a “pyproject.toml” file. A “pyrightconfig.json” file always takes precedent over “pyproject.toml” if both are present. For a sample pyproject.toml file, see [below](../configuration/config-files.md#sample-pyprojecttoml-file).

!!! info

the `[tool.pyright]` section in `pyproject.toml` is also supported for backwards compatibility with existing pyright configs.

Relative paths specified within the config file are relative to the config file’s location. Paths with shell variables (including `~`) are not supported. Paths within a config file should generally be relative paths so the config file can be shared by other developers who contribute to the project.

## Environment Options

The following settings control the *environment* in which Pyright will check for diagnostics. These settings determine how Pyright finds source files, imports, and what Python version specific rules are applied.
The following settings control the *environment* in which basedpyright will check for diagnostics. These settings determine how Pyright finds source files, imports, and what Python version specific rules are applied.

- **include** [array of paths, optional]: Paths of directories or files that should be considered part of the project. If no paths are specified, pyright defaults to the directory that contains the config file. Paths may contain wildcard characters ** (a directory or multiple levels of directories), * (a sequence of zero or more characters), or ? (a single character). If no include paths are specified, the root path for the workspace is assumed.

Expand Down
2 changes: 1 addition & 1 deletion docs/installation/command-line-and-language-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ once installed, the `basedpyright` and `basedpyright-langserver` scripts will be
basedpyright --help
```

for instructions on how to use `basedpyright-langserver`, see the [IDE-specific instructions below](./ides.md).
for instructions on how to use `basedpyright-langserver`, see the [IDE-specific instructions](./ides.md).
10 changes: 5 additions & 5 deletions docs/installation/ides.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ install the extension from [the vscode extension marketplace](https://marketplac

clicking "Fix settings & keep both extensions" will set the following settings for you automatically:

```jsonc
// .vscode/settings.json
```json title=".vscode/settings.json"
{
// disable pylance's type checking and only use its language server
"python.analysis.typeCheckingMode": "off",

// disable basedpyright's language server and only use its type checking
"basedpyright.disableLanguageServices": true
}
```
Expand All @@ -40,9 +42,7 @@ the basedpyright extension will automatically look for the pypi package in your

if you're adding basedpyright as a development dependency in your project, we recommend adding it to the recommended extensions list in your workspace to prompt others working on your repo to install it:

```jsonc
// .vscode/extensions.json

```json title=".vscode/extensions.json"
{
"recommendations": ["detachhead.basedpyright"]
}
Expand Down
4 changes: 1 addition & 3 deletions docs/installation/pre-commit hook.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# pre-commit hook

```yaml
# .pre-commit-config.yaml

```yaml title=".pre-commit-config.yaml"
repos:
- repo: https://github.com/DetachHead/basedpyright-pre-commit-mirror
rev: v1.13.0 # or whatever the latest version is at the time
Expand Down
17 changes: 13 additions & 4 deletions docs/usage/commands.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
## VS Code Commands
# VS Code Commands

Pyright offers the following commands, which can be invoked from VS Code’s “Command Palette”, which can be accessed from the View menu or by pressing Cmd-Shift-P.
basedyright offers the following commands, which can be invoked from VS Code’s “Command Palette”, which can be accessed from the View menu or by pressing Cmd-Shift-P.

### Organize Imports
## Organize Imports
This command reorders all imports found in the global (module-level) scope of the source file. As recommended in PEP8, imports are grouped into three groups, each separated by an empty line. The first group includes all built-in modules, the second group includes all third-party modules, and the third group includes all local modules.

Within each group, imports are sorted alphabetically. And within each “from X import Y” statement, the imported symbols are sorted alphabetically. Pyright also rewraps any imports that don't fit within a single line, switching to multi-line formatting.

### Restart Server
!!! note

we recommend using [ruff](https://docs.astral.sh/ruff/formatter/#sorting-imports) to organize your imports instead, because pyright does not provide a way to validate that imports are sorted via the CLI.

## Restart Server
This command forces the type checker to discard all of its cached type information and restart analysis. It is useful in cases where new type stubs or libraries have been installed.


## Write new errors to baseline

writes any new errors to the [baseline](../benefits-over-pyright/baseline.md) file. the language server will automatically update it on-save if errors are removed from a file and no new errors were added. for more information about when to use this command, [see here](../benefits-over-pyright/baseline.md#how-often-do-i-need-to-update-the-baseline-file).

0 comments on commit ed150be

Please sign in to comment.