Factory doesn't pick up `faker_session_locale` fixture changes, generates data with default settings
Description
Issue Description
When running tests and modifying Faker settings within the faker_session_locale fixture to generate data in a specific language (e.g., Russian), any Factory does not recognize these changes and continues generating data based on the default Faker object settings. As a result, data is generated with default settings instead of the expected Russian localization.
Proposed Solution
This issue can be resolved by creating a project-level fixture that replaces the Faker object instantiated when creating Factory objects. Since the problem manifests at the test level, the solution should be implemented at the same level.
MCVE
To write minimal code, you need to create several files and download several libraries:
uv init \
&& mkdir tests \
&& touch ./tests/conftest.py ./tests/test_example.py \
&& uv add polyfactory==2.21.0 pydantic pytest
# If not UV
python -m venv .venv \
&& source .venv/bin/activate \
&& mkdir tests \
&& touch ./tests/conftest.py ./tests/test_example.py \
&& pip install polyfactory==2.21.0 pydantic pytest
tests/conftest.py
import pytest
@pytest.fixture(scope='session', autouse=True)
def faker_session_locale():
return ['ru_RU']
tests/test_example.py
import re
from polyfactory.factories.pydantic_factory import ModelFactory
from polyfactory import Use
from pydantic import BaseModel
from faker import Faker
class ExampleModel(BaseModel):
field: str
class ExampleFactory(ModelFactory[ExampleModel]):
field = Use(ModelFactory.__faker__.word)
def test_exmaple(faker: Faker):
factory = ExampleFactory.build()
assert bool(re.search(r'[а-яёА-ЯЁ]', factory.field)), (factory.field, faker.word())
This test will fail because the answer will consist of English letters.
Release Version
2.21.0
Platform
- [x] Linux
- [ ] Mac
- [ ] Windows
- [ ] Other (Please specify in the description above)
How would this be expected to interact with non-session level scope described here?
I think I didn't express myself clearly - what I meant was: it would be convenient if setting global Faker configurations through the faker_session_locale fixture would automatically update all Faker instances created in each individual Factory's __faker__ attribute. This way, there would be no need to create a base Factory with the __faker__ = Faker(locale=["ru_RU"]) configuration.
Or is it possible to implement a global Faker configuration before running tests through a fixture for Factory for Polyfactory?
This makes sense as a use case to try and support.
Somes things to consider,
- This is a backwards breaking change if enabled by default. If want to enable by default then this should be left to v3 with appropriate migration note
- How is this being set per factory? Currently this fixture is coming from pytest fixture so lifecycle is within a pytest scope. Would this revert when outside pytest fixture scope
- There may places where random/faker differ or issues if bound already e.g.
Use(MyFactory.__faker__.pystrwon't use this faker instance if set. This is a separate issue but nice to resolve to avoid unexpected results