Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Changelog
=========

* Reset `Polyfactory <https://polyfactory.litestar.dev/>`__’s default random state at the start of every test, if it is installed.

Thanks to davidszotten for the request in `Issue #720 <https://github.com/pytest-dev/pytest-randomly/issues/720>`__.

4.1.0 (2026-04-20)
------------------

Expand Down
5 changes: 5 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ All of these features are on by default but can be disabled with flags.

Only its `legacy random state <https://numpy.org/doc/stable/reference/random/legacy.html>`__ is affected.

* `Polyfactory <https://polyfactory.litestar.dev/>`__

Only the default random generator is affected. Factories that have called
``seed_random()`` with their own seed are unaffected.

* If additional random generators are used, they can be registered under the
``pytest_randomly.random_seeder``
`entry point <https://packaging.python.org/specifications/entry-points/>`_ and
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ test = [
"faker",
"model-bakery>=1.13",
"numpy",
"polyfactory",
"pytest>=9",
"pytest-xdist",
]
Expand Down
11 changes: 11 additions & 0 deletions src/pytest_randomly/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@
except ImportError: # pragma: no cover
have_numpy = False

# polyfactory
try:
from polyfactory.constants import DEFAULT_RANDOM as polyfactory_random

have_polyfactory = True
except ImportError: # pragma: no cover
have_polyfactory = False


def make_seed() -> int:
return random.Random().getrandbits(32)
Expand Down Expand Up @@ -157,6 +165,9 @@ def _reseed(config: Config, offset: int = 0) -> int:
if have_numpy: # pragma: no branch
np_random.seed(seed % 2**32)

if have_polyfactory: # pragma: no branch
polyfactory_random.setstate(random_state)

if entrypoint_reseeds is None:
eps = entry_points(group="pytest_randomly.random_seeder")
entrypoint_reseeds = [e.load() for e in eps]
Expand Down
44 changes: 44 additions & 0 deletions tests/test_pytest_randomly.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,50 @@ def test_one():
out.assert_outcomes(passed=1)


def test_polyfactory(ourtester):
"""
Check that Polyfactory's default random generator is reset between tests.

Uses a Union-typed field so the assertion depends on
DEFAULT_RANDOM.choice() picking which type to generate. A plain ``int``
field wouldn't do: Polyfactory generates those via its Faker instance,
whose random generator pytest-randomly already reseeds separately, so
such a test would pass even without resetting DEFAULT_RANDOM.
"""
ourtester.makepyfile(
test_one="""
from dataclasses import dataclass
from typing import Union

from polyfactory.factories import DataclassFactory


@dataclass
class Foo:
x: Union[int, str, float, bytes]


class FooFactory(DataclassFactory[Foo]):
__model__ = Foo


def test_a():
value = FooFactory.build().x
assert isinstance(value, str)
assert value == 'jKdWckZoDYuPmqHSsjBh'


def test_b():
value = FooFactory.build().x
assert isinstance(value, int)
assert value == 1908
"""
)

out = ourtester.runpytest("--randomly-seed=1")
out.assert_outcomes(passed=2)


def test_failing_import(testdir):
"""Test with pytest raising CollectError or ImportError.

Expand Down