Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions _typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ extend-exclude = [
# words naturally. It's annoying to have to make all
# of them actually words. So just ignore typos here.
"crates/ty_ide/src/completion.rs",
# Same for "Did you mean...?" levenshtein tests.
"crates/ty_python_semantic/src/types/diagnostic/levenshtein.rs",
]

[default.extend-words]
Expand Down
112 changes: 56 additions & 56 deletions crates/ty/docs/rules.md

Large diffs are not rendered by default.

51 changes: 0 additions & 51 deletions crates/ty_python_semantic/resources/mdtest/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2167,57 +2167,6 @@ reveal_type(Foo.BAR.value) # revealed: @Todo(Attribute access on enum classes)
reveal_type(Foo.__members__) # revealed: @Todo(Attribute access on enum classes)
```

## Suggestions for obvious typos

<!-- snapshot-diagnostics -->

For obvious typos, we add a "Did you mean...?" suggestion to the diagnostic.

```py
import collections

print(collections.dequee) # error: [unresolved-attribute]
```

But the suggestion is suppressed if the only close matches start with a leading underscore:

```py
class Foo:
_bar = 42

print(Foo.bar) # error: [unresolved-attribute]
```

The suggestion is not suppressed if the typo itself starts with a leading underscore, however:

```py
print(Foo._barr) # error: [unresolved-attribute]
```

And in method contexts, the suggestion is never suppressed if accessing an attribute on an instance
of the method's enclosing class:

```py
class Bar:
_attribute = 42

def f(self, x: "Bar"):
# TODO: we should emit `[unresolved-attribute]` here, should have the same behaviour as `x.attribute` below
print(self.attribute)

# We give a suggestion here, even though the only good candidates start with underscores and the typo does not,
# because we're in a method context and `x` is an instance of the enclosing class.
print(x.attribute) # error: [unresolved-attribute]

class Baz:
def f(self, x: Bar):
# No suggestion is given here, because:
# - the good suggestions all start with underscores
# - the typo does not start with an underscore
# - We *are* in a method context, but `x` is not an instance of the enclosing class
print(x.attribute) # error: [unresolved-attribute]
```

## References

Some of the tests in the *Class and instance variables* section draw inspiration from
Expand Down
36 changes: 0 additions & 36 deletions crates/ty_python_semantic/resources/mdtest/import/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,39 +205,3 @@ python-version = "3.13"
import aifc # error: [unresolved-import]
from distutils import sysconfig # error: [unresolved-import]
```

## `from` import that has a typo

We offer a "Did you mean?" subdiagnostic suggestion if there's a name in the module that's
reasonably similar to the unresolved member.

<!-- snapshot-diagnostics -->

`foo.py`:

```py
from collections import dequee # error: [unresolved-import]
```

However, we suppress the suggestion if the only close matches in the module start with a leading
underscore:

`bar.py`:

```py
from baz import foo # error: [unresolved-import]
```

`baz.py`:

```py
_foo = 42
```

The suggestion is never suppressed if the typo itself starts with a leading underscore, however:

`eggs.py`:

```py
from baz import _fooo # error: [unresolved-import]
```

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion crates/ty_python_semantic/src/semantic_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::module_resolver::{Module, resolve_module};
use crate::semantic_index::ast_ids::HasScopedExpressionId;
use crate::semantic_index::place::FileScopeId;
use crate::semantic_index::semantic_index;
use crate::types::all_members::all_declarations_and_bindings;
use crate::types::ide_support::all_declarations_and_bindings;
use crate::types::{Type, binding_type, infer_scope_types};

pub struct SemanticModel<'db> {
Expand Down
4 changes: 2 additions & 2 deletions crates/ty_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ use crate::semantic_index::definition::Definition;
use crate::semantic_index::place::{ScopeId, ScopedPlaceId};
use crate::semantic_index::{imported_modules, place_table, semantic_index};
use crate::suppression::check_suppressions;
pub use crate::types::all_members::all_members;
use crate::types::call::{Binding, Bindings, CallArgumentTypes, CallableBinding};
pub(crate) use crate::types::class_base::ClassBase;
use crate::types::context::{LintDiagnosticGuard, LintDiagnosticGuardBuilder};
Expand All @@ -47,6 +46,7 @@ use crate::types::function::{
DataclassTransformerParams, FunctionSpans, FunctionType, KnownFunction,
};
use crate::types::generics::{GenericContext, PartialSpecialization, Specialization};
pub use crate::types::ide_support::all_members;
use crate::types::infer::infer_unpack_types;
use crate::types::mro::{Mro, MroError, MroIterator};
pub(crate) use crate::types::narrow::infer_narrowing_constraint;
Expand All @@ -58,7 +58,6 @@ use instance::Protocol;
pub use instance::{NominalInstanceType, ProtocolInstanceType};
pub use special_form::SpecialFormType;

pub(crate) mod all_members;
mod builder;
mod call;
mod class;
Expand All @@ -68,6 +67,7 @@ mod diagnostic;
mod display;
mod function;
mod generics;
pub(crate) mod ide_support;
mod infer;
mod instance;
mod mro;
Expand Down
4 changes: 2 additions & 2 deletions crates/ty_python_semantic/src/types/call/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::types::signatures::{Parameter, ParameterForm};
use crate::types::{
BoundMethodType, ClassLiteral, DataclassParams, KnownClass, KnownInstanceType,
MethodWrapperKind, PropertyInstanceType, SpecialFormType, TupleType, TypeMapping, UnionType,
WrapperDescriptorKind, all_members, todo_type,
WrapperDescriptorKind, ide_support, todo_type,
};
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, SubDiagnostic};
use ruff_python_ast as ast;
Expand Down Expand Up @@ -669,7 +669,7 @@ impl<'db> Bindings<'db> {
if let [Some(ty)] = overload.parameter_types() {
overload.set_return_type(TupleType::from_elements(
db,
all_members::all_members(db, *ty)
ide_support::all_members(db, *ty)
.into_iter()
.sorted()
.map(|member| Type::string_literal(db, &member)),
Expand Down
4 changes: 0 additions & 4 deletions crates/ty_python_semantic/src/types/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,6 @@ pub enum ClassType<'db> {

#[salsa::tracked]
impl<'db> ClassType<'db> {
pub(super) fn is_protocol(self, db: &'db dyn Db) -> bool {
self.class_literal(db).0.is_protocol(db)
}

pub(super) fn normalized(self, db: &'db dyn Db) -> Self {
match self {
Self::NonGeneric(_) => self,
Expand Down
9 changes: 2 additions & 7 deletions crates/ty_python_semantic/src/types/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@ use crate::types::string_annotation::{
use crate::types::{SpecialFormType, Type, protocol_class::ProtocolClassLiteral};
use crate::{Db, Module, ModuleName, Program, declare_lint};
use itertools::Itertools;
pub(crate) use levenshtein::{
HideUnderscoredSuggestions, find_best_suggestion_for_unresolved_member,
};
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, SubDiagnostic};
use ruff_python_ast::{self as ast, AnyNodeRef};
use ruff_text_size::{Ranged, TextRange};
use rustc_hash::FxHashSet;
use std::fmt::Formatter;

mod levenshtein;

/// Registers all known type check lints.
pub(crate) fn register_lints(registry: &mut LintRegistryBuilder) {
registry.register_lint(&CALL_NON_CALLABLE);
Expand Down Expand Up @@ -2217,7 +2212,7 @@ fn report_invalid_base<'ctx, 'db>(
/// misconfigured their Python version.
pub(super) fn hint_if_stdlib_submodule_exists_on_other_versions(
db: &dyn Db,
diagnostic: &mut LintDiagnosticGuard,
mut diagnostic: LintDiagnosticGuard,
full_submodule_name: &ModuleName,
parent_module: &Module,
) {
Expand Down Expand Up @@ -2252,5 +2247,5 @@ pub(super) fn hint_if_stdlib_submodule_exists_on_other_versions(
version_range = version_range.diagnostic_display(),
));

add_inferred_python_version_hint_to_diagnostic(db, diagnostic, "resolving modules");
add_inferred_python_version_hint_to_diagnostic(db, &mut diagnostic, "resolving modules");
}
Loading
Loading