pycrdt icon indicating copy to clipboard operation
pycrdt copied to clipboard

What is the best way to clone shared types in pycrdt?

Open armanckeser opened this issue 3 months ago • 12 comments

In the JS library there is the .clone() utility method that returns a fresh copy of the sharedtype that can be included in a new ydoc. I couldn't find an equivalent in pycrdt, any tips on cloning sharedtypes from one ydoc to another?

Thanks!

armanckeser avatar Sep 24 '25 13:09 armanckeser

I'm not sure Yrs has this functionality, @Horusiath ? Otherwise, we could implement it in Python. I guess it would have to support nested types.

davidbrochart avatar Sep 24 '25 13:09 davidbrochart

yrs doesn't have such thing. Depending on the type your could call toJson (for arrays/maps) or get formatted delta chunks (for text types).

Horusiath avatar Sep 25 '25 10:09 Horusiath

I see, good to know I wasn't missing anything. Not sure what you mean by delta chunks though, also does that apply to XML fragments? Thanks!

armanckeser avatar Sep 25 '25 11:09 armanckeser

Actually I think that AsPrelim is what you're looking for - it basically can take any yrs object and change it into equivalent input object that can be integrated into another document. Ofc. this means that it's stripped off the metadata required for conflict resolution, so it's only for things like copying.

Horusiath avatar Sep 26 '25 06:09 Horusiath

That's exactly our use case! What would it take to implement the bindings for this on the Python side?

armanckeser avatar Sep 26 '25 12:09 armanckeser

Probably not much, do you want to try and open a PR?

davidbrochart avatar Sep 26 '25 12:09 davidbrochart

@davidbrochart before I open the PR, as far as I can tell, the Python implementation does not expose Prelim types and types them as Any and hides them in the sharedtype's class. In the implementation, should I return something like Array::from_prelim(prelim) from the as_prelim binding as opposed to returning the prelim itself as Any?

armanckeser avatar Sep 26 '25 13:09 armanckeser

Hmm right... Actually, isn't the .to_py() method what you are looking for?

davidbrochart avatar Sep 26 '25 13:09 davidbrochart

We can't use .to_py() on Xml types, which is our main sharedtype

armanckeser avatar Sep 26 '25 13:09 armanckeser

Any thoughts?

armanckeser avatar Sep 28 '25 18:09 armanckeser

Maybe we should implement .to_py() on Xml types?

davidbrochart avatar Sep 28 '25 18:09 davidbrochart

Maybe, but Xml representations in Python are in a weird spot. The built-in element tree is slow and doesn't have many features, the de-facto standard is lxml library, but both xml and lxml will get flagged by Bandit for being insecure. Even though it shouldn't be a huge problem for this use case, since we are not parsing strings but converting nodes, the code might require some #nosemgreps if this CI is using Bandit. Apart from that, we would also need to change the __init__ for XmlFragment's to accept and transform our pythonic representation back into pycrdt.

Maybe we can return the Prelim type from to_py of XmlFragments? No added dependencies?

armanckeser avatar Sep 30 '25 12:09 armanckeser