litestar-org/polyfactory

Bug: Pydantic Field(...., const=True) attribute ignored when creating pydantic instance with `ModelFactory`

xebia-pdalka opened this issue · 2 comments

Description

polyfactory starting from version 2.3.2 ignores Field(..., const=True) constraint of pydantic model when creating second (and subsequent) instance using ModelFactory. This causes pydantic validation failure. See code example for more details.

URL to code causing the issue

No response

MCVE

from polyfactory.factories.pydantic_factory import ModelFactory
from pydantic import BaseModel, Field

class A(BaseModel):
    v: int = Field(1, const=True)
    
class AFactory(ModelFactory[A]):
    __model__ = A

AFactory.build()
# returns: A(v=1) - OK

AFactory.build()
# raises:
# pydantic.error_wrappers.ValidationError: 1 validation error for A
# v
#   unexpected value; permitted: 1 (type=value_error.const; given=7545; permitted=[1])

Steps to reproduce

1. Run the sample code

Screenshots

No response

Logs

No response

Litestar Version

polyfactory==2.4.0
pydantic==1.10.9

Platform

  • Linux
  • Mac
  • Windows
  • Other (Please specify in the description above)

Funding

  • You can sponsor this specific effort via a Polar.sh pledge below
  • We receive the pledge once the issue is completed & verified
Fund with Polar

ill take a look

Thank you for the fix. It works for the sample code I have provided, however it does not seem to be generic - it does not work for Enum fields. See the example below. Unlike earlier, creating the first instance of pydantic class fails.

pydantic==1.10.9
polyfactory==2.6.1

from enum import Enum

from polyfactory.factories.pydantic_factory import ModelFactory
from pydantic import BaseModel, Field

class DataType(Enum):
    TYPE1 = 'TYPE1'
    TYPE2 = 'TYPE2'
    TYPE3 = 'TYPE3'
    TYPE4 = 'TYPE4'
    TYPE5 = 'TYPE5'
    TYPE6 = 'TYPE6'
    TYPE7 = 'TYPE7'
    TYPE8 = 'TYPE8'
    TYPE9 = 'TYPE9'

class A(BaseModel):
    v: int = Field(1, const=True)
    type: DataType = Field(DataType.TYPE1, const=True)

class AFactory(ModelFactory[A]):
    __model__ = A

AFactory.build()
# raises: 
# pydantic.error_wrappers.ValidationError: 1 validation error for A
# type
#   unexpected value; permitted: <DataType.TYPE1: 'TYPE1'> (type=value_error.const; given=DataType.TYPE2; permitted=[<DataType.TYPE1: 'TYPE1'>])