Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python typing for a parameter can be None

I'm trying to create a tree structure with python typing annotation. The code is like this:

from typing import List

class TNode:
    def __init__(self, parent: 'TNode', data: str, children: List['TNode'] = []):
        self.parent = parent
        self.data = data
        self.children = children


root = TNode(None, 'example')

But the code has a issue of type mismatching, Pycharm will raise Expected type 'TNode', got 'None' instead. Is there a way to solve this issue, or if there is a better way to design the class constructor?

like image 676
hsc Avatar asked Oct 21 '25 14:10

hsc


1 Answers

If your parent node can be None, you need to mark the argument as Optional or explicitly use a Union[None, 'TNode'] annotation:

from typing import List, Optional

class TNode:
    def __init__(self, parent: Optional['TNode'], data: str, children: List['TNode'] = []) -> None:

Side note: you probably do not want to use [] as a default value for children. Defaults are evaluated once and stored with the function object, so if you were to use the default value and mutate it, you mutate the shared default. See "Least Astonishment" and the Mutable Default Argument.

Set children to a default None sentinel value instead:

class TNode:
    def __init__(
        self,
        parent: Optional['TNode'],
        data: str,
        children: Optional[List['TNode']] = None
    ) -> None:
        self.parent = parent
        self.data = data
        self.children = children or []

The children or [] expression will set self.children to an empty list whenever the children argument is a falsey value, including None and an empty list.

I also used a different formatting for the argument list, better suited for type-annotated arguments where the line length would exceed the recommended 80 characters line length limit.

like image 136
Martijn Pieters Avatar answered Oct 23 '25 02:10

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!