polyfactory icon indicating copy to clipboard operation
polyfactory copied to clipboard

Bug: empty string generated for regex requiring at least one char

Open WilliamDEdwards opened this issue 8 months ago • 1 comments

Description

Regex seems to be ignored inside dicts, as Polyfactory is generating `` as a value:

{'environment_variables': {'XZdrHqToIHlKKDxepfKJ': ''}}

Calling build() 10 times results in None 6 times, and `` 4 times.

--

This does NOT happen when the value is not nullable, i.e.:

class Model(BaseModel):
  environment_variables: Dict[str, constr(regex=r"^[A-Za-z_]+$")]

--

This ALSO happens when key/value are swapped:

class Model(BaseModel):
  environment_variables: Optional[Dict[constr(regex=r"^[A-Za-z_]+$"), str]]

Result:

{'environment_variables': {'': 'BildVEhMalDZKoEqvGvl'}}

--

This does NOT happen outside a dict:

class Model(BaseModel):
  environment_variables: constr(regex=r"^[A-Za-z_]+$")

Result:

{'environment_variables': 'XCjdsB'}

URL to code causing the issue

No response

MCVE

from polyfactory.factories.pydantic_factory import ModelFactory
from pydantic import BaseModel
from typing import Optional,Dict
from pydantic import constr,Field

class Model(BaseModel):
  environment_variables: Optional[Dict[str, constr(regex=r"^[A-Za-z_]+$")]]

class Factory(ModelFactory[Model]):
  ...

print(Factory.build())

Steps to reproduce

See MRE

Screenshots

No response

Logs


Release Version

2.21.0

Platform

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

WilliamDEdwards avatar Apr 24 '25 12:04 WilliamDEdwards

Hi @WilliamDEdwards , based on regex vs pattern I'm guessing this is using v1?

I think internal this is parsed correctly in polyfactory as conlist and similar have specific workaround so not parsed correctly in general. Trying the newer suggested syntax seems to work. Does this work to update usage?


from typing import Annotated, Dict, Optional

from pydantic.v1 import BaseModel, Field

from polyfactory.factories.pydantic_factory import ModelFactory


class Model(BaseModel):
    environment_variables: Optional[Dict[str, Annotated[str, Field(regex=r"^[A-Za-z_]+$")]]]


class Factory(ModelFactory[Model]): ...


def test_build() -> None:
    assert Factory.batch(10)  # noqa: S101

adhtruong avatar May 26 '25 10:05 adhtruong