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 json validation for NameEmail #8650

Merged
merged 3 commits into from Jan 29, 2024

Conversation

Holi0317
Copy link
Contributor

Fixes #8649

Change Summary

Fixes json validation for NameEmail type

Related issue number

#8649

Checklist

  • The pull request title is a good summary of the changes - it will be used in the changelog
  • Unit tests for the changes exist
  • Tests pass on CI
  • Documentation reflects the changes where applicable
  • My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

Copy link

codspeed-hq bot commented Jan 26, 2024

CodSpeed Performance Report

Merging #8650 will not alter performance

Comparing Holi0317:8649-name-email-json (603d1b4) with main (5fc166c)

Summary

✅ 10 untouched benchmarks

Copy link
Contributor Author

@Holi0317 Holi0317 left a comment

Choose a reason for hiding this comment

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

Got few question and need guidance on the implementation and design. Writing core schema is a bit daunting ;(

@@ -464,22 +464,15 @@ def __init__(self, name: str, email: str):
def __eq__(self, other: Any) -> bool:
return isinstance(other, NameEmail) and (self.name, self.email) == (other.name, other.email)

@classmethod
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if my approach is correct here.

Actually I don't know what this method is (can't find docs on the website). But seems deleting this method breaks the json schema generation on format. Currently unit test are failing and I need some guidance on fixing that.

I added support on {"email": "", "name": ""} schema for the input. Not sure if we should do that or just stick with plain str which is a bit easier to implement I guess.

Copy link
Member

Choose a reason for hiding this comment

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

I think we can actually leave this here, that should help to resolve some of the issues with the failing tests.

'foo bar', 'foobaR@example.com'
)

assert Model.model_validate_json('{"v":{"name":"foo bar","email":"whatever <foobaR@example.com>"}}').v == NameEmail(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

IDK if this case should be allowed or should raise an exception. Coz the implementation just override the name from dict and throw away parsed name.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we want to support this case, as mentioned in my above comment.

@sydney-runkle sydney-runkle added the relnotes-fix Used for bugfixes. label Jan 29, 2024
Copy link
Member

@sydney-runkle sydney-runkle left a comment

Choose a reason for hiding this comment

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

Requested a few changes. Looks like you're off to a good start! Thanks for your contribution!

@@ -464,22 +464,15 @@ def __init__(self, name: str, email: str):
def __eq__(self, other: Any) -> bool:
return isinstance(other, NameEmail) and (self.name, self.email) == (other.name, other.email)

@classmethod
Copy link
Member

Choose a reason for hiding this comment

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

I think we can actually leave this here, that should help to resolve some of the issues with the failing tests.

field_schema = handler(core_schema)
field_schema.update(type='string', format='name-email')
return field_schema

@classmethod
def __get_pydantic_core_schema__(
Copy link
Member

Choose a reason for hiding this comment

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

I think a more simple approach would be something like this:

@classmethod
def __get_pydantic_core_schema__(
    cls,
    _source: type[Any],
    _handler: GetCoreSchemaHandler,
) -> core_schema.CoreSchema:
    import_email_validator()

    return core_schema.no_info_after_validator_function(
        cls._validate,
        core_schema.json_or_python_schema(
            json_schema=core_schema.str_schema(),
            python_schema=core_schema.union_schema(
                [core_schema.is_instance_schema(cls), core_schema.str_schema()],
                custom_error_type='name_email_type',
                custom_error_message='Input is not a valid NameEmail',
            ),
        ),
    )

pydantic/networks.py Outdated Show resolved Hide resolved
'foo bar', 'foobaR@example.com'
)

assert Model.model_validate_json('{"v":{"name":"foo bar","email":"whatever <foobaR@example.com>"}}').v == NameEmail(
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we want to support this case, as mentioned in my above comment.

@Holi0317
Copy link
Contributor Author

@sydney-runkle Thanks for your review. I've made the changes you request and simplify the test case a bit.

Copy link
Member

@sydney-runkle sydney-runkle left a comment

Choose a reason for hiding this comment

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

Nice work! Will merge this shortly :).

@sydney-runkle sydney-runkle merged commit b838cc9 into pydantic:main Jan 29, 2024
53 checks passed
@Holi0317 Holi0317 deleted the 8649-name-email-json branch January 29, 2024 21:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NameEmail does not support parsing from json input
2 participants