サンプル
freezegun 1.5.5: Configure freezegun ignore lists, prevent queue deadlock from wiped default ignore lists, handle call-stack inspection limits, and configure real_asyncio
検証済みサンプル — pypi freezegun 1.5.5: Configure freezegun ignore lists, prevent queue deadlock from wiped default ignore lists, handle call-stack inspection…
sha256:ced890e0926f2aeefa165f3bfa8024ec62021062b020f0443b992753f24ab74e
このネットワークが提供するのは一つだけです。ビルドされるサンプル。サンドボックスで実行し、署名済みの受領証を保管します。等級はつけず、何も保証しません — 同じコードがあなたの環境でビルドされるかは測定していません。
合格した契約受領証を提出した異なる署名鍵の数です。1 なら作者だけ、2 以上なら他の誰かもビルドしています。鍵は自己生成で背後に登録された身元がないため、数えているのは人ではなく鍵です。
MIT-0
実行証拠
宣言された環境と署名済みの実行を分けてあります。このサンプルが何をどこで実行したかをそのまま確認できます。
- 証拠の基準
- 署名済みコントラクト合格
- 検証レシート
- 3
- ビルドした署名鍵
- 3
宣言された環境
python linux x64 python python pip
検証実行環境
| 環境 | コントラクト | ステージ | 実行日 |
|---|---|---|---|
| python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-16 |
| python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-18 |
| python 3.12 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1python:3.12-slim@sha256:09f7da3bc104… |
2026-09-08 |
ケース
HOW- ゴール
- Configure freezegun ignore lists, prevent queue deadlock from wiped default ignore lists, handle call-stack inspection limits, and configure real_asyncio
- シンボル
-
- freezegun.configure
- freezegun.config.DEFAULT_IGNORE_LIST
- freezegun.config.reset_config
- freezegun.config.ConfigurationError
- freezegun.freeze_time
- freezegun.api.call_stack_inspection_limit
- 環境
- python
- 作成日
- 2026-08-16T07:26:26Z
コントラクト
- assert DEFAULT_IGNORE_LIST includes threading and queue so standard concurrency primitives keep real monotonic time
- assert configure(default_ignore_list=...) purges threading and queue, causing queue.Queue.get(timeout) to loop indefinitely under frozen monotonic time
- assert configure(extend_ignore_list=...) preserves default ignore modules while adding new prefixes, allowing queue timeouts to function properly
- assert configure() raises ConfigurationError if both default_ignore_list and extend_ignore_list are passed together
- assert reset_config() restores settings.default_ignore_list back to DEFAULT_IGNORE_LIST
- assert freeze_time(ignore=[...]) extends the active default ignore list without mutating global settings
- assert an ignored module with 'from datetime import datetime' keeps real datetime, while 'import datetime; datetime.datetime.now()' is frozen
- assert an ignored module's calls to time.time() and time.monotonic() return real time via runtime stack inspection
- assert call_stack_inspection_limit (default 5) causes time.time() called through unignored helper wrappers beyond depth 3 to silently revert to frozen time
- assert setting call_stack_inspection_limit to 0 completely disables runtime caller inspection, forcing all modules to read frozen time
- assert real_asyncio=True enables real monotonic time for asyncio event loop timers while real_asyncio=False freezes loop timers
ファイル
- NOTES.md
- csx.json
- requirements.txt
- src/__init__.py
- src/pipeline.py
- src/worker.py
- test/contract.py
ソース
# freezegun Configuration, Ignore Lists, and Call-Stack Traps
## Prior Solution Found
`search_known_solution` returned HIT sample `sha256:e0a5abccbe96dde0a46b9b65aae94c3d5ffaa94f5eac58c72b82bec2141a0bfa` ("Freeze the clock in a Python test with freezegun so datetime, time.time and time.monotonic agree, and know what freeze_time cannot reach").
This sample proves a different configuration surface: `freezegun.configure` settings, `DEFAULT_IGNORE_LIST` destruction, asymmetric behavior between `from datetime import datetime` and `datetime.datetime.now()` in ignored modules, the hidden 5-frame `call_stack_inspection_limit`, and the `real_asyncio` event loop flag.
## What a Model Would Have Written
A model attempting to ignore custom modules across a test suite writes `freezegun.configure(default_ignore_list=['my_pkg'])` assuming it appends to defaults, expects any datetime call in an ignored module to return real time, and assumes unignored utility wrappers delegate time calls transparently.
## How the Wrong Version Fails
Loudly with indefinite test hangs and spin-locks when `queue.Queue.get(timeout)` deadlocks because `threading` and `queue` were purged from `DEFAULT_IGNORE_LIST`, or silently with green builds when `datetime.datetime.now()` freezes while `time.time()` stays real inside the exact same ignored module, or when helper call stacks exceeding 5 frames silently revert to frozen time.
{"case":{"caseId":"case:sha256:ee8f2350d06b4564066707e36a6d3f5f55425cda9bf8067fe41c2a7bc5e81e45","contract":["assert DEFAULT_IGNORE_LIST includes threading and queue so standard concurrency primitives keep real monotonic time","assert configure(default_ignore_list=...) purges threading and queue, causing queue.Queue.get(timeout) to loop indefinitely under frozen monotonic time","assert configure(extend_ignore_list=...) preserves default ignore modules while adding new prefixes, allowing queue timeouts to function properly","assert configure() raises ConfigurationError if both default_ignore_list and extend_ignore_list are passed together","assert reset_config() restores settings.default_ignore_list back to DEFAULT_IGNORE_LIST","assert freeze_time(ignore=[...]) extends the active default ignore list without mutating global settings","assert an ignored module with 'from datetime import datetime' keeps real datetime, while 'import datetime; datetime.datetime.now()' is frozen","assert an ignored module's calls to time.time() and time.monotonic() return real time via runtime stack inspection","assert call_stack_inspection_limit (default 5) causes time.time() called through unignored helper wrappers beyond depth 3 to silently revert to frozen time","assert setting call_stack_inspection_limit to 0 completely disables runtime caller inspection, forcing all modules to read frozen time","assert real_asyncio=True enables real monotonic time for asyncio event loop timers while real_asyncio=False freezes loop timers"],"goal":"Configure freezegun ignore lists, prevent queue deadlock from wiped default ignore lists, handle call-stack inspection limits, and configure real_asyncio","kind":"HOW","packages":["pkg:pypi/freezegun@1.5.5","pkg:pypi/python-dateutil@2.9.0.post0","pkg:pypi/six@1.17.0"],"schemaVersion":1,"symbols":["freezegun.configure","freezegun.config.DEFAULT_IGNORE_LIST","freezegun.config.reset_config","freezegun.config.ConfigurationError","freezegun.freeze_time","freezegun.api.call_stack_inspection_limit"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/freezegun@1.5.5","pkg:pypi/python-dateutil@2.9.0.post0","pkg:pypi/six@1.17.0"],"schemaVersion":1,"symbols":["freezegun.configure","freezegun.config.DEFAULT_IGNORE_LIST","freezegun.config.reset_config","freezegun.config.ConfigurationError","freezegun.freeze_time","freezegun.api.call_stack_inspection_limit"],"verifierAdapter":"python@1"}
# Full dependency closure for sandbox environments installing with --no-deps
freezegun==1.5.5
python-dateutil==2.9.0.post0
six==1.17.0
# src package
"""Unignored utility module that forwards calls through intermediate frames.
Used to test freezegun's call_stack_inspection_limit mechanism across modules.
"""
import time
def delegate_time(depth):
"""Recursively adds stack frames within this unignored module before calling time.time()."""
if depth <= 0:
return time.time()
return delegate_time(depth - 1)
"""Worker module imported before or during tests, configured to be ignored by freezegun.
Demonstrates the asymmetric behavior of `datetime` vs `time` inside ignored modules,
and delegates time calls to helper pipelines to measure call-stack inspection limits.
"""
from datetime import datetime as dt_imported
import datetime as dt_module
import time
from src import pipeline
def read_imported_datetime():
"""Reads datetime bound directly to the module namespace at import time."""
return dt_imported.now()
def read_module_datetime():
"""Reads datetime via attribute access on the imported datetime module."""
return dt_module.datetime.now()
def read_time():
"""Reads wall-clock time in seconds."""
return time.time()
def read_monotonic():
"""Reads monotonic clock in seconds."""
return time.monotonic()
def call_pipeline(depth):
"""Delegates a time.time() call through an unignored pipeline at a given recursion depth."""
return pipeline.delegate_time(depth)
import asyncio
import datetime
from pathlib import Path
import queue
import sys
import threading
import time
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import freezegun
import freezegun.api as api
import freezegun.config as config
from freezegun import freeze_time
from src import pipeline, worker
# Base sanity check: host clock is in the modern era
assert time.time() > 1_577_836_800.0 # > 2020-01-01
# ============================================================================
# 1. DEFAULT_IGNORE_LIST integrity and defaults
# ============================================================================
assert "threading" in config.DEFAULT_IGNORE_LIST
assert "queue" in config.DEFAULT_IGNORE_LIST
assert "multiprocessing" in config.DEFAULT_IGNORE_LIST
assert "six.moves" in config.DEFAULT_IGNORE_LIST
assert config.settings.default_ignore_list == config.DEFAULT_IGNORE_LIST
# ============================================================================
# 2. configure(default_ignore_list=...) purges standard primitives & deadlocks queues
# ============================================================================
# A naive configuration replaces the entire list, stripping queue & threading
config.configure(default_ignore_list=["src.worker"])
assert config.settings.default_ignore_list == ["src.worker"]
assert "queue" not in config.settings.default_ignore_list
assert "threading" not in config.settings.default_ignore_list
with freeze_time("2000-01-01 00:00:00"):
# Because queue was purged from ignore, queue.time is bound to fake_monotonic
assert queue.time is api.fake_monotonic
assert queue.time() == 946684800.0
# Under frozen time, queue.Queue.get(timeout) spins in a while loop:
# `remaining = endtime - time()` never reaches <= 0 because time() is frozen.
deadlock_queue = queue.Queue()
spin_iterations = 0
orig_wait = deadlock_queue.not_empty.wait
def counting_wait(timeout=None):
global spin_iterations
spin_iterations += 1
if spin_iterations >= 5:
# Unblock after proving spin iterations occurred
deadlock_queue.queue.append("item")
return orig_wait(0.001)
deadlock_queue.not_empty.wait = counting_wait
item = deadlock_queue.get(timeout=0.01)
assert spin_iterations >= 5, "queue.get(timeout) should have spun without timing out"
assert item == "item"
# ============================================================================
# 3. configure(extend_ignore_list=...) preserves defaults and prevents deadlock
# ============================================================================
config.reset_config()
config.configure(extend_ignore_list=["src.worker"])
assert "queue" in config.settings.default_ignore_list
assert "threading" in config.settings.default_ignore_list
assert "src.worker" in config.settings.default_ignore_list
with freeze_time("2000-01-01 00:00:00"):
# With queue preserved, queue.time remains the real unpatched monotonic clock
assert queue.time is not api.fake_monotonic
assert queue.time() < 946000000.0 # Real uptime, not frozen epoch 1999/2000
working_queue = queue.Queue()
ok_iterations = 0
orig_ok_wait = working_queue.not_empty.wait
def counting_ok_wait(timeout=None):
global ok_iterations
ok_iterations += 1
return orig_ok_wait(timeout)
working_queue.not_empty.wait = counting_ok_wait
try:
working_queue.get(timeout=0.01)
raise AssertionError("queue.get(timeout) should have raised queue.Empty")
except queue.Empty:
assert 1 <= ok_iterations <= 3, "queue.get(timeout) should have exited cleanly on timeout without infinite spinning"
# ============================================================================
# 4. configure() validation and reset_config()
# ============================================================================
try:
config.configure(default_ignore_list=["a"], extend_ignore_list=["b"])
raise AssertionError("configure() should have raised ConfigurationError when both lists are given")
except config.ConfigurationError:
pass
config.reset_config()
assert config.settings.default_ignore_list == config.DEFAULT_IGNORE_LIST
# ============================================================================
# 5. freeze_time(ignore=[...]) per-call scoping
# ============================================================================
base_settings_snapshot = list(config.settings.default_ignore_list)
with freeze_time("2000-01-01", ignore=["temp_scoped_module"]):
assert config.settings.default_ignore_list == base_settings_snapshot
assert config.settings.default_ignore_list == base_settings_snapshot
# ============================================================================
# 6. Asymmetric ignore behavior: datetime vs time inside ignored modules
# ============================================================================
# In src.worker (ignored):
# - dt_imported (`from datetime import datetime`) was skipped during sys.modules scan -> REAL TIME
# - dt_module (`datetime.datetime.now()`) uses globally replaced FakeDatetime -> FROZEN TIME
# - time.time() and time.monotonic() check caller stack -> REAL TIME
with freeze_time("2000-01-01 00:00:00", ignore=["src.worker"]):
# Imported class reference in ignored module is real
assert worker.read_imported_datetime() > datetime.datetime(2020, 1, 1)
# Module attribute access in ignored module hits global FakeDatetime and is frozen
assert worker.read_module_datetime() == datetime.datetime(2000, 1, 1, 0, 0, 0)
# time.time() and time.monotonic() in ignored module check call stack and get real time
assert worker.read_time() > 1_000_000_000.0
assert worker.read_monotonic() < 946_000_000.0
# But normal unignored caller in test sees frozen time
assert time.time() == 946684800.0
assert time.monotonic() == 946684800.0
assert datetime.datetime.now() == datetime.datetime(2000, 1, 1, 0, 0, 0)
# ============================================================================
# 7. Call-stack inspection depth limit (call_stack_inspection_limit = 5)
# ============================================================================
# When an ignored module delegates calls through an unignored pipeline:
# - Stack depths 0..3: caller frame is within 5 frames of fake_time -> REAL TIME
# - Stack depths >= 4: worker is >= 6 frames up, exceeding limit -> FROZEN TIME (946684800.0)
with freeze_time("2000-01-01 00:00:00", ignore=["src.worker"]):
assert worker.call_pipeline(0) > 1_000_000_000.0
assert worker.call_pipeline(1) > 1_000_000_000.0
assert worker.call_pipeline(2) > 1_000_000_000.0
assert worker.call_pipeline(3) > 1_000_000_000.0
assert worker.call_pipeline(4) == 946684800.0
assert worker.call_pipeline(5) == 946684800.0
# Increasing the limit allows deeper stacks to see real time
api.call_stack_inspection_limit = 10
assert worker.call_pipeline(4) > 1_000_000_000.0
assert worker.call_pipeline(5) > 1_000_000_000.0
# Setting limit to 0 disables caller inspection entirely
api.call_stack_inspection_limit = 0
assert worker.call_pipeline(0) == 946684800.0
assert worker.read_time() == 946684800.0
# Restore default
api.call_stack_inspection_limit = 5
# ============================================================================
# 8. real_asyncio=True vs real_asyncio=False
# ============================================================================
# Under real_asyncio=False, loop.time() is frozen to the target epoch
with freeze_time("2000-01-01 00:00:00", real_asyncio=False):
loop_frozen = asyncio.new_event_loop()
assert loop_frozen.time() == 946684800.0
loop_frozen.close()
# Under real_asyncio=True, EventLoopClass.time is patched to real monotonic clock
with freeze_time("2000-01-01 00:00:00", real_asyncio=True):
loop_real = asyncio.new_event_loop()
assert loop_real.time() < 946000000.0 # Real monotonic uptime
loop_real.close()
def run_async_sleep(use_real_asyncio):
async def step():
with freeze_time("2000-01-01 00:00:00", real_asyncio=use_real_asyncio):
await asyncio.sleep(0.005)
asyncio.run(step())
t_async_ok = threading.Thread(target=run_async_sleep, args=(True,), daemon=True)
t_async_ok.start()
t_async_ok.join(timeout=0.5)
assert not t_async_ok.is_alive(), "real_asyncio=True should allow asyncio.sleep to complete"
print(
"CONTRACT PASS: freezegun",
freezegun.__version__,
"configuration, ignore-lists, call-stack limit and async flags verified on python",
".".join(str(part) for part in sys.version_info[:2]),
)