Unexpected Collection Length Generation with `annotation_types.Len(1)`
Problem Description
The main issue I've identified is that when using at.Len(1), the generator sometimes produces two values instead of one, contrary to what's stated in the documentation. I've located where this occurs in the code. If more than one value needs to be generated, the user should use the following options:
class Foo(BaseModel):
bar: Annotated[list[int], at.Len(1)]
class FooFactory(Foo[Foo]):
__randomize_collection_length__ = True
__min_collection_length__ = 2
__max_collection_length__ = 5
# Or
class FooFactory(Foo[Foo]):
@classmethod
def bar(cls) -> list[int]:
return cls.__faker__.pylist(cls.__faker__.pyint(2, 5), value_types=[int])
Current Behavior
When at.Len(1) is specified, the collection can contain either 1 or 2 elements due to the current logic.
Proposed Solution
I propose the following fix:
min_items = abs(min_items if min_items is not None else (max_items or 0))
max_items = abs(max_items) if max_items is not None else max(min_items, 1)
Instead of the current implementation:
min_items = abs(min_items if min_items is not None else (max_items or 0))
max_items = abs(max_items if max_items is not None else min_items + 1)
Expected Results
With this change, we would observe the following behavior:
min_items=1, max_items=None → max_items=1
min_items=0, max_items=None → max_items=1
min_items=5, max_items=None → max_items=5
min_items=None, max_items=None → min_items=0, max_items=1
Alternative
If this behavior was intentional by design, I'm willing to document this behavior in the documentation instead.
MCVE
from typing import Annotated
import annotated_types as at
from pydantic import BaseModel
from polyfactory.factories.pydantic_factory import ModelFactory
class Foo(BaseModel):
bar: Annotated[list[int], at.Len(1)]
class FooFactory(ModelFactory[Foo]):
__random_seed__ = 4
print(ModelFactory.create_factory(Foo).build())
Release Version
2.21.0
Platform
- [x] Linux
- [ ] Mac
- [ ] Windows
- [ ] Other (Please specify in the description above)
Proposed solution makes sense. I think constraints being a union of these makes sense which seems to be this behaviour
PRs welcome to fix
@Rub1kCube @adhtruong Please take a look at the PR. I've created it against my fork.