Mutually recursive types in Python 3.6 using a named tuple syntax

I am trying to implement Nodes and Edges for a graph. Here is my code:

from typing import NamedTuple, List class Node(NamedTuple): name: str edges: List[Edge] class Edge(NamedTuple): src: Node dest: Node 

This causes an error because the Edge type is not defined when creating the Node .

 NameError: name 'Edge' is not defined 

Switching definitions around doesn't work, because Edge also applies to Node .

How can I make it work?

+5
source share
2 answers

Use string literals.

 from typing import NamedTuple, List class Node(NamedTuple): name: str edges: List['Edge'] class Edge(NamedTuple): src: Node dest: Node 

Details are in PEP-484 in the Direct Links section:

If the type hint contains names that are not yet defined, this definition can be expressed as a string literal, which will be resolved later.

+6
source

You can use string literals; they will be evaluated later:

 class Node(NamedTuple): name: str edges: List['Edge'] 

See PEP 484 Direct Link Section - Tooltip Type:

If the type hint contains names that are not yet defined, this definition can be expressed as a string literal, which will be resolved later.

For NamedTuple objects NamedTuple direct links are explicitly stored for later dereferencing:

 >>> Node._field_types {'name': <class 'str'>, 'edges': typing.List[_ForwardRef('Edge')]} 

which will check the type of validation can subsequently be dereferenced from locales and global variables:

 >>> typing._eval_type(Node._field_types['edges'], globals(), locals()) typing.List[__main__.Edge] 
+5
source

Source: https://habr.com/ru/post/1263364/


All Articles