I'm using python 3.8 and just updated pyright to 1.1.377 and I get now type errors for defaultdict(defaultdict)
assignments.
The code to reproduce what I mean would be:
from typing import DefaultDict
from collections import defaultdict
class MyClass:
pass
d: DefaultDict[int, DefaultDict[int, MyClass]] = defaultdict(defaultdict)
d[1][2] = MyClass()
I get pyright error:
error: Expression of type "defaultdict[Unknown, defaultdict[Unknown, defaultdict[Unknown, Unknown]]]" is incompatible with declared type "DefaultDict[int, DefaultDict[int, MyClass]]
How to do the defaultdict instantiation here to fulfill the type I've declared?
If you take a look at the docs it explains why you might assume that this should work especially if you imagine mypy
and pyright
are quite similar. pyright gives us instances they are not look at the docs below for some common issues with types in pyright
vs mypy
Ref: doc
Having said that,
The Issue you are having is solely because of how Pyright handles the type inference for defaultdict
. When you use defaultdict(defaultdict)
without specifying the type arguments, Pyright
unlike mypy cannot infer the correct types, leading to the error you're seeing.
What you can do is use good old lambda
to help with the use of lambda
: lambda
func would returns a defaultdict
with the correct type which I hope is what you want -> defaultdict[int, MyClass]
here is a snippet to guide you
from typing import DefaultDict
from collections import defaultdict
class MyClass:
pass
d: DefaultDict[int, DefaultDict[int, MyClass]] = defaultdict(lambda: defaultdict(MyClass))
d[1][2] = MyClass()
Here is a simple test to valid instantiation of defaultdict
d: DefaultDict[int, DefaultDict[int, MyClass]] = defaultdict(lambda: defaultdict(MyClass))
def func(a: DefaultDict[int, DefaultDict[int, MyClass]]):
reveal_type(a) # pyright should now reveal Runtime type is 'defaultdict'
func(d)