1+ from typing import ClassVar , List , Sequence
2+
13import ntcore
24import pytest
35from wpimath import geometry
@@ -25,6 +27,7 @@ class Component:
2527 topic = nt .getTopic (name )
2628 assert topic .getTypeString () == type_str
2729 assert topic .genericSubscribe ().get ().value () == value
30+ assert getattr (component , name ) == value
2831
2932 for name , value in [
3033 ("rotation" , geometry .Rotation2d ()),
@@ -33,13 +36,15 @@ class Component:
3336 assert nt .getTopic (name ).getTypeString () == f"struct:{ struct_type .__name__ } "
3437 topic = nt .getStructTopic (name , struct_type )
3538 assert topic .subscribe (None ).get () == value
39+ assert getattr (component , name ) == value
3640
3741 for name , struct_type , value in [
3842 ("rotations" , geometry .Rotation2d , [geometry .Rotation2d ()]),
3943 ]:
4044 assert nt .getTopic (name ).getTypeString () == f"struct:{ struct_type .__name__ } []"
4145 topic = nt .getStructArrayTopic (name , struct_type )
4246 assert topic .subscribe ([]).get () == value
47+ assert getattr (component , name ) == value
4348
4449
4550def test_tunable_errors ():
@@ -50,7 +55,44 @@ class Component:
5055
5156
5257def test_tunable_errors_with_empty_sequence ():
53- with pytest .raises (ValueError ):
58+ with pytest .raises (( RuntimeError , ValueError ) ):
5459
5560 class Component :
5661 empty = tunable ([])
62+
63+
64+ def test_type_hinted_empty_sequences () -> None :
65+ class Component :
66+ generic_seq = tunable [Sequence [int ]](())
67+ class_var_seq : ClassVar [tunable [Sequence [int ]]] = tunable (())
68+ inst_seq : Sequence [int ] = tunable (())
69+
70+ generic_typing_list = tunable [List [int ]]([])
71+ class_var_typing_list : ClassVar [tunable [List [int ]]] = tunable ([])
72+ inst_typing_list : List [int ] = tunable ([])
73+
74+ # TODO(davo): re-enable after py3.8 is dropped
75+ # generic_list = tunable[list[int]]([])
76+ # class_var_list: ClassVar[tunable[list[int]]] = tunable([])
77+ # inst_list: list[int] = tunable([])
78+
79+ component = Component ()
80+ setup_tunables (component , "test_type_hinted_sequences" )
81+ NetworkTables = ntcore .NetworkTableInstance .getDefault ()
82+ nt = NetworkTables .getTable ("/components/test_type_hinted_sequences" )
83+
84+ for name in [
85+ "generic_seq" ,
86+ "class_var_seq" ,
87+ "inst_seq" ,
88+ "generic_typing_list" ,
89+ "class_var_typing_list" ,
90+ "inst_typing_list" ,
91+ # "generic_list",
92+ # "class_var_list",
93+ # "inst_list",
94+ ]:
95+ assert nt .getTopic (name ).getTypeString () == "int[]"
96+ entry = nt .getEntry (name )
97+ assert entry .getIntegerArray (None ) == []
98+ assert getattr (component , name ) == []
0 commit comments