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

dataclass field doesn't change required schema #968

Closed
ahirner opened this issue Nov 6, 2019 · 4 comments · Fixed by #980
Closed

dataclass field doesn't change required schema #968

ahirner opened this issue Nov 6, 2019 · 4 comments · Fixed by #980

Comments

@ahirner
Copy link
Contributor

@ahirner ahirner commented Nov 6, 2019

Bug

Please complete:

  • OS: Mac OS
  • Python version import sys; print(sys.version): 3.6.7 with dataclasses backport
  • Pydantic version import pydantic; print(pydantic.VERSION): 1.0

It is known that @pydantic.dataclasses.dataclass doesn't fully mimic the BaseModel. However, we'd like use .schema() representation faithfully. I'm wondering what's the best workaround.

Adding a Config for b with required=False doesn't carry over to .schema() either.

from typing import Dict

from dataclasses import field
from pydantic import Field, ValidationError
from pydantic.dataclasses import dataclass

@dataclass
class D1:
    a: int
    # b: Dict[str, int] = {"x":10} # mutable default, not allowed
@dataclass
class D2:
    a: int
    b: Dict[str, int] = Field({"x":10}) # pydantic.Field, unsafe and invalid default
@dataclass        
class D3:
    a: int
    b: Dict[str, int] = field(default_factory=lambda: {"x":10}) # std lib, safe and invalid default
        
class C:
    fields = {"b": { "required": False}} # doesn't carry over!!

@dataclass(config=C)        
class D4:
    a: int
    b: Dict[str, int] = field(default_factory=lambda: {"x":10})

print(D1(10))
try:
    print(D2(10))
except ValidationError as e:
    print(e) # pydantic/dataclasses.py:77

print(D3(10))
req = D3.__pydantic_model__.schema()["required"]
if req != ["a"]:
    print('only ["a"] should be required, is:', req)
    
print()
print(D4.__pydantic_model__.schema()["required"]) # same as D3

Output

D1(a=10)
1 validation error for D2
b
  value is not a valid dict (type=type_error.dict)
D3(a=10, b={'x': 10})
only ["a"] should be required, is: ['a', 'b']

['a', 'b']
@ahirner ahirner added the bug label Nov 6, 2019
@samuelcolvin samuelcolvin added feature request and removed bug labels Nov 6, 2019
@samuelcolvin

This comment has been minimized.

Copy link
Owner

@samuelcolvin samuelcolvin commented Nov 6, 2019

This isn't a bug, but a feature request.

class Config:
    fields = {"b": { "required": False}}

Wouldn't work on a normal model.

I think what you want is better support for the field() function from dataclasses. If so, please describe exactly what parts of field() usage you'd like to support in pydantic. Is it just the default in schema?

@ahirner

This comment has been minimized.

Copy link
Contributor Author

@ahirner ahirner commented Nov 7, 2019

Thanks for clarifying!
Only handling default* in schema is what we need to support. However, it would be nice to have a stable interface for .__pydantic_model__. I'm not sure if this might change.

@samuelcolvin

This comment has been minimized.

Copy link
Owner

@samuelcolvin samuelcolvin commented Nov 7, 2019

__pydantic_model__ won't change, we should document it.

It would be wonderful if you could create a PR for that. 😄

@ahirner

This comment has been minimized.

Copy link
Contributor Author

@ahirner ahirner commented Nov 8, 2019

i'm going for it

@ahirner ahirner mentioned this issue Nov 8, 2019
4 of 4 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.