Repository: litestar-org/polyfactory (python)

Issue:
Setting seed does not make mock data generation deterministic in case of pydantic factory
Setting the random seed on a pydantic factory does not make it deterministic. When running below code we see different records being generated.

```python
from random import Random
from polyfactory.factories.pydantic_factory import ModelFactory
from pydantic import BaseModel, constr, condate
import datetime
from typing import Any

class Person(BaseModel):
    name: str
    date_of_birth: condate(ge=datetime.date(1900, 1, 1), lt=datetime.date.today())

class Factory(ModelFactory[Any]):
    __model__ = Person
    __random_seed__ = 42
    _random__ = Random(42)

for i in range(10):
    print(Factory.build())
```

<!-- POLAR PLEDGE BADGE START -->
---

## Funding
* If you would like to see an issue prioritized, make a pledge towards it!
* We receive the pledge once the issue is completed & verified

<a href="https://polar.sh/litestar-org/polyfactory/issues/316">
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://polar.sh/api/github/litestar-org/polyfactory/issues/316/pledge.svg?darkmode=1">
  <img alt="Fund with Polar" src="https://polar.sh/api/github/litestar-org/polyfactory/issues/316/pledge.svg">
</picture>
</a>
<!-- POLAR PLEDGE BADGE END -->


Pull request:
fix: constrained strings not deterministic with seed because urandom not seedable
[//]: # "By submitting this pull request, you agree to:"
[//]: # "- follow [Litestar's Code of Conduct](https://github.com/litestar-org/.github/blob/main/CODE_OF_CONDUCT.md)"
[//]: # "- follow [Litestar's contribution guidelines](https://github.com/litestar-org/.github/blob/main/CONTRIBUTING.md)"

### Pull Request Checklist

- [x] New code has 100% test coverage
- [x] (If applicable) The prose documentation has been updated to reflect the changes introduced by this PR
- [x] (If applicable) The reference documentation has been updated to reflect the changes introduced by this PR
- [x] Pre-Commit Checks were ran and passed
- [x] Tests were ran and passed

### Description
[//]: # "Please describe your pull request for new release changelog purposes"

- `urandom` was replaced by using `random.getrandbits` to make generation of constrained strings deterministic when seed is set

### Close Issue(s)
Fixes #316 




Patch:
diff --git a/polyfactory/value_generators/primitives.py b/polyfactory/value_generators/primitives.py
index 5fc348f..edad0f8 100644
--- a/polyfactory/value_generators/primitives.py
+++ b/polyfactory/value_generators/primitives.py
@@ -2,7 +2,6 @@ from __future__ import annotations
 
 from binascii import hexlify
 from decimal import Decimal
-from os import urandom
 from typing import TYPE_CHECKING
 
 if TYPE_CHECKING:
@@ -80,7 +79,7 @@ def create_random_bytes(
         max_length = min_length + 1 * 2
 
     length = random.randint(min_length, max_length)
-    result = hexlify(urandom(length))
+    result = b"" if length == 0 else hexlify(random.getrandbits(length * 8).to_bytes(length, "little"))
 
     if lower_case:
         result = result.lower()


Test patch:
diff --git a/tests/test_random_seed.py b/tests/test_random_seed.py
index 9a5ab91..0a2fb6f 100644
--- a/tests/test_random_seed.py
+++ b/tests/test_random_seed.py
@@ -40,3 +40,19 @@ def test_deterministic_optionals_seeding() -> None:
     ModelFactory.seed_random(seed)
     second_build = [FactoryWithNoneOptionals.build() for _ in range(10)]
     assert first_build == second_build
+
+
+def test_deterministic_constrained_strings() -> None:
+    class MyModel(BaseModel):
+        id: int
+        special_id: str = Field(min_length=10, max_length=24)
+
+    class MyModelFactory(ModelFactory):
+        __model__ = MyModel
+
+    ModelFactory.seed_random(1651)
+
+    ins = MyModelFactory.build()
+
+    assert ins.id == 4
+    assert ins.special_id == "48489ab53c59b24acfe1"