Doramagic Project Pack · Human Manual

kgb

Python function spy support for unit tests

Overview and Quick Start

Related topics: Core Architecture: SpyAgency, FunctionSpy, and SpyCall, Spy Operations and Assertions

Section Related Pages

Continue reading this section for the full explanation and source context.

Section 1. Manual SpyAgency instance

Continue reading this section for the full explanation and source context.

Section 2. Mixin with unittest

Continue reading this section for the full explanation and source context.

Section 3. Pytest fixture

Continue reading this section for the full explanation and source context.

Related topics: Core Architecture: SpyAgency, FunctionSpy, and SpyCall, Spy Operations and Assertions

Overview and Quick Start

Introduction

kgb is a Python function-spying library used to intercept calls to functions, methods, and classmethods in unit tests. It captures arguments, return values, and raised exceptions for later inspection, while still allowing the original implementation to be invoked or replaced with a fake. The library is maintained by Beanbag Inc. and is used in projects such as Review Board, Djblets, and Django Evolution. Source: README.rst

The package's public surface is small and focused. The top-level module re-exports the agency, the standalone context manager, and a set of spy operation helpers used to script complex return/raise behavior:

# Source: kgb/__init__.py
__all__ = [
    'SpyAgency',
    'SpyOpMatchAny',
    'SpyOpMatchInOrder',
    'SpyOpRaise',
    'SpyOpRaiseInOrder',
    'SpyOpReturn',
    'SpyOpReturnInOrder',
    'spy_on',
    ...
]

Source: kgb/__init__.py

The current development version is 7.3.1 alpha, with version 7.3 being the most recent stable release line that added Python 3.14 support and a SpyAgency.get_spy() helper. Source: kgb/__init__.py, NEWS.rst

Installation and Python Compatibility

Installation is a single pip command:

$ pip install kgb

Source: README.rst

kgb supports both CPython and PyPy. Version 7.0 dropped Python 2.6, 3.4, and 3.5. Subsequent releases added support for newer interpreters, as summarized below.

ReleaseNotable Change
7.0Dropped legacy Python; introduced pytest plugin and snake_case assertions.
7.1Added Python 3.11 support.
7.1.1Packaged the LICENSE file.
7.2Added Python 3.13 support; fixed related code-generation crashes.
7.3Added Python 3.14 support and SpyAgency.get_spy().

Source: NEWS.rst

The README mentions support for "Python 2.7 and 3.6 through 3.11" in its original text, but the more recent NEWS.rst indicates the project has been updated for 3.13 and 3.14. Source: README.rst, NEWS.rst

Core Architecture

At a high level, kgb works by replacing a target function's code object with a generated forwarder that records each call before delegating either to the original function or to a user-supplied fake. The replacement is set up by FunctionSpy and managed by SpyAgency.

flowchart LR
    Caller[Caller code] --> Spy["Replaced function\n(FunctionSpy forwarder)"]
    Spy -->|records args| Calls[(Call history)]
    Spy -->|call_original=True| Original[Original function]
    Spy -->|call_fake=fn| Fake[User fake]
    Spy -->|spy_op chain| Ops["SpyOpReturn / SpyOpRaise / SpyOpMatchAny"]
    Agency[SpyAgency] -->|tracks| Spy
    Agency -->|unspy_all| Spy

The forwarder is generated from the spied function's signature, which is captured by FunctionSig (a BaseFunctionSig subclass). Python 3 uses FunctionSigPy3 and relies on inspect.Signature to enumerate parameters, including positional-only and keyword-only arguments. Source: kgb/signature.py

On Python 3.11 and newer, kgb also mirrors co_flags bits for generators, coroutines, and async generators from the original code object onto the replacement. This avoids DeprecationWarning messages that the interpreter would otherwise emit. Source: kgb/spies.py

The SpyAgency class holds a set of registered spies and exposes lifecycle methods. When mixed into a unittest.TestCase, its tearDown automatically calls unspy_all, ensuring spies do not leak between tests. Source: kgb/agency.py

Quick Start Examples

kgb supports four primary usage patterns. All of them revolve around spy_on.

1. Manual `SpyAgency` instance

The most explicit form creates an agency, registers a spy, and queries it:

from kgb import SpyAgency

def test_mind_control_device():
    mcd = MindControlDevice()
    agency = SpyAgency()
    agency.spy_on(mcd.assassinate, call_fake=give_hugs)
    ...

Source: README.rst

2. Mixin with `unittest`

SpyAgency can be combined with a test base class. Its tearDown cleans up automatically:

import unittest
from kgb import SpyAgency

class TopSecretTests(SpyAgency, unittest.TestCase):
    def test_doomsday_device(self):
        dd = DoomsdayDevice()

        @self.spy_for(dd.kaboom)
        def _save_world(*args, **kwargs):
            print('Sprinkles and ponies!')

        dd.kaboom()

Source: README.rst, kgb/agency.py

3. Pytest fixture

When kgb is installed, it registers a pytest plugin. The spy_agency fixture yields a fresh agency and calls unspy_all on teardown:

def test_doomsday_device(spy_agency):
    dd = DoomsdayDevice()

    @spy_agency.spy_for(dd.kaboom)
    def _save_world(*args, **kwargs):
        print('Sprinkles and ponies!')

    dd.kaboom()

Source: kgb/pytest_plugin.py, README.rst

4. Standalone context manager

For one-off spies, the top-level spy_on is usable as a context manager without instantiating an agency:

from kgb import spy_on

def test_the_bomb():
    bomb = Bomb()
    with spy_on(bomb.explode, call_original=False):
        bomb.explode()  # Won't actually explode.

Source: README.rst

Common Operations and Assertions

Once a spy is in place, you can inspect calls, assert behavior, reset history, and invoke the original implementation:

result = obj.function.call_original('foo', bar='baz')
obj.function.reset_calls()

Source: README.rst

SpyAgency exposes camelCase assertion methods (e.g., assertSpyCalledWith, assertSpyRaised) and, since 7.0, snake_case aliases (e.g., assert_spy_called_with). Source: kgb/agency.py, NEWS.rst

When a spy cannot be mixed in, the same assertions are available as free functions in kgb.asserts, which internally uses a module-level SpyAgency. Source: kgb/asserts.py

A common source of confusion is reusing the same spy across multiple test invocations (e.g., from ddt-driven parameter expansion). Re-applying spy_on to an already-spied function raises ExistingSpyError; the cure is to call unspy_all (or the per-spy unspy()) between test iterations. Source: kgb/errors.py, kgb/agency.py

See Also

  • FunctionSpy and Call Inspection — Deep dive into FunctionSpy and SpyCall records.
  • Advanced Operations: SpyOp* Classes — Scripting multi-call returns and raises.
  • Changelog (NEWS.rst) — Version history and compatibility notes.

Source: https://github.com/beanbaginc/kgb / Human Manual

Core Architecture: SpyAgency, FunctionSpy, and SpyCall

Related topics: Overview and Quick Start, Spy Operations and Assertions

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Overview and Quick Start, Spy Operations and Assertions

Core Architecture: SpyAgency, FunctionSpy, and SpyCall

Overview

kgb is a function-spying library for Python unit tests. At its heart, three classes cooperate to intercept calls to a target function, record those calls, and assert on them later. SpyAgency is the lifecycle manager, FunctionSpy is the runtime interceptor that replaces the target's code, and SpyCall is the per-invocation recorder. Around them, a signature-introspection layer adapts to differences between CPython versions, and two entry points (spy_on context manager and the spy_agency pytest fixture) make the system ergonomic in both unittest and pytest suites.

flowchart LR
    User[Test Code] -->|spy_on / @spy_for| Agency[SpyAgency]
    Agency -->|creates & tracks| Spy[FunctionSpy]
    Spy -->|replaces __code__| Target[(Target Function)]
    Target -->|on call| Spy
    Spy -->|appends| Call[SpyCall]
    Spy -->|may invoke| Original[Original callable]
    Spy -->|may invoke| Op[SpyOp* / call_fake]
    Call -->|stored in| Spy
    Agency -->|assert_*| Call

SpyAgency — The Coordinator

SpyAgency lives in kgb/agency.py. It owns a set of every FunctionSpy it has ever created and exposes two kinds of behavior: lifecycle (spy_on, spy_for, unspy, unspy_all) and assertions (assertSpyCalled, assertSpyCalledWith, assertSpyLastReturned, etc.). Source: kgb/agency.py:1-60.

The class is designed to be either instantiated directly or mixed in to a unittest.TestCase. The constructor calls super().__init__(*args, **kwargs), and a tearDown() method calls self.unspy_all() automatically — this is the mechanism that prevents the "spies leaking between tests" pitfall that users hit when running data-driven tests such as DDT. Source: kgb/agency.py:18-50. As reported in issue #5, failing to unspy causes ExistingSpyError on subsequent runs; the agency pattern solves this by tying cleanup to the test case lifecycle.

From kgb 7.0 onward, SpyAgency also exposes assert_spy_called–style snake_case aliases and a spy_agency pytest fixture is provided in kgb/pytest_plugin.py, which yields a fresh SpyAgency and guarantees unspy_all() on teardown. Source: kgb/pytest_plugin.py:1-30; NEWS.rst.

FunctionSpy — The Runtime Interceptor

FunctionSpy is defined in kgb/spies.py. A single instance represents one spied function: it holds the original callable, the current fake (call_fake) or planned operation (op), the calls list of SpyCall records, and metadata about the function's owner and type. Source: kgb/spies.py.

The most invasive part of kgb is the _build_spy_code path: kgb synthesizes a new Python code object that impersonates the original function and forwards every call back into _kgb_forwarding_call, which delegates to the spy's handle_call(). To support closures, the synthesized function explicitly references each co_freevars name; to support the new exception state machinery in Python 3.11+, the code uses code.replace(...) rather than building a new CodeType. Source: kgb/spies.py:build_spy_code. This is precisely the area that had to be repaired for Python 3.13 compatibility in kgb 7.2 — see issue #11, where setting co_freevars / co_cellvars on a replaced code object caused interpreter crashes. Source: NEWS.rst:kgb 7.2.

FunctionSpy is the only class that knows how to record a call. When the spied function is invoked, it constructs a SpyCall, normalizes the arguments (stripping the bound self for methods), executes the configured plan — original callable, call_fake, or a BaseSpyOperation subclass — and stores the resulting return value or exception on the SpyCall. The operation abstraction lives in kgb/ops.py and ships with SpyOpReturn, SpyOpRaise, SpyOpMatchAny, and ordered variants.

SpyCall — The Per-Invocation Recorder

SpyCall is defined in kgb/calls.py and is created once per invocation. It stores args, kwargs, return_value, and exception, and provides boolean predicates (called_with, returned, raised, raised_with_message) plus last_* helpers that delegate to the most recent call in the owning spy's list. Source: kgb/calls.py:1-80.

This design means that all call-related state is immutable per call and append-only on the spy. Resetting state is a single operation: FunctionSpy.reset_calls() empties the list. Source: kgb/spies.py. Returning multiple different values across calls — the "double agent" pattern from issue #3 — is therefore supported by reading calls[0].return_value, calls[1].return_value, etc., rather than by overloading the spy itself.

Supporting Layer: Signature Introspection and Entry Points

Because the __code__ replacement must match the target function's argument shape exactly, kgb wraps every intercepted function in a FunctionSig introspector. The base class BaseFunctionSig and the Python 3 implementation FunctionSigPy3 are defined in kgb/signature.py. They expose attributes such as defined_func, has_getter, has_setter, is_slippery, and all_arg_names, and provide format_arg_spec() for code generation. Source: kgb/signature.py:1-120. Version-specific subclasses exist so that positional-only arguments, __wrapped__ unwrapping, and the __code__.replace API all work consistently.

Two user-facing entry points wire this machinery together:

  • The spy_on context manager in kgb/contextmanagers.py creates a throwaway SpyAgency, yields the new FunctionSpy, and calls unspy() on exit. This is the right tool for ad-hoc, single-test spies.
  • The spy_agency pytest fixture in kgb/pytest_plugin.py is the idiomatic option for pytest users and was introduced in kgb 7.0.

The package's public surface is centralized in kgb/__init__.py, which re-exports SpyAgency, spy_on, and the SpyOp* operation classes, and defines VERSION = (7, 3, 1, 'alpha', 0, False). Source: kgb/__init__.py:1-30.

Common Failure Modes

A few issues recur in the community and map directly onto this architecture:

SymptomRoot cause in architectureSource
ExistingSpyError on second test (DDT)SpyAgency.unspy_all() not run between iterationsissue #5
Crash on Python 3.13 b2 with closures_build_spy_code mutated co_freevars / co_cellvars incorrectlyissue #11
Pytest fails on Python 3.10/3.11assertRaisesRegexp alias removal and bytecode changesissues #8, #9, #12
test_spy_on_generator fails on PyPy3.11__code__ mutation interacts with PyPy's JIT/object modelissue #13

In every case, the underlying fix lives in either FunctionSig (introspection), _build_spy_code (interception), or the lifecycle methods on SpyAgency.

See Also

  • Getting Started: Installing and Importing kgb
  • Spies in Depth: call_fake, call_original, and SpyOp*
  • pytest Integration: The spy_agency Fixture
  • Python Version Compatibility Matrix

Source: https://github.com/beanbaginc/kgb / Human Manual

Spy Operations and Assertions

Related topics: Core Architecture: SpyAgency, FunctionSpy, and SpyCall, Testing Framework Integration and Platform Compatibility

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Core Architecture: SpyAgency, FunctionSpy, and SpyCall, Testing Framework Integration and Platform Compatibility

Spy Operations and Assertions

kgb provides two complementary mechanisms for shaping what a spy *does* when it intercepts a call and what you *check* afterward. Spy operations (registered via op=) describe a planned sequence of behaviors — return values, raised exceptions, or matching rules — for each invocation of the spied function. Assertions are the read-side companion, letting a test verify that a spy (or a single SpyCall) was called, what it received, what it returned, and what it raised. Together they let a test author replace real side effects and then verify the interactions deterministically.

1. Spy Operations (`op=`)

A spy operation is an object that decides how to handle each intercepted call. They are registered when a spy is set up, by passing an op= argument to spy_on() or @spy_for(). The base class lives in kgb/ops.py and exposes a handle_call(spy_call, *args, **kwargs) method that returns a value or raises an exception.

The built-in operations, re-exported from kgb/__init__.py, are:

ClassBehavior
SpyOpReturn(value)Always return a fixed value.
SpyOpRaise(exception)Always raise a fixed exception (or exception instance).
SpyOpReturnInOrder([...])Return successive values across calls.
SpyOpRaiseInOrder([...])Raise successive exceptions across calls.
SpyOpMatchInOrder([...])Match expected calls (args/kwargs) in order; raise UnexpectedCallError on mismatch.
SpyOpMatchAny([...])Match expected calls in any order; raise UnexpectedCallError on mismatch.

Each Match* entry is a dict that may itself include an inner op key, allowing nested reusable rule sets. Example from the release notes:

spy_on(lockbox.enter_code, op=kgb.SpyOpMatchInOrder([
    {
        'args': (42, 42, 42, 42, 42, 42),
        'op': kgb.SpyOpRaise(Kaboom()),
        'call_original': True,
    },
]))

BaseSpyOperation.setup() returns a fake function the spy will install as a forwarding trampoline, so the spy framework can treat any operation uniformly (kgb/ops.py). When a call fails to match, UnexpectedCallError is raised — and since kgb 7, the error message includes the call that was actually made, simplifying debugging.

2. Recording Calls: `FunctionSpy` and `SpyCall`

Every intercepted invocation is recorded by the spy as a SpyCall, accessible from function.calls (kgb/calls.py). A SpyCall stores args, kwargs, return_value, and exception, and exposes predicates such as called_with(...), returned(...), raised(...), and raised_with_message(...). These predicates are the building blocks used by all higher-level assertions.

The spy itself is the actual function object once spying is active — meaning code that calls obj.function is transparently rerouted through kgb's forwarding call (kgb/spies.py). For type-checker-friendly access, kgb 7.3 added SpyAgency.get_spy(), which returns the FunctionSpy for a given callable without relying on the replaced function object.

3. Assertion Surface: `SpyAgency`, `kgb.asserts`, and the pytest fixture

The primary assertion API lives on SpyAgency in kgb/agency.py. Both unittest-style (camelCase, e.g., assertSpyCalledWith) and snake_case (assert_spy_called_with) forms are provided. When SpyAgency is mixed into a unittest.TestCase, its tearDown() automatically unspies everything (kgb/agency.py).

For non-unittest frameworks, every assert_* method is also re-exported as a standalone function in kgb/asserts.py, backed by a module-level SpyAgency instance. The module loops over vars(SpyAgency) and dynamically attaches every method whose name starts with assert_ to its __all__.

For pytest users, kgb/pytest_plugin.py provides a spy_agency fixture that yields a fresh SpyAgency and calls unspy_all() on teardown. The same assert_* methods are available on this fixture object.

A representative subset of the available assertions:

AssertionChecks
assert_has_spy(spy) / assert_spy_called(spy)The function was ever called.
assert_spy_not_called(spy)The function was never called.
assert_spy_call_count(spy, n)The function was called exactly n times.
assert_spy_called_with(spy, *a, **kw)Any call matched the given arguments.
assert_spy_last_called_with(spy, *a, **kw)The most recent call matched.
assert_spy_called_once_with(spy, *a, **kw)Exactly one call matched.
assert_spy_raised(spy, exc) / assert_spy_last_raised(...)A call (or the last one) raised an exception class.
assert_spy_raised_message(spy, exc, msg) / assert_spy_last_raised_message(...)A call (or the last) raised with a matching message.
assert_spy_returned(spy, value) / assert_spy_last_returned(...)A call (or the last) returned a given value.

Most assertions accept either a callable or a FunctionSpy; some (called_with, returned, raised) also accept an individual SpyCall, which is useful when asserting on a specific recorded call rather than the whole history (kgb/calls.py).

4. Lifecycle and Common Failure Modes

Spies are typically created via one of four patterns described in the README: instantiating SpyAgency, mixing it into a test class, using @spy_for as a decorator (kgb 6+), or the standalone spy_on context manager in kgb/contextmanagers.py. The context-manager form creates a throwaway SpyAgency, spies for the duration of the with block, and then calls unspy().

A few failure modes worth noting:

  • Double-spying. Attempting to spy on a function that is already spied raises ExistingSpyError. This commonly surfaces when using parameterized test runners (e.g., DDT) that re-enter the same spy across iterations; the fix is to ensure the agency is torn down or unspy() is called between runs.
  • Decorator-wrapped functions. Some decorators do not preserve __name__, which can confuse kgb's signature handling. kgb 7 introduced a func_name= argument to spy_on() so callers can declare the original function name explicitly.
  • Mismatch errors. When using SpyOpMatchInOrder / SpyOpMatchAny, any unexpected call raises UnexpectedCallError; since kgb 7 the message lists the actual call that triggered the failure.
  • Generator functions. Spying on generator functions is supported, but tests must be aware that the spy wraps the generator object. A known issue exists on PyPy 3.11 where one specific generator-related test fails; the upstream fix tracks changes in how PyPy builds and executes generator bytecodes.

For deeper coverage of the bytecode-injection mechanics that make spy_on() transparent to callers, see the FunctionSig and _build_spy_code helpers in kgb/spies.py.

See Also

  • kgb README on PyPI — installation, quick start, and high-level examples.
  • kgb 7.2 release notes — Python 3.13 compatibility fixes for function composition and execution.
  • kgb 7.3 release notes — Python 3.14 support, SpyAgency.get_spy(), generator DeprecationWarning fix.
  • Review Board project — kgb's primary production user, providing real-world examples of spy operations and assertions.

Source: https://github.com/beanbaginc/kgb / Human Manual

Testing Framework Integration and Platform Compatibility

Related topics: Overview and Quick Start, Spy Operations and Assertions

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Overview and Quick Start, Spy Operations and Assertions

Testing Framework Integration and Platform Compatibility

kgb integrates with the major Python testing ecosystems (pytest, unittest, and standalone scripts) and supports a broad matrix of Python interpreters (CPython 2.7, 3.6 through 3.14, and PyPy). Because kgb's core mechanism is replacing the __code__ attribute of a function, every interpreter release can shift the surface it relies on, so platform compatibility and framework integration are first-class concerns of the project.

Integration with pytest

kgb ships as a native pytest plugin that exposes a spy_agency fixture. When the plugin is loaded, any pytest test function can request the fixture and receive a ready-to-use SpyAgency instance. The fixture guarantees that every spy registered during the test is torn down automatically.

Source: kgb/pytest_plugin.py:9-22

@pytest.fixture
def spy_agency():
    agency = SpyAgency()
    try:
        yield agency
    finally:
        agency.unspy_all()

The fixture pattern means tests do not need to instantiate SpyAgency manually and do not need to remember to call unspy_all() in cleanup. The repository's conftest.py configures pytest by ignoring Python-3-only test files when running under Python 2, so the same suite can be exercised on both interpreter families without manual exclusion.

Source: conftest.py:5-10

Integration with unittest and Standalone Use

For projects using unittest, SpyAgency is designed as a mixin that combines with any TestCase subclass. Its __init__ forwards positional and keyword arguments through super(), allowing it to compose cleanly with other mixins such as django.test.TestCase.

Source: kgb/agency.py:33-49

When mixed into a TestCase, the agency's tearDown() calls super().tearDown() and then self.unspy_all(), ensuring every spy registered during the test is removed before the next test runs. This prevents cross-test leakage and avoids the ExistingSpyError that arises when the same function is spied twice in the same run (see Issue #5).

For lightweight, one-shot spying without managing an agency, kgb provides the spy_on context manager. It instantiates a private SpyAgency, registers a spy, yields it to the caller, and calls unspy() from the finally block.

Source: kgb/contextmanagers.py:11-31

from kgb import spy_on

with spy_on(bomb.explode, call_original=False):
    bomb.explode()

Python Version Compatibility

kgb must function across many Python versions because bytecode replacement interacts with interpreter internals that change between releases. Compatibility is handled through version-specific introspection classes and a top-level factory exported as FunctionSig.

Source: kgb/signature.py:122-130

if sys.version_info[0] == 2:
    FunctionSig = FunctionSigPy2
elif sys.version_info[0] == 3:
    FunctionSig = FunctionSigPy3
else:
    raise Exception('Unsupported Python version')

FunctionSigPy2 uses the legacy inspect.formatargspec() API to reconstruct argument lists, while FunctionSigPy3 walks inspect.Signature.parameters and preserves positional-only, keyword-only, *args, and **kwargs parameter kinds. Common helpers like get_defined_attr_value and is_attr_defined_on_ancestor live in kgb/utils.py so that signature and spy logic can share a stable descriptor-walking implementation across interpreter versions.

Source: kgb/utils.py:12-39

The release history records the supported Python matrix. kgb 7.0 dropped Python 2.6, 3.4, and 3.5. kgb 7.1 added Python 3.11, kgb 7.2 added Python 3.13 (with fixes for closure-related crashes), and kgb 7.3 added Python 3.14 while also shipping the LICENSE file for downstream packaging.

Source: NEWS.rst:1-30

Platform Support Matrix

The table below summarizes the integration modes kgb advertises and the lifecycle each one provides.

Integration ModeMechanismCleanup HookAvailable Since
pytest fixturespy_agency fixturefinally: agency.unspy_all()kgb 7.0
unittest mixinclass Foo(SpyAgency, TestCase)SpyAgency.tearDown()kgb 0.5
Context managerwith spy_on(...)finally: spy.unspy()kgb 0.5
Standalone assertsfrom kgb.asserts import ...n/a (read-only helpers)kgb 7.0

For interpreter coverage, kgb 7.3 explicitly supports CPython 2.7 and 3.6 through 3.14, plus PyPy. The internal sys.version_info switch in signature.py still gates Py2 vs Py3 paths, while Python 3 minor-version differences (such as positional-only parameters introduced in 3.8) are absorbed inside FunctionSigPy3.

Source: kgb/signature.py:122-130

Common Compatibility Pitfalls

Three patterns recur in community reports:

  1. PyPy interpreter quirks — bytecode replacement behaves differently on PyPy, and test_spy_on_generator remains a known failure on PyPy 3.11 (Issue #13). CPython support is broad, but PyPy compatibility is best-effort.
  2. Removed unittest aliasesassertRaisesRegexp was deprecated in Python 3.2 and removed in 3.12 (Issue #12). Test code using the deprecated alias must migrate to assertRaisesRegex.
  3. Closure capturing under Python 3.13 beta — spies that captured closures crashed on Python 3.13 beta builds (Issue #11). This was fixed in kgb 7.2 by adapting to the new function composition model.

Source: GitHub Issues #11, #12, #13

The README also documents that kgb can be mixed into any TestCase subclass and combined with frameworks such as asynctest for asynchronous tests (Issue #4), making it a drop-in choice across most Python testing styles.

Source: README.rst

See Also

Source: https://github.com/beanbaginc/kgb / Human Manual

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

high Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

high Configuration risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

Doramagic Pitfall Log

Found 12 structured pitfall item(s), including 2 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

1. Installation risk: Installation risk requires verification

  • Severity: high
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/beanbaginc/kgb/issues/13

2. Configuration risk: Configuration risk requires verification

  • Severity: high
  • Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/beanbaginc/kgb/issues/11

3. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/beanbaginc/kgb/issues/8

4. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/beanbaginc/kgb/issues/9

5. Capability evidence risk: Capability evidence risk requires verification

  • Severity: medium
  • Finding: README/documentation is current enough for a first validation pass.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: capability.assumptions | github_repo:10215090 | https://github.com/beanbaginc/kgb

6. Runtime risk: Runtime risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a runtime risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/beanbaginc/kgb/issues/5

7. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/beanbaginc/kgb/issues/12

8. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | github_repo:10215090 | https://github.com/beanbaginc/kgb

9. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: downstream_validation.risk_items | github_repo:10215090 | https://github.com/beanbaginc/kgb

10. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: risks.scoring_risks | github_repo:10215090 | https://github.com/beanbaginc/kgb

11. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: issue_or_pr_quality=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | github_repo:10215090 | https://github.com/beanbaginc/kgb

12. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: release_recency=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | github_repo:10215090 | https://github.com/beanbaginc/kgb

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 12

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using kgb with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence