[ty] Ignore possibly-unresolved-reference by default (#17934)

This commit is contained in:
Micha Reiser 2025-05-08 17:44:56 +02:00 committed by GitHub
parent 067a8ac574
commit d608eae126
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 97 additions and 72 deletions

6
.github/mypy-primer-ty.toml vendored Normal file
View file

@ -0,0 +1,6 @@
#:schema ../ty.schema.json
# Configuration overrides for the mypy primer run
# Enable off-by-default rules.
[rules]
possibly-unresolved-reference = "warn"

View file

@ -50,6 +50,10 @@ jobs:
run: |
cd ruff
echo "Enabling mypy primer specific configuration overloads (see .github/mypy-primer-ty.toml)"
mkdir -p ~/.config/ty
cp .github/mypy-primer-ty.toml ~/.config/ty/ty.toml
PRIMER_SELECTOR="$(paste -s -d'|' crates/ty_python_semantic/resources/primer/good.txt)"
echo "new commit"

View file

@ -1394,33 +1394,6 @@ or `ImportError` at runtime.
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L822)
</details>
## `possibly-unresolved-reference`
**Default level**: warn
<details>
<summary>detects references to possibly undefined names</summary>
### What it does
Checks for references to names that are possibly not defined.
### Why is this bad?
Using an undefined variable will raise a `NameError` at runtime.
### Example
```python
for i in range(0):
x = i
print(x) # NameError: name 'x' is not defined
```
### Links
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unresolved-reference)
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L836)
</details>
## `redundant-cast`
**Default level**: warn
@ -1552,3 +1525,30 @@ a = 20 / 2
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Fsuppression.rs#L15)
</details>
## `possibly-unresolved-reference`
**Default level**: ignore
<details>
<summary>detects references to possibly undefined names</summary>
### What it does
Checks for references to names that are possibly not defined.
### Why is this bad?
Using an undefined variable will raise a `NameError` at runtime.
### Example
```python
for i in range(0):
x = i
print(x) # NameError: name 'x' is not defined
```
### Links
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unresolved-reference)
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L836)
</details>

View file

@ -369,12 +369,12 @@ fn configuration_rule_severity() -> anyhow::Result<()> {
for a in range(0, int(y)):
x = a
print(x) # possibly-unresolved-reference
prin(x) # unresolved-reference
"#,
)?;
// Assert that there's a possibly unresolved reference diagnostic
// and that division-by-zero has a severity of error by default.
// Assert that there's an `unresolved-reference` diagnostic (error)
// and a `division-by-zero` diagnostic (error).
assert_cmd_snapshot!(case.command(), @r"
success: false
exit_code: 1
@ -389,15 +389,15 @@ fn configuration_rule_severity() -> anyhow::Result<()> {
|
info: `lint:division-by-zero` is enabled by default
warning: lint:possibly-unresolved-reference: Name `x` used when possibly not defined
--> test.py:7:7
warning: lint:unresolved-reference: Name `prin` used when not defined
--> test.py:7:1
|
5 | x = a
6 |
7 | print(x) # possibly-unresolved-reference
| ^
7 | prin(x) # unresolved-reference
| ^^^^
|
info: `lint:possibly-unresolved-reference` is enabled by default
info: `lint:unresolved-reference` is enabled by default
Found 2 diagnostics
@ -409,7 +409,7 @@ fn configuration_rule_severity() -> anyhow::Result<()> {
r#"
[tool.ty.rules]
division-by-zero = "warn" # demote to warn
possibly-unresolved-reference = "ignore"
unresolved-reference = "ignore"
"#,
)?;
@ -448,12 +448,12 @@ fn cli_rule_severity() -> anyhow::Result<()> {
for a in range(0, int(y)):
x = a
print(x) # possibly-unresolved-reference
prin(x) # unresolved-reference
"#,
)?;
// Assert that there's a possibly unresolved reference diagnostic
// and that division-by-zero has a severity of error by default.
// Assert that there's an `unresolved-reference` diagnostic (error),
// a `division-by-zero` (error) and a unresolved-import (error) diagnostic by default.
assert_cmd_snapshot!(case.command(), @r"
success: false
exit_code: 1
@ -480,15 +480,15 @@ fn cli_rule_severity() -> anyhow::Result<()> {
|
info: `lint:division-by-zero` is enabled by default
warning: lint:possibly-unresolved-reference: Name `x` used when possibly not defined
--> test.py:9:7
warning: lint:unresolved-reference: Name `prin` used when not defined
--> test.py:9:1
|
7 | x = a
8 |
9 | print(x) # possibly-unresolved-reference
| ^
9 | prin(x) # unresolved-reference
| ^^^^
|
info: `lint:possibly-unresolved-reference` is enabled by default
info: `lint:unresolved-reference` is enabled by default
Found 3 diagnostics
@ -499,7 +499,7 @@ fn cli_rule_severity() -> anyhow::Result<()> {
case
.command()
.arg("--ignore")
.arg("possibly-unresolved-reference")
.arg("unresolved-reference")
.arg("--warn")
.arg("division-by-zero")
.arg("--warn")
@ -551,12 +551,12 @@ fn cli_rule_severity_precedence() -> anyhow::Result<()> {
for a in range(0, int(y)):
x = a
print(x) # possibly-unresolved-reference
prin(x) # unresolved-reference
"#,
)?;
// Assert that there's a possibly unresolved reference diagnostic
// and that division-by-zero has a severity of error by default.
// Assert that there's a `unresolved-reference` diagnostic (error)
// and a `division-by-zero` (error) by default.
assert_cmd_snapshot!(case.command(), @r"
success: false
exit_code: 1
@ -571,15 +571,15 @@ fn cli_rule_severity_precedence() -> anyhow::Result<()> {
|
info: `lint:division-by-zero` is enabled by default
warning: lint:possibly-unresolved-reference: Name `x` used when possibly not defined
--> test.py:7:7
warning: lint:unresolved-reference: Name `prin` used when not defined
--> test.py:7:1
|
5 | x = a
6 |
7 | print(x) # possibly-unresolved-reference
| ^
7 | prin(x) # unresolved-reference
| ^^^^
|
info: `lint:possibly-unresolved-reference` is enabled by default
info: `lint:unresolved-reference` is enabled by default
Found 2 diagnostics
@ -590,12 +590,12 @@ fn cli_rule_severity_precedence() -> anyhow::Result<()> {
case
.command()
.arg("--error")
.arg("possibly-unresolved-reference")
.arg("unresolved-reference")
.arg("--warn")
.arg("division-by-zero")
// Override the error severity with warning
.arg("--ignore")
.arg("possibly-unresolved-reference"),
.arg("unresolved-reference"),
@r"
success: true
exit_code: 0
@ -951,7 +951,7 @@ fn user_configuration() -> anyhow::Result<()> {
for a in range(0, int(y)):
x = a
print(x)
prin(x)
"#,
),
])?;
@ -979,15 +979,15 @@ fn user_configuration() -> anyhow::Result<()> {
|
info: `lint:division-by-zero` was selected in the configuration file
warning: lint:possibly-unresolved-reference: Name `x` used when possibly not defined
--> main.py:7:7
warning: lint:unresolved-reference: Name `prin` used when not defined
--> main.py:7:1
|
5 | x = a
6 |
7 | print(x)
| ^
7 | prin(x)
| ^^^^
|
info: `lint:possibly-unresolved-reference` is enabled by default
info: `lint:unresolved-reference` is enabled by default
Found 2 diagnostics
@ -995,7 +995,7 @@ fn user_configuration() -> anyhow::Result<()> {
"
);
// The user-level configuration promotes `possibly-unresolved-reference` to an error.
// The user-level configuration sets the severity for `unresolved-reference` to error.
// Changing the level for `division-by-zero` has no effect, because the project-level configuration
// has higher precedence.
case.write_file(
@ -1003,7 +1003,7 @@ fn user_configuration() -> anyhow::Result<()> {
r#"
[rules]
division-by-zero = "error"
possibly-unresolved-reference = "error"
unresolved-reference = "error"
"#,
)?;
@ -1023,15 +1023,15 @@ fn user_configuration() -> anyhow::Result<()> {
|
info: `lint:division-by-zero` was selected in the configuration file
error: lint:possibly-unresolved-reference: Name `x` used when possibly not defined
--> main.py:7:7
error: lint:unresolved-reference: Name `prin` used when not defined
--> main.py:7:1
|
5 | x = a
6 |
7 | print(x)
| ^
7 | prin(x)
| ^^^^
|
info: `lint:possibly-unresolved-reference` was selected in the configuration file
info: `lint:unresolved-reference` was selected in the configuration file
Found 2 diagnostics

View file

@ -59,7 +59,7 @@ info: revealed-type: Revealed type
```
```
warning: lint:possibly-unresolved-reference: Name `x` used when possibly not defined
info: lint:possibly-unresolved-reference: Name `x` used when possibly not defined
--> src/mdtest_snippet.py:16:17
|
14 | # revealed: Unknown

View file

@ -475,12 +475,26 @@ impl RuleSelection {
/// Creates a new rule selection from all known lints in the registry that are enabled
/// according to their default severity.
pub fn from_registry(registry: &LintRegistry) -> Self {
Self::from_registry_with_default(registry, None)
}
/// Creates a new rule selection from all known lints in the registry, including lints that are default by default.
/// Lints that are disabled by default use the `default_severity`.
pub fn all(registry: &LintRegistry, default_severity: Severity) -> Self {
Self::from_registry_with_default(registry, Some(default_severity))
}
fn from_registry_with_default(
registry: &LintRegistry,
default_severity: Option<Severity>,
) -> Self {
let lints = registry
.lints()
.iter()
.filter_map(|lint| {
Severity::try_from(lint.default_level())
.ok()
.or(default_severity)
.map(|severity| (*lint, (severity, LintSource::Default)))
})
.collect();

View file

@ -851,7 +851,7 @@ declare_lint! {
pub(crate) static POSSIBLY_UNRESOLVED_REFERENCE = {
summary: "detects references to possibly undefined names",
status: LintStatus::preview("1.0.0"),
default_level: Level::Warn,
default_level: Level::Ignore,
}
}

View file

@ -1,4 +1,5 @@
use camino::{Utf8Component, Utf8PathBuf};
use ruff_db::diagnostic::Severity;
use ruff_db::files::{File, Files};
use ruff_db::system::{
CaseSensitivity, DbWithWritableSystem, InMemorySystem, OsSystem, System, SystemPath,
@ -25,7 +26,7 @@ pub(crate) struct Db {
impl Db {
pub(crate) fn setup() -> Self {
let rule_selection = RuleSelection::from_registry(default_lint_registry());
let rule_selection = RuleSelection::all(default_lint_registry(), Severity::Info);
Self {
system: MdtestSystem::in_memory(),

View file

@ -653,7 +653,7 @@
"possibly-unresolved-reference": {
"title": "detects references to possibly undefined names",
"description": "## What it does\nChecks for references to names that are possibly not defined.\n\n## Why is this bad?\nUsing an undefined variable will raise a `NameError` at runtime.\n\n## Example\n\n```python\nfor i in range(0):\n x = i\n\nprint(x) # NameError: name 'x' is not defined\n```",
"default": "warn",
"default": "ignore",
"oneOf": [
{
"$ref": "#/definitions/Level"