Bug: Invalid Coverage for Optional Fields with Annotated Constraint
tharindurr opened this issue · 0 comments
tharindurr commented
Description
I was trying to produce coverage for a Pydantic model with Annotated Field constraints.
class PartialA(BaseModel):
a: Annotated[str | None, Field(min_length=1, max_length=10)] = None
The coverage function does not yield proper attributes for field a
.
I tracked it down to the method get_field_value_coverage
in BaseFactory
which should extract the proper constraints.
Hope the issue is clear, happy to give further clarifications.
URL to code causing the issue
No response
MCVE
- This is a test that I wrote which can be used to test my issue
from pydantic import BaseModel, Field
from typing import Annotated
from polyfactory.factories.pydantic_factory import ModelFactory
from polyfactory.pytest_plugin import register_fixture
class A(BaseModel):
a: Annotated[str, Field(min_length=1, max_length=10)]
class PartialA(BaseModel):
a: Annotated[str | None, Field(min_length=1, max_length=10)] = None
class PartialB(BaseModel):
a: str | None = None
class PartialC(BaseModel):
a: Annotated[int | None, Field(ge=0, le=10)] = None
@register_fixture
class ASchemaFactory(ModelFactory[A]):
__model__ = A
@register_fixture
class PartialASchemaFactory(ModelFactory[PartialA]):
__model__ = PartialA
@register_fixture
class PartialBSchemaFactory(ModelFactory[PartialB]):
__model__ = PartialB
@register_fixture
class PartialCSchemaFactory(ModelFactory[PartialC]):
__model__ = PartialC
def test_a_schema_factory(
a_schema_factory: ASchemaFactory):
for spec in a_schema_factory.coverage():
pass
def test_partial_a_schema_factory(
partial_a_schema_factory: PartialASchemaFactory):
for spec in partial_a_schema_factory.coverage():
pass
def test_partial_b_schema_factory(
partial_b_schema_factory: PartialBSchemaFactory):
for spec in partial_b_schema_factory.coverage():
pass
def test_partial_c_schema_factory(
partial_c_schema_factory: PartialCSchemaFactory):
for spec in partial_c_schema_factory.coverage():
pass
Steps to reproduce
No response
Screenshots
No response
Logs
==================================================================== test session starts =====================================================================
platform linux -- Python 3.12.2, pytest-7.4.3, pluggy-1.3.0
rootdir: /home/rr/work/oss/polyfactory
configfile: pyproject.toml
plugins: cov-4.1.0, hypothesis-6.92.1, Faker-21.0.0, asyncio-0.23.2
asyncio: mode=Mode.AUTO
collected 4 items
tests/test_optional_constraint_coverage_factory.py .F.F
========================================================================== FAILURES ==========================================================================
_______________________________________________________________ test_partial_a_schema_factory ________________________________________________________________
partial_a_schema_factory = <class 'tests.test_optional_constraint_coverage_factory.PartialASchemaFactory'>
def test_partial_a_schema_factory(
partial_a_schema_factory: PartialASchemaFactory):
> for spec in partial_a_schema_factory.coverage():
tests/test_optional_constraint_coverage_factory.py:44:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'tests.test_optional_constraint_coverage_factory.PartialASchemaFactory'>, kwargs = {}, data = {'a': 'GHTBnvXwdvDGBsyHYejs'}
@classmethod
def coverage(cls, **kwargs: Any) -> abc.Iterator[T]:
"""Build a batch of the factory's Meta.model will full coverage of the sub-types of the model.
:param kwargs: Any kwargs. If field_meta names are set in kwargs, their values will be used.
:returns: A iterator of instances of type T.
"""
for data in cls.process_kwargs_coverage(**kwargs):
> instance = cls.__model__(**data)
E pydantic_core._pydantic_core.ValidationError: 1 validation error for PartialA
E a
E String should have at most 10 characters [type=string_too_long, input_value='GHTBnvXwdvDGBsyHYejs', input_type=str]
E For further information visit https://errors.pydantic.dev/2.5/v/string_too_long
polyfactory/factories/base.py:1058: ValidationError
_______________________________________________________________ test_partial_c_schema_factory ________________________________________________________________
partial_c_schema_factory = <class 'tests.test_optional_constraint_coverage_factory.PartialCSchemaFactory'>
def test_partial_c_schema_factory(
partial_c_schema_factory: PartialCSchemaFactory):
> for spec in partial_c_schema_factory.coverage():
tests/test_optional_constraint_coverage_factory.py:54:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'tests.test_optional_constraint_coverage_factory.PartialCSchemaFactory'>, kwargs = {}, data = {'a': 7693}
@classmethod
def coverage(cls, **kwargs: Any) -> abc.Iterator[T]:
"""Build a batch of the factory's Meta.model will full coverage of the sub-types of the model.
:param kwargs: Any kwargs. If field_meta names are set in kwargs, their values will be used.
:returns: A iterator of instances of type T.
"""
for data in cls.process_kwargs_coverage(**kwargs):
> instance = cls.__model__(**data)
E pydantic_core._pydantic_core.ValidationError: 1 validation error for PartialC
E a
E Input should be less than or equal to 10 [type=less_than_equal, input_value=7693, input_type=int]
E For further information visit https://errors.pydantic.dev/2.5/v/less_than_equal
polyfactory/factories/base.py:1058: ValidationError
====================================================================== warnings summary ======================================================================
.venv/lib/python3.12/site-packages/beanie/odm/fields.py:581
/home/rr/work/oss/polyfactory/.venv/lib/python3.12/site-packages/beanie/odm/fields.py:581: DeprecationWarning: `general_plain_validator_function` is deprecated, use `with_info_plain_validator_function` instead.
return core_schema.general_plain_validator_function(validate)
.venv/lib/python3.12/site-packages/pydantic_core/core_schema.py:3902
.venv/lib/python3.12/site-packages/pydantic_core/core_schema.py:3902
.venv/lib/python3.12/site-packages/pydantic_core/core_schema.py:3902
/home/rr/work/oss/polyfactory/.venv/lib/python3.12/site-packages/pydantic_core/core_schema.py:3902: DeprecationWarning: `general_plain_validator_function` is deprecated, use `with_info_plain_validator_function` instead.
warnings.warn(
.venv/lib/python3.12/site-packages/beanie/odm/fields.py:150
.venv/lib/python3.12/site-packages/beanie/odm/fields.py:150
/home/rr/work/oss/polyfactory/.venv/lib/python3.12/site-packages/beanie/odm/fields.py:150: DeprecationWarning: `general_plain_validator_function` is deprecated, use `with_info_plain_validator_function` instead.
python_schema=core_schema.general_plain_validator_function(
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================================================== short test summary info ===================================================================
FAILED tests/test_optional_constraint_coverage_factory.py::test_partial_a_schema_factory - pydantic_core._pydantic_core.ValidationError: 1 validation error for PartialA
FAILED tests/test_optional_constraint_coverage_factory.py::test_partial_c_schema_factory - pydantic_core._pydantic_core.ValidationError: 1 validation error for PartialC
========================================================== 2 failed, 2 passed, 6 warnings in 0.46s ===========================================================
Release Version
2.15.0
Platform
- Linux
- Mac
- Windows
- Other (Please specify in the description above)
Note
While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.
Check out all issues funded or available for funding on our Polar.sh dashboard
- If you would like to see an issue prioritized, make a pledge towards it!
- We receive the pledge once the issue is completed & verified
- This, along with engagement in the community, helps us know which features are a priority to our users.