Conversation
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
|
cf54b6c to
9ad1ecf
Compare
| __setattr__ :: bound method object.__setattr__(name: str, value: Any, /) -> None | ||
| __sizeof__ :: bound method object.__sizeof__() -> int | ||
| __str__ :: bound method object.__str__() -> str | ||
| __subclasshook__ :: bound method type.__subclasshook__(subclass: type, /) -> bool |
There was a problem hiding this comment.
These were just (slightly) wrong before. FYI @BurntSushi.
9ad1ecf to
b2a1106
Compare
| // method, but `instance_of_SomeClass.__delattr__` is. | ||
| for Member { name, .. } in all_declarations_and_bindings(db, class_body_scope) { | ||
| let result = parent_instance.member(db, name.as_str()); | ||
| let result = ty.member(db, name.as_str()); |
There was a problem hiding this comment.
This is a small bugfix. Instead of trying to access the member on instances of the parent class, just access them on the type that we're adding completions for — similar to how it's done in the method above. If we don't do this, the descriptor protocol will be invoked with the wrong instance type (which is why we see the changes in bound methods).
It was also possible to change this for TypedDict, because "instances"/inhabitants of TypedDict-based classes are not represented by Type::NominalInstance, but Type::TypedDict.
b2a1106 to
45ef715
Compare
45ef715 to
b6b9352
Compare
| return SubclassOfType::from( | ||
| db, | ||
| KnownClass::Dict | ||
| .to_specialized_class_type( | ||
| db, | ||
| [KnownClass::Str.to_instance(db), Type::object(db)], | ||
| ) | ||
| .expect("dict[] takes two type parameters"), | ||
| ); | ||
| } |
There was a problem hiding this comment.
Shouldn't this be a class-literal type rather than a subclass-of type? Similar to the way we know that an int-literal must be an instance of exactly int (not a subclass of int), it's invalid for a TypedDict inhabitant to be an instance of a dict subclass -- it must be an instance of exactly dict, I think? This is different to NominalInstance types, which is why we use SubclassOf types as the meta-types for most instance types.
There was a problem hiding this comment.
Shouldn't this be a class-literal type rather than a subclass-of type?
This is what I had at first. Then I noticed that type({}) is type[dict[Unknown, Unknown]] and I tried to model that similarly.
it's invalid for a
TypedDictinhabitant to be an instance of adictsubclass -- it must be an instance of exactlydict
Yes, I think that's right. Will change back to <class 'dict[str, object]'>.
There was a problem hiding this comment.
This is what I had at first. Then I noticed that
type({})istype[dict[Unknown, Unknown]]and I tried to model that similarly.
yeah, the apparent inconsistency here is due to the fact that with x = {}, we infer the type of x as dict[Unknown, Unknown], which is "lossy" -- looking at the source code, we know that it is (for now) an instance of exactly dict, but this is not recorded in the type we infer: the type we infer allows for the possibility that x could be an instance of a subclass of dict. That lossiness in the type then means that the only safe type we can infer for type(x) here is type[dict[Unknown, Unknown]] rather than <class 'dict[Unknown, Unknown]'>
And the "lossiness" of the type we infer for x there is sort-of deliberate: you usually want to be able to substitute a subclass of dict wherever a dict is expected! But for TypedDict types, that's not allowed, so we can use a more precise type for type() calls on TypedDict inhabitants.
98b1db7 to
f5e3f3a
Compare
f5e3f3a to
eeb2d34
Compare
Summary
This PR fixes a few inaccuracies in attribute access on
TypedDicts. It also changes the return type oftype(person)totype[dict[str, object]]ifperson: Personis an inhabitant of aTypedDictPerson. We still usetype[Person]as the meta type of Person, however (see reasoning here).Test Plan
Updated Markdown tests.