@@ -25,6 +25,21 @@ def keys(self): # type: ignore[override]
2525 raise RuntimeError ("broken keys" )
2626
2727
28+ class _HyperbrowserKeysFailureMapping (Mapping [object , object ]):
29+ def __getitem__ (self , key : object ) -> object :
30+ _ = key
31+ return "value"
32+
33+ def __iter__ (self ) -> Iterator [object ]:
34+ return iter (())
35+
36+ def __len__ (self ) -> int :
37+ return 0
38+
39+ def keys (self ): # type: ignore[override]
40+ raise HyperbrowserError ("custom keys failure" )
41+
42+
2843class _BrokenValueMapping (Mapping [object , object ]):
2944 def __getitem__ (self , key : object ) -> object :
3045 _ = key
@@ -166,6 +181,35 @@ def test_read_string_mapping_keys_rejects_non_string_keys():
166181 )
167182
168183
184+ def test_read_string_mapping_keys_rejects_string_subclass_keys ():
185+ class _StringKey (str ):
186+ pass
187+
188+ with pytest .raises (HyperbrowserError , match = "non-string key: _StringKey" ):
189+ read_string_mapping_keys (
190+ {_StringKey ("key" ): "value" },
191+ expected_mapping_error = "expected mapping" ,
192+ read_keys_error = "failed keys" ,
193+ non_string_key_error_builder = lambda key : (
194+ f"non-string key: { type (key ).__name__ } "
195+ ),
196+ )
197+
198+
199+ def test_read_string_mapping_keys_preserves_hyperbrowser_key_read_failures ():
200+ with pytest .raises (HyperbrowserError , match = "custom keys failure" ) as exc_info :
201+ read_string_mapping_keys (
202+ _HyperbrowserKeysFailureMapping (),
203+ expected_mapping_error = "expected mapping" ,
204+ read_keys_error = "failed keys" ,
205+ non_string_key_error_builder = lambda key : (
206+ f"non-string key: { type (key ).__name__ } "
207+ ),
208+ )
209+
210+ assert exc_info .value .original_error is None
211+
212+
169213def test_copy_mapping_values_by_string_keys_returns_selected_values ():
170214 copied_values = copy_mapping_values_by_string_keys (
171215 {"field" : "value" , "other" : "ignored" },
0 commit comments