Pydantic v1 type support
Hi UPath maintainers 🫡
Just came across this package this morning after having the same need for a pathlib-style API backed by fsspec - nice to see its already an OS package 🥇
I was wondering how keen you would be to enabling (or accepting a PR for) pydantic v1 type compatibility? I believe it would be as simple as adding in:
class UPath(...):
...
@classmethod
def __get_validators__(cls) -> Iterator[Callable]:
yield cls._validate
@classmethod
def _validate(cls, v: Any) -> UPath:
return cls(v)
or perhaps with a try/except catch around cls(v) to ensure a ValidationError is thrown if an exception is thrown during cls(v).
I noticed you recently added pydantic v2 support, so was wondering whether this small adjustment would enable the UPath to be used in both pydantic v1 and v2 models.
I note that whilst supporting v1 is potentially not a long term solution, I imagine there are still a number of use cases that could benefit from v1 support and I don't believe it will interfere with any v2 support since they use different validation mechanisms.
What are your thoughts on this? Would you be receptive to a v1 validation PR? 🙏 Thanks in advance!
Hi @rx-dwoodward,
Thanks for offering to contribute ❤️
Would you be receptive to a v1 validation PR?
Yes. The PR would ideally have to implement:
- pydantic v1 support on the UPath class allowing serialization of .path, .protocol and .storage_options
- go through equivalent or same serialization tests as the pydantic v2 serialization tests
- add pydantic v1 tests as an additional step to the build matrix in the ci or via parameterization to the tests. (I guess parameterization might work, since v2 ships v1 as far as I am aware.)
Hi @ap-- ,
for the first point
pydantic v1 support on the UPath class allowing serialization of .path, .protocol and .storage_options
How would you like this to be implemented? Since pydantic v1 models do not have a hook for custom serialization on custom classes (annoyingly) it has to be up to the BaseModel to determine how to JSON encode custom classes.
I could write a to_dict() method explicitly that can be used like so:
from pydantic.v1 import BaseModel
class Model(BaseModel):
path: UPath
class Config:
json_encoders = {UPath: lambda u: u.to_dict}
model = Model(path="...")
model.json() # == '{"path": {"path": ..., "protocol": ..., "storage_options": ...}}'
annoyingly I don't think there is any other way to ensure that custom classes are handled correctly by a v1 model out the box.
Would this be acceptable?