How?

[T]he “separation of concerns”, which, even if not perfectly possible, is yet the only available technique for effective ordering of one’s thoughts… is being one- and multiple-track minded simultaneously. — Edsger Dijkstra1

Like a homicidal psycho jungle cat, xattree claws itself into your attrs object model at import time. There it remains like toxoplasmosis until runtime, at which point it consumes the soul (__dict__) of unsuspecting instances and substitutes itself (an xarray.DataTree).

        sequenceDiagram
    Note over caller: initialize
    caller->>host: __init__()
    Note over host,__dict__: attrs-generated initialization
    host->>__dict__: [populates]
    create participant DataTree
    Note over host,DataTree: xarray data tree initialization
    host->>DataTree: [creates]
    __dict__->>DataTree: [transfers everything to]
    opt 
    host-->>parent: [bind parent]
    DataTree<<-->>parent: [bind data trees,<br/>align dimensions]
    end
    DataTree->>host: [return]
    Note over host,DataTree: (__dict__ now mostly empty,<br/>node's dimensions aligned)
    host->>caller: [return]
    
    Note over caller: get variable
    caller->>host: .x
    Note over host,DataTree: override __getattr__
    alt is array
    host->>DataTree: .data["x"]
    else is dimension
    host->>DataTree: .data.dims["x"]
    else is scalar
    host->>DataTree: .data.attrs["x"]
    end
    DataTree->>host: [return value]
    host->>caller: [return value]
    
    Note over caller: set variable
    caller->>host: .x = ...
    Note over host,DataTree: override __setattr__
    alt is array
    host->>DataTree: .data["x"] = ...
    DataTree->>DataTree: [check dimensions]
    else is scalar
    host->>DataTree: .data.attrs["x"] = ...
    end
    DataTree->>host: [return]
    host->>caller: [return]