# src/pytools/typer/utils/get_from_ctx.py
# Standard Library
from typing import Type, TypeVar
# Third Party
import typer
# Core
from pytools.core.get_from_obj import get_from_obj

T = TypeVar("T")


def get_from_ctx(ctx: typer.Context, key: str, typ: Type[T]) -> T:
    """
    Get a value from the context, traversing up parent contexts if needed.
    
    In nested Typer apps, each subapp has its own context. This function
    checks the current context's obj, and if not found, checks parent contexts.
    """
    # Try current context first
    current_ctx = ctx
    while current_ctx is not None:
        if current_ctx.obj is not None:
            try:
                return get_from_obj(current_ctx.obj, key, typ)
            except KeyError:
                # Key not found in this context, try parent
                pass
        # Move to parent context
        current_ctx = getattr(current_ctx, 'parent', None)
    
    # If we get here, the key wasn't found in any context
    raise KeyError(f"Key '{key}' not found in context or any parent context")

