Skip to content

feat: with bigfoot: context manager shorthand (v0.4.1)#3

Merged
elijahr merged 2 commits intomainfrom
elijahr/sandbox-returns-verifier
Mar 6, 2026
Merged

feat: with bigfoot: context manager shorthand (v0.4.1)#3
elijahr merged 2 commits intomainfrom
elijahr/sandbox-returns-verifier

Conversation

@elijahr
Copy link
Copy Markdown
Contributor

@elijahr elijahr commented Mar 6, 2026

Summary

  • Adds _BigfootModule(types.ModuleType) subclass with __enter__/__exit__/__aenter__/__aexit__ and applies it via sys.modules[__name__].__class__ = _BigfootModule
  • with bigfoot: and async with bigfoot: are now shorthand for with bigfoot.sandbox(): / async with bigfoot.sandbox():
  • Both forms return the active StrictVerifier from __enter__, so with bigfoot as v: gives direct verifier access (e.g. for registering custom plugins manually)
  • Uses a threading.local LIFO stack for correct nested sandbox tracking
  • All docs, guides, and README updated to use the new with bigfoot: syntax throughout

Test plan

  • test_bigfoot_module_is_context_manager — sync with bigfoot as v: returns StrictVerifier, mock/assert works inside
  • test_bigfoot_module_is_async_context_manager — async form works identically
  • test_bigfoot_nested_sandboxes_via_with_bigfoot — nested with bigfoot: blocks share the same verifier without interference
  • All 557 existing tests continue to pass

Add module-level context manager support so `with bigfoot:` and
`async with bigfoot:` serve as shorthand for the sandbox() call.
Both forms return the active StrictVerifier from __enter__, enabling
`with bigfoot as v:` for direct verifier access when needed.

Update all documentation, guides, and README to use the new syntax.
Bump version to 0.4.1.
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the usability of the bigfoot library by introducing a more Pythonic and concise context manager syntax. Users can now activate testing sandboxes directly via with bigfoot: or async with bigfoot:, simplifying test code. The change also ensures robust handling of nested contexts and provides direct access to the underlying verifier object for advanced configurations, making the library more flexible and developer-friendly.

Highlights

  • Context Manager Shorthand: Introduced with bigfoot: and async with bigfoot: as a more concise shorthand for with bigfoot.sandbox(): and async with bigfoot.sandbox(): respectively.
  • Direct Verifier Access: Both the new shorthand and the explicit sandbox() context managers now return the active StrictVerifier instance, allowing direct access (e.g., with bigfoot as v:).
  • Nested Sandbox Handling: Implemented a threading.local LIFO stack to correctly manage and track nested with bigfoot: sandbox contexts without interference.
  • Documentation Updates: All relevant documentation, guides, and the README have been updated to reflect and promote the new with bigfoot: syntax.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • CHANGELOG.md
    • Added entry for version 0.4.1, detailing the new with bigfoot: and async with bigfoot: shorthand context managers.
Activity
  • The author elijahr implemented the _BigfootModule subclass to enable module-level context management.
  • The author updated the pyproject.toml to increment the version to 0.4.1.
  • The author updated the README.md and various documentation guides (async, http-plugin, mock-plugin, pytest-integration, quickstart, stateful-plugins, subprocess-plugin, writing-plugins) to reflect the new context manager shorthand.
  • The author added new unit tests to verify the functionality of the bigfoot module as a context manager, covering synchronous, asynchronous, and nested usage.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a convenient shorthand, with bigfoot:, for the sandbox context manager, which is a great enhancement for the library's usability. The implementation is clever, using sys.modules[__name__].__class__ to make the module itself a context manager. The changes are thoroughly documented and well-tested. My feedback includes a minor refactoring suggestion for the core implementation in _BigfootModule to improve code clarity and reduce duplication.

Comment thread src/bigfoot/__init__.py
Comment on lines +389 to +424
class _BigfootModule(types.ModuleType):
"""ModuleType subclass that makes ``bigfoot`` usable as a context manager.

``with bigfoot:`` is equivalent to ``with bigfoot.sandbox():``.
``async with bigfoot:`` is equivalent to ``async with bigfoot.sandbox():``.
Both forms return the active :class:`StrictVerifier` from ``__enter__``.
"""

def __enter__(self) -> StrictVerifier:
cm = sandbox()
stack = _sandbox_stack.__dict__.setdefault("stack", [])
stack.append(cm)
return cm.__enter__()

def __exit__(
self,
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: object,
) -> None:
_sandbox_stack.stack.pop().__exit__(exc_type, exc_val, exc_tb)

async def __aenter__(self) -> StrictVerifier:
cm = sandbox()
stack = _sandbox_stack.__dict__.setdefault("stack", [])
stack.append(cm)
return await cm.__aenter__()

async def __aexit__(
self,
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: object,
) -> None:
await _sandbox_stack.stack.pop().__aexit__(exc_type, exc_val, exc_tb)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The __enter__ and __aenter__ methods contain duplicated logic for creating and pushing the sandbox context manager onto the stack. This can be refactored into a helper method to improve maintainability and reduce code duplication. Additionally, using hasattr to check for the stack's existence is more idiomatic and readable than accessing __dict__ directly.

class _BigfootModule(types.ModuleType):
    """ModuleType subclass that makes ``bigfoot`` usable as a context manager.

    ``with bigfoot:`` is equivalent to ``with bigfoot.sandbox():``.
    ``async with bigfoot:`` is equivalent to ``async with bigfoot.sandbox():``.
    Both forms return the active :class:`StrictVerifier` from ``__enter__``.
    """

    def _push_cm(self) -> SandboxContext:
        """Create a new sandbox context, push it to the thread-local stack, and return it."""
        cm = sandbox()
        if not hasattr(_sandbox_stack, "stack"):
            _sandbox_stack.stack = []
        _sandbox_stack.stack.append(cm)
        return cm

    def __enter__(self) -> StrictVerifier:
        return self._push_cm().__enter__()

    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_val: BaseException | None,
        exc_tb: object,
    ) -> None:
        _sandbox_stack.stack.pop().__exit__(exc_type, exc_val, exc_tb)

    async def __aenter__(self) -> StrictVerifier:
        return await self._push_cm().__aenter__()

    async def __aexit__(
        self,
        exc_type: type[BaseException] | None,
        exc_val: BaseException | None,
        exc_tb: object,
    ) -> None:
        await _sandbox_stack.stack.pop().__aexit__(exc_type, exc_val, exc_tb)

@elijahr elijahr merged commit eb3dfff into main Mar 6, 2026
10 checks passed
@elijahr elijahr deleted the elijahr/sandbox-returns-verifier branch March 6, 2026 00:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant