← the record

Audit a2eb44b9783f

pallets/flask at 36e4a824f3: the project's own tests caught 29 of 40 planted faults, 11 got through, and corral proved 10 of those missing tests by writing a test and running it.

repo
https://github.com/pallets/flask
commit
36e4a824f340fdee7ed50937ba8e7f6bc7d17f81
corral
v1.0.0-rc.10.0.20260908141717-7224c328bb4f
substrate
workspace
seats
critic: claude-haiku-4-5
mutant-generator: gemini-3.6-flash
test-writer: gemini-3.6-flash
tokens
564.2k in, 8.5k out, 28 calls
started
2026-09-08 14:37 UTC
not audited
153 no-language · 79 gitignored · 27 is-test · 21 test-support — lives in the test tree, never a subject · 20 not-selected · 11 no-paired-test · 2 imported at load time — no test exercises it directly · 1 uncovered — no test executes this file

src/flask/app.py

0.72kill rate, 95% interval 0.57–0.84 (n=40, duplicates counted)
29 of 40caught by the project's tests
11got through
10proven missing tests
language
python
status
needs-review
the tests corral wrote
from datetime import timedelta
from flask.app import _make_timedelta
import flask
import pytest
import flask.app
import werkzeug.serving
from flask.app import Flask

def test_corral_make_timedelta_seconds_conversion():
    assert _make_timedelta(None) is None
    assert _make_timedelta(timedelta(seconds=15)) == timedelta(seconds=15)

    result = _make_timedelta(30)
    assert result == timedelta(seconds=30)
    assert result.total_seconds() == 30

def test_app_corral_cli_runner_kwargs():
    app = flask.Flask("test_app_corral")

    runner = app.test_cli_runner(echo_stdin=True)
    assert runner.echo_stdin is True

    class CustomCliRunner:
        def __init__(self, app, custom_arg=None):
            self.app = app
            self.custom_arg = custom_arg

    app.test_cli_runner_class = CustomCliRunner
    custom_runner = app.test_cli_runner(custom_arg="expected_value")
    assert custom_runner.custom_arg == "expected_value"

def test_legacy_subclass_method_signature_receives_app_context():
    with pytest.deprecated_call():

        class LegacyFlask(flask.Flask):
            def dispatch_request(self):
                return super().dispatch_request()

    app = LegacyFlask(__name__)

    @app.route("/")
    def index():
        return "Hello Legacy"

    client = app.test_client()
    rv = client.get("/")
    assert rv.status_code == 200
    assert rv.data == b"Hello Legacy"

def test_app_run_resets_got_first_request_flag(monkeypatch):
    monkeypatch.delenv("FLASK_RUN_FROM_CLI", raising=False)

    def dummy_run_simple(*args, **kwargs):
        pass

    monkeypatch.setattr(werkzeug.serving, "run_simple", dummy_run_simple)

    app = flask.Flask("test_app_corral_reset_flag")
    app._got_first_request = True

    app.run()

    assert app._got_first_request is False

def test_subclass_deprecated_method_signature_warning():
    with pytest.warns(
        DeprecationWarning,
        match="The 'dispatch_request' method now takes 'ctx: AppContext'",
    ):

        class DeprecatedDispatchApp(Flask):
            def dispatch_request(self):
                return "ok"

def test_template_context_processor_precedence():
    app = flask.Flask("test_corral_app")

    @app.context_processor
    def inject_defaults():
        return {"override_me": "default_value", "other": "processor_value"}

    with app.test_request_context("/") as ctx:
        context = {"override_me": "explicit_value"}
        app.update_template_context(ctx, context)
        assert context["override_me"] == "explicit_value"
        assert context["other"] == "processor_value"

def test_make_shell_context_includes_g_corral():
    app = flask.app.Flask("test_app")
    context = app.make_shell_context()
    assert "g" in context
    assert context["g"] is flask.g
    assert context["app"] is app

def test_legacy_subclass_remove_ctx_deprecation_wrapper():
    with pytest.deprecated_call():
        class LegacyFlask(flask.Flask):
            def do_teardown_appcontext(self, exc):
                self.teardown_exc = exc

    app = LegacyFlask("legacy_app")
    ctx = app.app_context()

    app.do_teardown_appcontext(ctx, None)
    assert hasattr(app, "teardown_exc")
    assert app.teardown_exc is None

def test_get_send_file_max_age_timedelta_corral():
    app = flask.Flask("test_app")
    app.config["SEND_FILE_MAX_AGE_DEFAULT"] = timedelta(seconds=3600)
    assert app.get_send_file_max_age("foo.txt") == 3600

def test_open_instance_resource_binary_mode_corral(tmp_path):
    app = flask.Flask("test_app", instance_path=str(tmp_path))
    test_file = tmp_path / "test.bin"
    test_file.write_bytes(b"corral_test_bytes")

    with app.open_instance_resource("test.bin", "rb") as f:
        content = f.read()

    assert content == b"corral_test_bytes"

The faults that got through

A proven fault was caught by a test corral wrote and ran; an unproven one was not, so it may be a missing test or a fault no test can see.

s0/m1 · line 73 proven

- return timedelta(seconds=value)
+ return timedelta(minutes=value)

s5/m1 · line 87 proven

- if args and isinstance(args[0], AppContext):
+ if args and not isinstance(args[0], AppContext):

s2/m1 · line 99 proven

-     args = (app_ctx._get_current_object(),)
- elif not isinstance(args[0], AppContext):
-     args = (app_ctx._get_current_object(), *args)
+     args = (None,)
+ elif not isinstance(args[0], AppContext):
+     args = (None, *args)

s3/m1 · line 276 proven

- if method is base_method:
+ if method is not base_method:

s6/m4 · line 387 proven

- return int(value.total_seconds())
+ return int(value.total_seconds()) + 1

s6/m5 · line 464 proven

- if "b" in mode:
+ if "b" not in mode:

s3/m4 · line 618 proven

- context.update(orig_ctx)
+ pass

s3/m5 · line 627 proven

- rv = {"app": self, "g": g}
+ rv = {"app": self}

s2/m3 · line 747 proven

- self._got_first_request = False
+ self._got_first_request = True

s0/m2 · line 825 proven

- return cls(self, **kwargs)  # type: ignore
+ return cls(self)  # type: ignore

s4/m5 · line 1557 unproven

- builder.close()
+ pass