Instantiate empty type-hinted list

Question:

I have the following code:

from typing import List, NewType

MultiList = NewType("MultiList", List[List[int]])

def myfunc():
  multi: MultiList = []
  # More stuff here

The code works fine, it’s just my IDE (PyCharm) doesn’t like the instantiation of multi to an empty list, I get this error:

"Expected type 'MultiList', got 'list[list[int]]' instead"

I mean, a MultiList is a list[list[int]], so I really don’t know why it’s complaining. Unless it’s because the list is empty, but that doesn’t make a lot of sense to me either.

It’s not the end of the world, the code works just fine, I’d just like to know why it’s marked as wrong.

Asked By: Ben Taylor

||

Answers:

If you just mean "list of lists of ints", then don’t use NewType:

MultiList = List[List[int]]

NewType is for if you don’t want arbitrary lists of lists of ints to be treated as a MultiList. With NewType, static type checkers will only treat an object as a MultiList if you explicitly call MultiList:

MultiList = NewType("MultiList", List[List[int]])
multi: MultiList = MultiList([])
Answered By: user2357112

The entire purpose of the typing.NewType is to distinguish a type from another and treat it as a subtype. You annotate it as MultiList, which is treated as a subtype of list, so assigning a list instance is wrong.

You need to instantiate MultiList properly. Example:

def myfunc():
    multi: MultiList = MultiList([])

If you wanted a type alias instead, then you should not use NewType, but TypeAlias instead:

from typing import TypeAlias

MultiList: TypeAlias = list[list[int]]

def myfunc():
    multi: MultiList = []

PS: Unless you are using an outdated Python version, you should use the standard generic alias types, i.e. list instead of typing.List.

Answered By: Daniil Fajnberg