Configuration¶
pytest-uuid can be configured globally via pyproject.toml or programmatically in conftest.py.
pyproject.toml¶
[tool.pytest_uuid]
default_ignore_list = ["sqlalchemy", "celery"]
extend_ignore_list = ["myapp.internal"]
default_exhaustion_behavior = "raise"
Options¶
| Option | Type | Default | Description |
|---|---|---|---|
default_ignore_list |
list[str] |
["botocore"] |
Modules that always receive real UUIDs |
extend_ignore_list |
list[str] |
[] |
Additional modules to add to ignore list |
default_exhaustion_behavior |
str |
"cycle" |
Default behavior when UUIDs exhausted |
Default Ignore List
By default, botocore is ignored because it uses uuid.uuid4() internally for generating idempotent ClientTokens in AWS API operations. Patching this can interfere with AWS SDK retry logic. Use extend_ignore_list to add additional packages without overriding this default.
Opting Out of Defaults Per-Test
If you need to mock packages in the default ignore list for a specific test, use the ignore_defaults=False parameter:
@pytest.mark.freeze_uuid("...", ignore_defaults=False)
def test_mock_botocore():
# botocore will now receive mocked UUIDs
pass
See the Decorator API or Marker API for more details.
Programmatic Configuration¶
Configure in conftest.py:
# conftest.py
import pytest_uuid
pytest_uuid.configure(
default_ignore_list=["sqlalchemy", "celery"],
extend_ignore_list=["myapp.internal"],
default_exhaustion_behavior="raise",
)
Ignore List¶
The ignore list specifies module prefixes that should receive real UUIDs even when mocking is active. This is useful for third-party libraries that depend on real UUIDs for internal operations.
Common Modules to Ignore¶
[tool.pytest_uuid]
default_ignore_list = [
"sqlalchemy", # ORM with UUID primary keys
"celery", # Task queue with UUID task IDs
"alembic", # Database migrations
"django", # Web framework internals
]
How Ignore Works¶
The ignore check inspects the entire call stack:
- When
uuid.uuid4()is called, pytest-uuid walks the call stack - If any frame is from a module matching an ignored prefix, a real UUID is returned
- This handles cases where your code calls a library that internally calls
uuid.uuid4()
def test_ignore_in_stack(mock_uuid):
mock_uuid.uuid4.set("12345678-1234-4678-8234-567812345678")
mock_uuid.uuid4.set_ignore("sqlalchemy")
# Your code calls SQLAlchemy, which calls uuid.uuid4()
# SQLAlchemy gets a real UUID because it's in the call stack
session.add(User(name="Alice"))
Exhaustion Behavior¶
Control what happens when a UUID sequence runs out:
| Behavior | Description |
|---|---|
"cycle" |
Loop back to the start of the sequence (default) |
"random" |
Generate random UUIDs |
"raise" |
Raise UUIDsExhaustedError |
Example: Strict Mode¶
For strict testing, raise an error when UUIDs are exhausted:
import uuid
import pytest
from pytest_uuid import UUIDsExhaustedError
def test_strict(mock_uuid):
mock_uuid.uuid4.set("11111111-1111-4111-8111-111111111111")
uuid.uuid4() # OK
with pytest.raises(UUIDsExhaustedError):
uuid.uuid4() # Fails - must provide enough UUIDs
Per-Test Override¶
Configuration can be overridden per-test:
import uuid
import pytest
# Global config: on_exhausted="raise"
@pytest.mark.freeze_uuid(
"11111111-1111-4111-8111-111111111111",
on_exhausted="cycle", # Override for this test
)
def test_with_override():
uuid.uuid4()
uuid.uuid4() # Cycles instead of raising
Environment Variables¶
Currently, pytest-uuid does not support environment variables for configuration. Use pyproject.toml or conftest.py instead.