(self, proto)
| 2500 | proto.decode(msg, type=Ex[str]) |
| 2501 | |
| 2502 | def test_recursive_generic_namedtuple(self, proto): |
| 2503 | pytest.importorskip("typing_extensions") |
| 2504 | |
| 2505 | source = """ |
| 2506 | from __future__ import annotations |
| 2507 | from typing import Union, Generic, TypeVar |
| 2508 | from typing_extensions import NamedTuple |
| 2509 | |
| 2510 | T = TypeVar("T") |
| 2511 | |
| 2512 | class Ex(NamedTuple, Generic[T]): |
| 2513 | a: T |
| 2514 | b: Union[Ex[T], None] |
| 2515 | """ |
| 2516 | |
| 2517 | with temp_module(source) as mod: |
| 2518 | msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) |
| 2519 | msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) |
| 2520 | assert proto.decode(proto.encode(msg), type=mod.Ex) == msg |
| 2521 | assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 |
| 2522 | assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg |
| 2523 | |
| 2524 | with pytest.raises(ValidationError) as rec: |
| 2525 | proto.decode(proto.encode(msg2), type=mod.Ex[int]) |
| 2526 | assert "`$[1][0]`" in str(rec.value) |
| 2527 | assert "Expected `int`, got `str`" in str(rec.value) |
| 2528 | |
| 2529 | def test_namedtuple_hash_preserved_after_roundtrip(self, proto): |
| 2530 | """Hash of deserialized NamedTuple matches hash of original. |
nothing calls this directly
no test coverage detected