-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a deeply recursive schema/union test
This adds a test from [this pydantic issue](pydantic/pydantic#8499) to ensure that we don't error out when processing deeply recursive schemas with unions. No code change is needed at this time, we process this schema efficiently already.
- Loading branch information
Showing
1 changed file
with
51 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import textwrap | ||
|
||
import msgspec | ||
|
||
from utils import temp_module | ||
|
||
|
||
def test_process_large_recursive_union(): | ||
""" | ||
A recursive schema processing perf test from | ||
https://github.com/pydantic/pydantic/issues/8499 | ||
This test is mostly to ensure that processing deeply recursive schemas with | ||
unions succeeds. | ||
""" | ||
|
||
def gen_code(): | ||
yield "from __future__ import annotations" | ||
yield "from msgspec import Struct" | ||
yield "from typing import Union" | ||
|
||
for i in range(50): | ||
yield textwrap.dedent( | ||
f""" | ||
class Node{i}(Struct, tag='node{i}'): | ||
data: Union[Node, None] | ||
""" | ||
) | ||
yield "Node = Union[" | ||
for i in range(50): | ||
yield f" Node{i}," | ||
yield "]" | ||
|
||
code = "\n".join(gen_code()) | ||
|
||
with temp_module(code) as mod: | ||
dec = msgspec.json.Decoder(mod.Node) | ||
|
||
msg = b""" | ||
{ | ||
"type": "node25", | ||
"data": { | ||
"type": "node13", | ||
"data": null | ||
} | ||
} | ||
""" | ||
|
||
sol = mod.Node25(mod.Node13(None)) | ||
|
||
assert dec.decode(msg) == sol |