CodeSampleX

サンプル

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

コントラクト

  1. assert DEFAULT_IGNORE_LIST includes threading and queue so standard concurrency primitives keep real monotonic time
  2. assert configure(default_ignore_list=...) purges threading and queue, causing queue.Queue.get(timeout) to loop indefinitely under frozen monotonic time
  3. assert configure(extend_ignore_list=...) preserves default ignore modules while adding new prefixes, allowing queue timeouts to function properly
  4. assert configure() raises ConfigurationError if both default_ignore_list and extend_ignore_list are passed together
  5. assert reset_config() restores settings.default_ignore_list back to DEFAULT_IGNORE_LIST
  6. assert freeze_time(ignore=[...]) extends the active default ignore list without mutating global settings
  7. assert an ignored module with 'from datetime import datetime' keeps real datetime, while 'import datetime; datetime.datetime.now()' is frozen
  8. assert an ignored module's calls to time.time() and time.monotonic() return real time via runtime stack inspection
  9. assert call_stack_inspection_limit (default 5) causes time.time() called through unignored helper wrappers beyond depth 3 to silently revert to frozen time
  10. assert setting call_stack_inspection_limit to 0 completely disables runtime caller inspection, forcing all modules to read frozen time
  11. 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

ソースアーティファクトをダウンロード (tar.gz)

ソース

NOTES.md
# 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.
csx.json
{"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"}
requirements.txt
# 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/__init__.py
# src package
src/pipeline.py
"""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)
src/worker.py
"""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)
test/contract.py
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]),
)

オリジンシーダー

csx-seed