pydantic-xml icon indicating copy to clipboard operation
pydantic-xml copied to clipboard

tag-indexed unions

Open nilsbtr opened this issue 5 months ago • 1 comments

Does pydantic-xml currently have tag-indexed unions? I'm trying to deserialize a svg file (~3mb) and because I have big Unions of possible children (all with different/unique tags) it gets very slow as it trys to create a snapshot of every possible child.

   Ordered by: cumulative time
   List reduced from 180 to 20 due to restriction <20>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.042    0.042  249.157  249.157 ...\.venv\Lib\site-packages\pydantic_xml\model.py:524(from_xml)
        1    0.000    0.000  249.114  249.114 ...\.venv\Lib\site-packages\pydantic_xml\model.py:497(from_xml_tree)
   7719/1    0.503    0.000  248.432  248.432 ...\.venv\Lib\site-packages\pydantic_xml\serializers\factories\model.py:188(deserialize)
   7648/1    0.084    0.000  248.404  248.404 ...\.venv\Lib\site-packages\pydantic_xml\serializers\factories\homogeneous.py:66(deserialize)
 15366/13    6.960    0.000  248.378   19.106 ...\.venv\Lib\site-packages\pydantic_xml\serializers\factories\union.py:110(deserialize)
21033320/146051  104.363    0.000  238.601    0.002 ...\.venv\Lib\site-packages\pydantic_xml\element\element.py:336(create_snapshot)
21033320/146051   19.451    0.000  237.807    0.002 ...\.venv\Lib\site-packages\pydantic_xml\element\element.py:342(<listcomp>)
146051/257    0.317    0.000  218.367    0.850 ...\.venv\Lib\site-packages\pydantic_xml\serializers\factories\model.py:418(deserialize)
 21041039  107.107    0.000  115.339    0.000 ...\.venv\Lib\site-packages\pydantic_xml\element\element.py:303(__init__)
 21041039    8.231    0.000    8.231    0.000 ...\.venv\Lib\site-packages\pydantic_xml\element\element.py:269(__init__)
   7719/1    0.073    0.000    0.682    0.682 ...\.venv\Lib\site-packages\pydantic_xml\element\native\lxml.py:19(from_native)
   7719/1    0.013    0.000    0.682    0.682 ...\.venv\Lib\site-packages\pydantic_xml\element\native\lxml.py:29(<listcomp>)
     7718    0.587    0.000    0.587    0.000 ...\.venv\Lib\site-packages\pydantic_xml\element\element.py:350(apply_snapshot)
   146051    0.180    0.000    0.492    0.000 ...\.venv\Lib\site-packages\pydantic_xml\element\element.py:411(pop_element)
     7718    0.015    0.000    0.431    0.000 ...\.venv\Lib\site-packages\pydantic\main.py:669(model_validate)
     7718    0.237    0.000    0.416    0.000 {method 'validate_python' of 'pydantic_core._pydantic_core.SchemaValidator' objects}
   241849    0.148    0.000    0.305    0.000 ...\.venv\Lib\site-packages\pydantic_xml\serializers\factories\primitive.py:127(deserialize)
   146051    0.172    0.000    0.228    0.000 ...\.venv\Lib\site-packages\pydantic_xml\element\element.py:519(strict_search)
   249567    0.133    0.000    0.172    0.000 ...\.venv\Lib\site-packages\pydantic_xml\element\element.py:397(pop_attrib)
    60504    0.070    0.000    0.142    0.000 ...\.venv\Lib\site-packages\pydantic\_internal\_model_construction.py:277(__instancecheck__)

Example element:

class SVG(Element, Color, Graphics, tag="svg"):
    model_config = ConfigDict(extra="forbid")

    elements: list[RootChildren] = element()

    x: str | None = attr(default=0)
    y: str | None = attr(default=0)
    width: str | None = attr(default=None)
    height: str | None = attr(default=None)

    clip_path: str | None = attr(name="clip-path", default=None)
    mask: str | None = attr(default=None)
    opacity: str | None = attr(default=None)
    overflow: str | None = attr(default=None)
    preserve_aspect_ratio: str | None = attr(name="preserveAspectRatio", default=None)
    version: str | None = attr(default=None)
    view_box: str | None = attr(name="viewBox", default=None)

RootChildren: TypeAlias = (
    ShapeElements
    | GradientElements
    | A
    | Animate
    | AnimateMotion
    | AnimateTransform
    | ClipPath
    | Defs
    | Desc
    | Filter
    | ForeignObject
    | G
    | Image
    | Marker
    | Mask
    | Metadata
    | Pattern
    | Set
    | Style
    | SVG
    | Switch
    | Symbol
    | Text
    | Title
    | Use
    | View
)

nilsbtr avatar Aug 22 '25 07:08 nilsbtr

@nilsbtr Hi,

right now only attribute-based discriminated unions are supported.

dapper91 avatar Sep 13 '25 19:09 dapper91