mirror of https://github.com/astral-sh/ruff
Update mdtests
This commit is contained in:
parent
178f48fc0b
commit
0b19caedec
|
|
@ -253,4 +253,23 @@ reveal_type(D().instance_method)
|
||||||
reveal_type(D.class_method)
|
reveal_type(D.class_method)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
```py
|
||||||
|
from ty_extensions import generic_context
|
||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
U = TypeVar("U")
|
||||||
|
|
||||||
|
class C(Generic[T]):
|
||||||
|
def method(self, u: int) -> int:
|
||||||
|
return u
|
||||||
|
|
||||||
|
def generic_method(self, t: T, u: U) -> U:
|
||||||
|
return u
|
||||||
|
|
||||||
|
reveal_type(generic_context(C.method)) # revealed: tuple[Self@method]
|
||||||
|
```
|
||||||
|
|
||||||
[self attribute]: https://typing.python.org/en/latest/spec/generics.html#use-in-attribute-annotations
|
[self attribute]: https://typing.python.org/en/latest/spec/generics.html#use-in-attribute-annotations
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,7 @@ reveal_type(bound_method(1)) # revealed: str
|
||||||
When we call the function object itself, we need to pass the `instance` explicitly:
|
When we call the function object itself, we need to pass the `instance` explicitly:
|
||||||
|
|
||||||
```py
|
```py
|
||||||
# error: [invalid-argument-type]
|
C.f(1) # error: [missing-argument]
|
||||||
# error: [missing-argument]
|
|
||||||
C.f(1)
|
|
||||||
|
|
||||||
reveal_type(C.f(C(), 1)) # revealed: str
|
reveal_type(C.f(C(), 1)) # revealed: str
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -562,17 +562,17 @@ class C(Generic[T]):
|
||||||
return u
|
return u
|
||||||
|
|
||||||
reveal_type(generic_context(C)) # revealed: tuple[T@C]
|
reveal_type(generic_context(C)) # revealed: tuple[T@C]
|
||||||
reveal_type(generic_context(C.method)) # revealed: None
|
reveal_type(generic_context(C.method)) # revealed: tuple[Self@method]
|
||||||
reveal_type(generic_context(C.generic_method)) # revealed: tuple[U@generic_method]
|
reveal_type(generic_context(C.generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||||
reveal_type(generic_context(C[int])) # revealed: None
|
reveal_type(generic_context(C[int])) # revealed: None
|
||||||
reveal_type(generic_context(C[int].method)) # revealed: None
|
reveal_type(generic_context(C[int].method)) # revealed: tuple[Self@method]
|
||||||
reveal_type(generic_context(C[int].generic_method)) # revealed: tuple[U@generic_method]
|
reveal_type(generic_context(C[int].generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||||
|
|
||||||
c: C[int] = C[int]()
|
c: C[int] = C[int]()
|
||||||
reveal_type(c.generic_method(1, "string")) # revealed: Literal["string"]
|
reveal_type(c.generic_method(1, "string")) # revealed: Literal["string"]
|
||||||
reveal_type(generic_context(c)) # revealed: None
|
reveal_type(generic_context(c)) # revealed: None
|
||||||
reveal_type(generic_context(c.method)) # revealed: None
|
reveal_type(generic_context(c.method)) # revealed: tuple[Self@method]
|
||||||
reveal_type(generic_context(c.generic_method)) # revealed: tuple[U@generic_method]
|
reveal_type(generic_context(c.generic_method)) # revealed: tuple[Self@generic_method, U@generic_method]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Specializations propagate
|
## Specializations propagate
|
||||||
|
|
|
||||||
|
|
@ -395,6 +395,7 @@ class C[T]:
|
||||||
|
|
||||||
def __init__[S](self, x: T, y: S) -> None: ...
|
def __init__[S](self, x: T, y: S) -> None: ...
|
||||||
|
|
||||||
|
# TODO: need to handle self in __init__ call.
|
||||||
reveal_type(C(1, 1)) # revealed: C[int]
|
reveal_type(C(1, 1)) # revealed: C[int]
|
||||||
reveal_type(C(1, "string")) # revealed: C[int]
|
reveal_type(C(1, "string")) # revealed: C[int]
|
||||||
reveal_type(C(1, True)) # revealed: C[int]
|
reveal_type(C(1, True)) # revealed: C[int]
|
||||||
|
|
@ -511,16 +512,16 @@ class C[T]:
|
||||||
def cannot_shadow_class_typevar[T](self, t: T): ...
|
def cannot_shadow_class_typevar[T](self, t: T): ...
|
||||||
|
|
||||||
reveal_type(generic_context(C)) # revealed: tuple[T@C]
|
reveal_type(generic_context(C)) # revealed: tuple[T@C]
|
||||||
reveal_type(generic_context(C.method)) # revealed: None
|
reveal_type(generic_context(C.method)) # revealed: tuple[Self@method]
|
||||||
reveal_type(generic_context(C.generic_method)) # revealed: tuple[U@generic_method]
|
reveal_type(generic_context(C.generic_method)) # revealed: tuple[U@generic_method]
|
||||||
reveal_type(generic_context(C[int])) # revealed: None
|
reveal_type(generic_context(C[int])) # revealed: None
|
||||||
reveal_type(generic_context(C[int].method)) # revealed: None
|
reveal_type(generic_context(C[int].method)) # revealed: tuple[Self@method]
|
||||||
reveal_type(generic_context(C[int].generic_method)) # revealed: tuple[U@generic_method]
|
reveal_type(generic_context(C[int].generic_method)) # revealed: tuple[U@generic_method]
|
||||||
|
|
||||||
c: C[int] = C[int]()
|
c: C[int] = C[int]()
|
||||||
reveal_type(c.generic_method(1, "string")) # revealed: Literal["string"]
|
reveal_type(c.generic_method(1, "string")) # revealed: Literal["string"]
|
||||||
reveal_type(generic_context(c)) # revealed: None
|
reveal_type(generic_context(c)) # revealed: None
|
||||||
reveal_type(generic_context(c.method)) # revealed: None
|
reveal_type(generic_context(c.method)) # revealed: tuple[Self@method]
|
||||||
reveal_type(generic_context(c.generic_method)) # revealed: tuple[U@generic_method]
|
reveal_type(generic_context(c.generic_method)) # revealed: tuple[U@generic_method]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ from ty_extensions import generic_context
|
||||||
legacy.m("string", None) # error: [invalid-argument-type]
|
legacy.m("string", None) # error: [invalid-argument-type]
|
||||||
reveal_type(legacy.m) # revealed: bound method Legacy[int].m[S](x: int, y: S@m) -> S@m
|
reveal_type(legacy.m) # revealed: bound method Legacy[int].m[S](x: int, y: S@m) -> S@m
|
||||||
reveal_type(generic_context(Legacy)) # revealed: tuple[T@Legacy]
|
reveal_type(generic_context(Legacy)) # revealed: tuple[T@Legacy]
|
||||||
reveal_type(generic_context(legacy.m)) # revealed: tuple[S@m]
|
reveal_type(generic_context(legacy.m)) # revealed: tuple[Self@m, S@m]
|
||||||
```
|
```
|
||||||
|
|
||||||
With PEP 695 syntax, it is clearer that the method uses a separate typevar:
|
With PEP 695 syntax, it is clearer that the method uses a separate typevar:
|
||||||
|
|
@ -165,6 +165,10 @@ class C[T]:
|
||||||
return y
|
return y
|
||||||
|
|
||||||
c: C[int] = C()
|
c: C[int] = C()
|
||||||
|
reveal_type(c) # revealed: C[Unknown]
|
||||||
|
# reveal_type(c) # revealed: C[Unknown]
|
||||||
|
# TODO: Next line fails. The reason is the reveal type above
|
||||||
|
# error: 13 [invalid-argument-type] "Argument to bound method `m` is incorrect: Expected `Self@m`, found `C[Unknown]`"
|
||||||
reveal_type(c.m(1, "string")) # revealed: Literal["string"]
|
reveal_type(c.m(1, "string")) # revealed: Literal["string"]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,42 +13,41 @@
|
||||||
use std::{collections::HashMap, slice::Iter};
|
use std::{collections::HashMap, slice::Iter};
|
||||||
|
|
||||||
use itertools::EitherOrBoth;
|
use itertools::EitherOrBoth;
|
||||||
use ruff_db::parsed::parsed_module;
|
|
||||||
use smallvec::{SmallVec, smallvec_inline};
|
use smallvec::{SmallVec, smallvec_inline};
|
||||||
|
|
||||||
use super::TypeVarVariance;
|
|
||||||
use super::{
|
use super::{
|
||||||
DynamicType, Type, definition_expression_type, infer_definition_types, semantic_index,
|
DynamicType, Type, TypeVarVariance, definition_expression_type, infer_definition_types,
|
||||||
|
semantic_index,
|
||||||
};
|
};
|
||||||
use crate::semantic_index::definition::Definition;
|
use crate::semantic_index::definition::{Definition, DefinitionKind};
|
||||||
use crate::types::constraints::{ConstraintSet, Constraints, IteratorConstraintsExtension};
|
use crate::types::constraints::{ConstraintSet, Constraints, IteratorConstraintsExtension};
|
||||||
use crate::types::function::FunctionType;
|
use crate::types::function::FunctionType;
|
||||||
use crate::types::generics::GenericContext;
|
use crate::types::generics::{GenericContext, walk_generic_context};
|
||||||
use crate::types::generics::walk_generic_context;
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
ApplyTypeMappingVisitor, BindingContext, BoundTypeVarInstance, FindLegacyTypeVarsVisitor,
|
ApplyTypeMappingVisitor, BindingContext, BoundTypeVarInstance, FindLegacyTypeVarsVisitor,
|
||||||
HasRelationToVisitor, IsEquivalentVisitor, KnownClass, MaterializationKind, NormalizedVisitor,
|
HasRelationToVisitor, IsEquivalentVisitor, KnownClass, MaterializationKind, NormalizedVisitor,
|
||||||
SpecialFormType, TypeMapping, TypeRelation, VarianceInferable, todo_type,
|
SpecialFormType, TypeMapping, TypeRelation, VarianceInferable, todo_type,
|
||||||
};
|
};
|
||||||
use crate::{Db, FxOrderSet};
|
use crate::{Db, FxOrderSet};
|
||||||
|
use ruff_db::parsed::parsed_module;
|
||||||
use ruff_python_ast::{self as ast, name::Name};
|
use ruff_python_ast::{self as ast, name::Name};
|
||||||
|
|
||||||
fn infer_method_type<'db>(
|
fn infer_method_type<'db>(
|
||||||
db: &'db dyn Db,
|
db: &'db dyn Db,
|
||||||
definition: Definition<'db>,
|
definition: Definition<'db>,
|
||||||
) -> Option<FunctionType<'db>> {
|
) -> Option<FunctionType<'db>> {
|
||||||
let scope_id = definition.scope(db);
|
let class_scope_id = definition.scope(db);
|
||||||
let file = scope_id.file(db);
|
let file = class_scope_id.file(db);
|
||||||
let index = semantic_index(db, file);
|
let index = semantic_index(db, file);
|
||||||
let module = parsed_module(db, file).load(db);
|
let module = parsed_module(db, file).load(db);
|
||||||
|
|
||||||
let method_scope = index.scope(scope_id.file_scope_id(db));
|
let DefinitionKind::Function(func_def) = definition.kind(db) else {
|
||||||
let method = method_scope.node().as_function(&module)?;
|
return None;
|
||||||
let parent_scope_id = method_scope.parent()?;
|
};
|
||||||
let parent_scope = index.scope(parent_scope_id);
|
let class_scope = index.scope(class_scope_id.file_scope_id(db));
|
||||||
parent_scope.node().as_class(&module)?;
|
class_scope.node().as_class(&module)?;
|
||||||
|
|
||||||
let method_definition = index.expect_single_definition(method);
|
let method_definition = index.expect_single_definition(func_def.node(&module));
|
||||||
let func_type = infer_definition_types(db, method_definition)
|
let func_type = infer_definition_types(db, method_definition)
|
||||||
.declaration_type(method_definition)
|
.declaration_type(method_definition)
|
||||||
.inner_type()
|
.inner_type()
|
||||||
|
|
@ -384,6 +383,7 @@ impl<'db> Signature<'db> {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let parameters =
|
let parameters =
|
||||||
Parameters::from_parameters(db, definition, function_node.parameters.as_ref());
|
Parameters::from_parameters(db, definition, function_node.parameters.as_ref());
|
||||||
|
|
||||||
let return_ty = function_node.returns.as_ref().map(|returns| {
|
let return_ty = function_node.returns.as_ref().map(|returns| {
|
||||||
let plain_return_ty = definition_expression_type(db, definition, returns.as_ref())
|
let plain_return_ty = definition_expression_type(db, definition, returns.as_ref())
|
||||||
.apply_type_mapping(
|
.apply_type_mapping(
|
||||||
|
|
@ -1194,17 +1194,30 @@ impl<'db> Parameters<'db> {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let method_type = infer_method_type(db, definition);
|
let method_type = infer_method_type(db, definition);
|
||||||
|
let is_method = method_type.is_some();
|
||||||
let is_classmethod = method_type.is_some_and(|f| f.is_classmethod(db));
|
let is_classmethod = method_type.is_some_and(|f| f.is_classmethod(db));
|
||||||
let is_staticmethod = method_type.is_some_and(|f| f.is_staticmethod(db));
|
let is_staticmethod = method_type.is_some_and(|f| f.is_staticmethod(db));
|
||||||
|
|
||||||
let positional_or_keyword = args.iter().map(|arg| {
|
let positional_or_keyword = args.iter().map(|arg| {
|
||||||
// TODO(https://github.com/astral-sh/ty/issues/159): Also set the type for `cls` argument
|
// TODO(https://github.com/astral-sh/ty/issues/159): Also set the type for `cls` argument
|
||||||
if !is_staticmethod
|
// eprintln!(
|
||||||
|
// "arg {}: pos: {:?}, is_static: {}, is_class: {}, anno: {:?}",
|
||||||
|
// arg.name().id.as_str(),
|
||||||
|
// parameters.index(arg.name().id()),
|
||||||
|
// is_staticmethod,
|
||||||
|
// is_classmethod,
|
||||||
|
// arg.parameter.annotation()
|
||||||
|
// );
|
||||||
|
// dbg!(is_method);
|
||||||
|
if is_method
|
||||||
|
&& !is_staticmethod
|
||||||
&& !is_classmethod
|
&& !is_classmethod
|
||||||
&& arg.parameter.annotation().is_none()
|
&& arg.parameter.annotation().is_none()
|
||||||
&& parameters.index(arg.name().id()) == Some(0)
|
&& parameters.index(arg.name().id()) == Some(0)
|
||||||
{
|
{
|
||||||
|
eprintln!("arg {} is self", arg.name().id.as_str());
|
||||||
let implicit_annotation = Type::SpecialForm(SpecialFormType::TypingSelf)
|
let implicit_annotation = Type::SpecialForm(SpecialFormType::TypingSelf)
|
||||||
.in_type_expression(db, definition.scope(db), Some(definition))
|
.in_type_expression(db, definition.scope(db), Some(definition))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
@ -1218,6 +1231,7 @@ impl<'db> Parameters<'db> {
|
||||||
form: ParameterForm::Value,
|
form: ParameterForm::Value,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
eprintln!("arg {} is not self", arg.name().id.as_str());
|
||||||
Parameter::from_node_and_kind(
|
Parameter::from_node_and_kind(
|
||||||
db,
|
db,
|
||||||
definition,
|
definition,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue