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

Add support for pydantic v2 #795

Merged
merged 11 commits into from
Dec 8, 2023
Merged

Conversation

JacobHayes
Copy link
Contributor

@JacobHayes JacobHayes commented Oct 1, 2023

Pull Request Checklist

Description of PR
WIP, but wanted to get the bulk of it up for any feedback while I:

  • add a test run in CI with pydantic v1 installed (to ensure existing users are covered - they passed manually)
  • add a couple more tests and try to support serializing v1 and v2 user-defined models (not just the v1 models from either version - I think this should be possible).
  • update the model generation to update the Field import

This PR updates hera to support use with either pydantic v1 or v2 installed. All hera internal code now imports pydantic objects from hera.shared._pydantic (extended and renamed from _base_model). This module ensures that we're always using v1 compatible objects, which allows us to support codebases installing either pydantic v1 or v2 (although the models passed to Hera must be v1 for pydantic v1 and v2 for pydantic v2).

@JacobHayes
Copy link
Contributor Author

JacobHayes commented Oct 1, 2023

Sorry for the large PR w/o much prior discussion - I think a lot of it is pretty rote transformations though (updating imports). This one might also be a bit easier to review commit-by-commit.

@matty-rose
Copy link
Contributor

hey @JacobHayes bit of a driveby comment but i'd done a little digging as well into introducing pydantic v2 compatibility here and ran into the exact issues with the codegen stuff seen in the CI failures here - the commit from this PR - JacobHayes#1 i think should help fix those. hope this helps a little, super keen to see this PR land!

@JacobHayes
Copy link
Contributor Author

Much appreciated @matty-rose!

@JacobHayes JacobHayes force-pushed the pydantic-v1-v2 branch 2 times, most recently from 39388ea to 8ddabf3 Compare October 11, 2023 15:53
@flaviuvadan flaviuvadan added type:enhancement A general enhancement semver:minor A change requiring a minor version bump labels Oct 11, 2023
@codecov
Copy link

codecov bot commented Oct 11, 2023

Codecov Report

Attention: 4 lines in your changes are missing coverage. Please review.

Comparison is base (826cebb) 79.7% compared to head (2b8ed33) 79.7%.

Files Patch % Lines
src/hera/shared/serialization.py 69.2% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@          Coverage Diff          @@
##            main    #795   +/-   ##
=====================================
  Coverage   79.7%   79.7%           
=====================================
  Files         45      45           
  Lines       3706    3724   +18     
  Branches     750     754    +4     
=====================================
+ Hits        2955    2970   +15     
- Misses       558     560    +2     
- Partials     193     194    +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@JacobHayes JacobHayes force-pushed the pydantic-v1-v2 branch 2 times, most recently from ed785c6 to 08bcfec Compare October 11, 2023 16:46
@JacobHayes JacobHayes marked this pull request as ready for review October 11, 2023 16:46
@JacobHayes
Copy link
Contributor Author

I'd still like to add a test run that overrides the poetry install in CI to use pydantic v1 to make sure that does (and continues to) work.

Do you all have any suggestions? Perhaps adding a simplified test-pydantic-v1 job to .github/workflows/cicd.yaml that overrides the installed version (that doesn't use a matrix, upload coverage, etc)?

@flaviuvadan
Copy link
Collaborator

I'd still like to add a test run that overrides the poetry install in CI to use pydantic v1 to make sure that does (and continues to) work.

Do you all have any suggestions? Perhaps adding a simplified test-pydantic-v1 job to .github/workflows/cicd.yaml that overrides the installed version (that doesn't use a matrix, upload coverage, etc)?

This sounds great to me. Could it be included in the matrix build maybe?

@JacobHayes
Copy link
Contributor Author

Are you thinking a new pydantic_major_version: [1, 2] arg and just always do something like pip install 'pydantic==$pydantic_major_version (w/ whatever tweaks pip needs to "take latest for that major version") after the poetry install? It does add a lot of new jobs but I guess the parallelism takes care of that haha.

One thing I'm not certain about is whether mypy will work across both versions (which is one reason for the test in the first place 😁) - hopefully we don't need to tweak the job any if there are issues there.

@flaviuvadan
Copy link
Collaborator

It does add a lot of new jobs but I guess the parallelism takes care of that haha

Yea, that's what I was thinking! And also this would be temporary. Perhaps we can remove it in a few months.

One thing I'm not certain about is whether mypy will work across both versions (which is one reason for the test in the first place 😁) - hopefully we don't need to tweak the job any if there are issues there.

Hopeful that we don't have to change it :)

@flaviuvadan
Copy link
Collaborator

@samj1912 and @elliotgunton this PR + approach LGTM. Any chance I can trouble you to review? Also weigh in on the Q of pydantic V1 vs V2 testing

@JacobHayes
Copy link
Contributor Author

Going to work on adding pydantic versions to build matrix here in a bit

@flaviuvadan
Copy link
Collaborator

@elliotgunton and @samj1912 nudge to review this. Again, LGTM, and I am a fan of the second job approach to verify pydantic v1 backwards compatibility

@flaviuvadan
Copy link
Collaborator

@JacobHayes what do you think about appending

[mypy-pydantic.*]
ignore_missing_imports = True

to mypy.ini prior to running pydantic v1 tests in CI?

Copy link
Collaborator

@elliotgunton elliotgunton left a comment

Choose a reason for hiding this comment

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

Awesome stuff @JacobHayes! 🚀

On this:

add a couple more tests and try to support serializing v1 and v2 user-defined models (not just the v1 models from either version - I think this should be possible).

Have you been able to add v2 models? I think a couple of tests using v2 models mirroring the callable_script.py example would suffice!

src/hera/shared/_pydantic.py Outdated Show resolved Hide resolved
.github/workflows/cicd.yaml Show resolved Hide resolved
@JacobHayes
Copy link
Contributor Author

Thanks for the suggestions, circling back to this today. 🚀

I think we should be able to get v1 and v2 user models serialized, but I think it'd be best (or at least easiest 😁) for the Hera internal models to be "all v1" or "all v2" until we move to v2 only.

@JacobHayes
Copy link
Contributor Author

rebased, but will follow up on the rest tomorrow

Signed-off-by: Jacob Hayes <jacob.r.hayes@gmail.com>
Signed-off-by: Jacob Hayes <jacob.r.hayes@gmail.com>
@sambhav sambhav force-pushed the pydantic-v1-v2 branch 7 times, most recently from 36a504f to 70e7a9e Compare December 7, 2023 23:40
matty-rose and others added 6 commits December 7, 2023 23:41
Signed-off-by: Matt Rose <mattyrose@canva.com>
Signed-off-by: Jacob Hayes <jacob.r.hayes@gmail.com>
Signed-off-by: Jacob Hayes <jacob.r.hayes@gmail.com>
Signed-off-by: Jacob Hayes <jacob.r.hayes@gmail.com>
Signed-off-by: Jacob Hayes <jacob.r.hayes@gmail.com>
Signed-off-by: Sambhav Kothari <skothari44@bloomberg.net>
@@ -89,7 +91,7 @@ def function_kebab_object(annotated_input_value: Annotated[Input, Parameter(name
with Workflow(name="my-workflow") as w:
with Steps(name="my-steps") as s:
my_function(arguments={"input": Input(a=2, b="bar", c=42)})
str_function(arguments={"input": Input(a=2, b="bar", c=42).json()})
str_function(arguments={"input": serialize(Input(a=2, b="bar", c=42))})
Copy link
Collaborator

Choose a reason for hiding this comment

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

This needs to be changed to serialize function in hera, which correctly handles dumping both v1 and v2 objects.

Comment on lines -81 to -92
pytest.param(
"tests.script_runner.parameter_inputs:str_subclass_parameter_expects_jsonstr_dict",
[{"name": "my_json_str", "value": json.dumps({"my": "dict"})}],
{"my": "dict"},
id="str-subclass-json-param-as-dict",
),
pytest.param(
"tests.script_runner.parameter_inputs:str_subclass_annotated_parameter_expects_jsonstr_dict",
[{"name": "my_json_str", "value": json.dumps({"my": "dict"})}],
{"my": "dict"},
id="str-subclass-json-annotated-param-as-dict",
),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Had to remove these tests as MyStr is considered an arbitrary type in pydantic v2 and we don't have arbitrary types enabled even for v1. Made more sense to just get rid of this example (which we had added of our own volition in a recent PR by @elliotgunton )

Signed-off-by: Sambhav Kothari <skothari44@bloomberg.net>
@sambhav sambhav enabled auto-merge (squash) December 7, 2023 23:53
@sambhav sambhav disabled auto-merge December 7, 2023 23:53
Copy link
Collaborator

@elliotgunton elliotgunton left a comment

Choose a reason for hiding this comment

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

Nothing blocking, looking good 🚀

src/hera/workflows/runner.py Outdated Show resolved Hide resolved
src/hera/shared/serialization.py Show resolved Hide resolved
src/hera/workflows/runner.py Show resolved Hide resolved
src/hera/workflows/runner.py Outdated Show resolved Hide resolved
tests/test_examples.py Outdated Show resolved Hide resolved
@sambhav sambhav force-pushed the pydantic-v1-v2 branch 2 times, most recently from 685aaa5 to 6c22fb1 Compare December 8, 2023 12:13
@sambhav sambhav enabled auto-merge (squash) December 8, 2023 12:13
Signed-off-by: Sambhav Kothari <skothari44@bloomberg.net>
@sambhav sambhav merged commit f0279c8 into argoproj-labs:main Dec 8, 2023
19 checks passed
@JacobHayes JacobHayes deleted the pydantic-v1-v2 branch December 15, 2023 01:24
@JacobHayes
Copy link
Contributor Author

This would have (or could 😁) simplify mypy things across versions: pydantic/pydantic#9042

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver:minor A change requiring a minor version bump type:enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Pydantic v2
5 participants