Skip to content

Test isolation: integration conftest leaks KALSHI_DEMO into unit from_env tests (4 full-suite failures) #445

Closed

Description

@TexasCoding

Summary

Four unit tests fail in the full pytest tests/ run but pass in isolation:

tests/test_client.py::TestKalshiClientFromEnv::test_from_env_demo_flag
tests/test_client.py::TestKalshiClientFromEnv::test_from_env_base_url_override
tests/test_async_client.py::TestAsyncKalshiClientFromEnv::test_from_env_demo_flag
tests/test_async_client.py::TestAsyncKalshiClientFromEnv::test_from_env_base_url_override

This is pre-existing (reproduces on main, independent of #443/PR #444) and is an environment-variable test-isolation leak.

Root cause

tests/integration/conftest.py has a session-scoped autouse fixture that does:

if "KALSHI_DEMO" not in os.environ:
    _monkeypatch_session.setenv("KALSHI_DEMO", "true")

_monkeypatch_session is a session-scoped MonkeyPatch, so it only undoes at session end — not between tests. Once the first test under tests/integration/ triggers fixture setup (the integration tests pytest.skip() in their bodies, but autouse fixtures still set up first), KALSHI_DEMO=true is set for the remainder of the session and leaks into later unit tests.

test_from_env_base_url_override sets KALSHI_API_BASE_URL but does not delenv("KALSHI_DEMO"), so from_env sees the leaked KALSHI_DEMO=true alongside an explicit base_url and raises the "Conflicting environment: demo=True together with explicit base_url" error.

Reproduction (deterministic)

uv run pytest tests/integration tests/test_client.py::TestKalshiClientFromEnv \
  tests/test_async_client.py::TestAsyncKalshiClientFromEnv -q -p no:randomly
# -> 4 failed, 8 passed, 313 skipped

Excluding tests/integration makes all four pass.

Suggested fixes (any one)

  1. Make the demo-env autouse fixture function-scoped (or use a fresh MonkeyPatch per test), so KALSHI_DEMO doesn't persist across the session.
  2. Have the TestKalshiClientFromEnv / TestAsyncKalshiClientFromEnv from_env tests monkeypatch.delenv("KALSHI_DEMO", raising=False) (they already delenv KALSHI_API_BASE_URL).
  3. Add a session-end teardown that explicitly restores KALSHI_DEMO.

Option 1 fixes the class of bug (any unit test reading KALSHI_DEMO is currently exposed), so it's preferable.

Activity

  1. TexasCoding commented on Jun 9, 2026

    @TexasCoding
    OwnerAuthor

    Correction + fix incoming (PR #444).

    The leaked variable is KALSHI_PRIVATE_KEY_PATH, not KALSHI_DEMO as I first wrote. The actual failure is:

    kalshi.errors.KalshiAuthError: Both KALSHI_PRIVATE_KEY and KALSHI_PRIVATE_KEY_PATH are set.
    

    Mechanism: tests/integration/conftest.py::_bridge_env_vars (session-scoped autouse) bridges a developer's ambient KALSHI_DEMO_PRIVATE_KEY_PATH → KALSHI_PRIVATE_KEY_PATH for the whole session. test_from_env_demo_flag / test_from_env_base_url_override set KALSHI_PRIVATE_KEY but — unlike their passing siblings (test_from_env_with_pem_string, test_from_env_with_key_path) — never delenv("KALSHI_PRIVATE_KEY_PATH"), so from_env() sees both and raises. (This is why it only surfaces on machines with demo creds exported, including the maintainer's; CI without demo creds wouldn't bridge a path and wouldn't trip it.)

    Fix: make the two non-hermetic tests match their siblings by dropping the ambient PEM path — monkeypatch.delenv("KALSHI_PRIVATE_KEY_PATH", raising=False) in both test_client.py and test_async_client.py. The session-scoped bridge itself is left as-is (session scope is required for the session-scoped integration clients); the right boundary to harden is the unit test's own env, consistent with the rest of the class. Will be closed by PR #444.

  2. added a commit that references this issue on Jun 9, 2026
    f273b49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtestingTest coverage

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions