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

Fix deserialization for str unions #1239

Merged
merged 7 commits into from
Oct 21, 2024

Conversation

alicederyn
Copy link
Collaborator

@alicederyn alicederyn commented Oct 15, 2024

Pull Request Checklist

Description of PR
PR #1168 changed the logic of map_runner_input and _parse to no longer pass incoming values to json.loads if their annotated type was a union that included str, rather than only when given a subtype of Optional[str]. This makes it impossible to, for instance, pass an int to a Union[str, int].

This PR splits origin_type_issubclass into two functions, origin_type_issupertype (which matches the previous behaviour) and origin_type_issubtype, and use the latter instead to restore the original behaviour.

Additionally, it fixes a bug where we were passing an annotation to issubclass without first checking if it's a type, resulting in a TypeError (partially addresses #1173).

@alicederyn alicederyn added semver:patch A change requiring a patch version bump type:bug A general bug labels Oct 15, 2024
PR argoproj-labs#1168 changed the logic of map_runner_input and _parse to no longer
pass incoming values to json.loads if their annotated type was a union
that included str, rather than only when given a subtype of
`Optional[str]`. Split `origin_type_issubclass` into two functions,
`origin_type_issupertype` (which matches the previous behaviour) and
`origin_type_issubtype`, and use the latter instead to restore the
original behaviour.

Add a runner check which verifies this behaviour.

Signed-off-by: Alice Purcell <[email protected]>
@alicederyn alicederyn force-pushed the revert._is_str_kwarg_of.change branch from 9192b57 to 52437be Compare October 15, 2024 10:44
Copy link

codecov bot commented Oct 15, 2024

Codecov Report

Attention: Patch coverage is 50.00000% with 11 lines in your changes missing coverage. Please review.

Project coverage is 45.9%. Comparing base (30cb592) to head (925150b).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/hera/shared/_type_util.py 20.0% 8 Missing ⚠️
.../hera/workflows/_runner/script_annotations_util.py 80.0% 1 Missing ⚠️
src/hera/workflows/_runner/util.py 80.0% 1 Missing ⚠️
src/hera/workflows/script.py 50.0% 1 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff          @@
##            main   #1239   +/-   ##
=====================================
  Coverage   45.9%   45.9%           
=====================================
  Files         60      60           
  Lines       4082    4096   +14     
  Branches     857     861    +4     
=====================================
+ Hits        1875    1884    +9     
- Misses      2175    2180    +5     
  Partials      32      32           

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

parse_obj_as does not appear to support union types (it is converting
ints to strings).

Signed-off-by: Alice Purcell <[email protected]>
tests/test_runner.py Outdated Show resolved Hide resolved
@alicederyn alicederyn marked this pull request as ready for review October 15, 2024 11:57
Copy link
Collaborator

@jeongukjae jeongukjae 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 to me. just small one.

Comment on lines -128 to +134
return origin_type_issubclass(func_param_annotation, str)
return origin_type_issubtype(func_param_annotation, (str, NoneType))
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍 Thanks

src/hera/shared/_type_util.py Outdated Show resolved Hide resolved
If origin_type_issubtype or origin_type_issupertype are passed a special
form annotation, they will raise a TypeError due to passing it into
issubclass. Fix this issue by first checking if the annotation is a
type, and returning False if not.

Unit test this with NoReturn, as we are very unlikely to ever create
a special case for this type in the function.

Signed-off-by: Alice Purcell <[email protected]>
The origin_type_is* functions were accidentally calling get_args on the
original annotation rather than the unwrapped type.

Signed-off-by: Alice Purcell <[email protected]>
@alicederyn alicederyn force-pushed the revert._is_str_kwarg_of.change branch from 5f03b16 to c434384 Compare October 17, 2024 08:34
Copy link
Collaborator

@jeongukjae jeongukjae 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 👍

tests/test_runner.py Outdated Show resolved Hide resolved
Pydantic v1 checks union types in declaration order, returning as soon
as a coercion succeeds; see
https://docs.pydantic.dev/1.10/usage/model_config/#smart-union for more.
Change the test str_or_int_parameter signature from `str | int` to `int
| str` to work with this legacy mode.

Signed-off-by: Alice Purcell <[email protected]>
@sambhav sambhav merged commit 7df9b8e into argoproj-labs:main Oct 21, 2024
23 checks passed
@alicederyn alicederyn deleted the revert._is_str_kwarg_of.change branch October 21, 2024 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver:patch A change requiring a patch version bump type:bug A general bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants