Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to pydantic v2 #129

Merged
merged 49 commits into from
Sep 23, 2023
Merged

Migrate to pydantic v2 #129

merged 49 commits into from
Sep 23, 2023

Conversation

nikitakuklev
Copy link
Collaborator

This PR begins work on pydantic v2 migration.

In general, documentation for v2 is still lacking, and many changes are not called out. On first pass, several issues were encountered due to changes in pydantic internals (v2 uses Rust core, has native json implementation, and thus less information is accessible/customizable). Namely:

  • Use of type_ attribute to acquire resolved inner type seems to have no direct replacement. Workaround with typing works ok for simple case of Optional[X], but requires further testing.
  • Dumping to json no longer takes **dumps_kwargs - need to rework saving
  • Loading json also needs to be handled explicitly if anything 'weird' is serialized. This should be doable with orjson methods as is.
  • Type-related object direct json deserialization currently fails due to a potential pydantic bug (filed issue at Different behavior of model_validate/model_validate_json with type fields pydantic/pydantic#6573). As explained above, we should move to parsing json ourselves in any case.

Next step is to explore breaking out field serialization logic to take advantage of per-field decorators.

@nikitakuklev nikitakuklev marked this pull request as draft July 11, 2023 01:00
@roussel-ryan
Copy link
Collaborator

Looks like a great start Nikita! Thanks so much for looking into this, keep up the good work!

@nikitakuklev
Copy link
Collaborator Author

Update: 2.1 has resolved some bugs, including above issue, but there are corner cases remaining with custom serialization. Will continue tracking main for now.

@roussel-ryan
Copy link
Collaborator

roussel-ryan commented Aug 30, 2023

Thanks @nikitakuklev on your hard work RE this issue! What are your thoughts on how close we are to transitioning Xopt to pydantic v2 (accepting this PR)?

@nikitakuklev
Copy link
Collaborator Author

We are close. I have unfortunately confirmed that some of the design changes in v2 are not bugs, so serialization is unlikely to ever work in the 'intended' way with decorators. I implemented parallel methods for those.

@nikitakuklev
Copy link
Collaborator Author

Tests now pass. I plan to test if orjson is still necessary, and then prepare for merge.

@nikitakuklev
Copy link
Collaborator Author

Note that development notebooks were kept at v1, not sure if needed anymore.

@nikitakuklev nikitakuklev marked this pull request as ready for review September 15, 2023 20:03
Copy link
Collaborator

@roussel-ryan roussel-ryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just a few questions and nits

xopt/evaluator.py Outdated Show resolved Hide resolved
tests/test_pydantic.py Show resolved Hide resolved
xopt/generators/bayesian/bayesian_generator.py Outdated Show resolved Hide resolved

DECODERS = {"torch.float32": torch.float32, "torch.float64": torch.float64}
MIN_INFERRED_NOISE_LEVEL = 1e-4


class StandardModelConstructor(ModelConstructor):
name = "standard"
name: str = Field("standard", frozen=True)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably be a class variable instead, if you could update this and the base constructor class that would be great

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

although on second thought, maybe not since the name isn't dumped during serialization. What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, classvars not getting dumped was the issue so kept them as standard fields. In case of generator, where name is classvar, we manually add that key during dump. There is another option of having a hidden discriminator field but that can't be (directly) used because they are incompatible with pre-validators.

@roussel-ryan
Copy link
Collaborator

@ChristopherMayes do we need the developer folder in docs/examples? I have a separate dev folder that is gitignored

@ChristopherMayes
Copy link
Collaborator

@ChristopherMayes do we need the developer folder in docs/examples? I have a separate dev folder that is gitignored

We should keep the logger example somewhere. The others look outdated.

@roussel-ryan
Copy link
Collaborator

Ok, also @nikitakuklev and @ChristopherMayes I will hold off on incorporating this until after 9/22 since we have some runtime for Badger on Thursday that I want to keep xopt stable for

@roussel-ryan
Copy link
Collaborator

@nikitakuklev so it looks like the examples are failing due to an update in matplotlib that I fixed in PR #147 . If you want to merge those changes into your branch then we can accept this PR

@nikitakuklev
Copy link
Collaborator Author

@roussel-ryan ready to merge

@roussel-ryan roussel-ryan merged commit bdbd79c into xopt-org:main Sep 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants