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 schema for set and frozenset with default value #4155

Merged

Conversation

aminalaee
Copy link
Contributor

@aminalaee aminalaee commented Jun 12, 2022

Change Summary

Fixes JSON schema for set and frozenset when they have default values, the output json is not valid and cannot be serialized.

For example:

import json
from pydantic import BaseModel

class Test(BaseModel):
    x = {1}

print(Test.schema())

It will produce:

{
  "title": "Test",
  "type": "object",
  "properties": {
    "x": {
      "title": "X",
      "type": "array",
      "default": {1},
      "items": {
        "type": "integer"
      },
      "uniqueItems": true
    }
  },
  "required": [
    "x"
  ]
}

But instead should be:

{
  "title": "Test",
  "type": "object",
  "properties": {
    "x": {
      "title": "X",
      "default": [
        1,
      ],
      "type": "array",
      "items": {},
      "uniqueItems": true
    }
  }
}

Related issue number

Fixes #4136

Checklist

  • Unit tests for the changes exist
  • Tests pass on CI and coverage remains at 100%
  • Documentation reflects the changes where applicable
  • changes/<pull request or issue id>-<github username>.md file added describing change
    (see changes/README.md for details)
  • My PR is ready to review, please add a comment including the phrase "please review" to assign reviewers

@aminalaee aminalaee changed the title Fix schema for Set with default value Fix schema for set and frozenset with default value Jun 12, 2022
@aminalaee
Copy link
Contributor Author

please review

@@ -984,7 +984,7 @@ def encode_default(dft: Any) -> Any:
return dft.value
elif isinstance(dft, (int, float, str)):
return dft
elif sequence_like(dft):
elif isinstance(dft, (list, tuple)):

Choose a reason for hiding this comment

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

I'm really not into the code base - so this is just a non-constructive critisism, but this change would narrow the scope compared to the original sequence_like check. What happens when these instances (set, frozenset, ...) are passed in?

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'm also very new to the codebase, but I think the sequence_like usage is not very accurate here.

If you look further, after these conditions it will try to use the pydantic_encoder for all unhandled types which in this case is set and frozenset.
And also there are tests for all cases and new ones for set and frozenset, so I think this is not narrowing down any type, just setting up different encoders for these types.

Choose a reason for hiding this comment

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

sounds reasonable! now we only need @samuelcolvin or @PrettyWood to approve :-)

@hramezani
Copy link
Member

hramezani commented Jul 13, 2022

Thanks @aminalaee for this patch 👍 LGTM

I think it would be good to add frozenset to the documentation about The field schema mapping from Python / pydantic as well. it was missed there.

@hramezani
Copy link
Member

please update

@aminalaee
Copy link
Contributor Author

please review

@samuelcolvin samuelcolvin merged commit 65a1381 into pydantic:master Aug 8, 2022
@samuelcolvin
Copy link
Member

Thanks so much @aminalaee.

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.

Serializing a set with default values creates a TypeError
5 participants