Add `_maybe_open_repl_fixture()`
Factoring the (basically duplicate) content from both use spots into a common `@cm` which delivers a `bool` signalling whether the REPL should be engaged. Fixes a lingering bug with `nullcontext()` calling btw..repl_fixture
							parent
							
								
									ba97a8ddc5
								
							
						
					
					
						commit
						4f6a9c62c6
					
				| 
						 | 
					@ -43,9 +43,10 @@ import threading
 | 
				
			||||||
import traceback
 | 
					import traceback
 | 
				
			||||||
from typing import (
 | 
					from typing import (
 | 
				
			||||||
    Any,
 | 
					    Any,
 | 
				
			||||||
    Callable,
 | 
					 | 
				
			||||||
    AsyncIterator,
 | 
					    AsyncIterator,
 | 
				
			||||||
    AsyncGenerator,
 | 
					    AsyncGenerator,
 | 
				
			||||||
 | 
					    Callable,
 | 
				
			||||||
 | 
					    Iterator,
 | 
				
			||||||
    Sequence,
 | 
					    Sequence,
 | 
				
			||||||
    Type,
 | 
					    Type,
 | 
				
			||||||
    TypeAlias,
 | 
					    TypeAlias,
 | 
				
			||||||
| 
						 | 
					@ -1850,27 +1851,12 @@ async def _pause(
 | 
				
			||||||
        # TODO, support @acm?
 | 
					        # TODO, support @acm?
 | 
				
			||||||
        # -[ ] what about a return-proto for determining
 | 
					        # -[ ] what about a return-proto for determining
 | 
				
			||||||
        #     whether the REPL should be allowed to enage?
 | 
					        #     whether the REPL should be allowed to enage?
 | 
				
			||||||
        nonlocal repl_fixture
 | 
					        # nonlocal repl_fixture
 | 
				
			||||||
        if not (
 | 
					 | 
				
			||||||
            repl_fixture
 | 
					 | 
				
			||||||
            or
 | 
					 | 
				
			||||||
            (rt_repl_fixture := _state._runtime_vars.get('repl_fixture'))
 | 
					 | 
				
			||||||
        ):
 | 
					 | 
				
			||||||
            repl_fixture = nullcontext(
 | 
					 | 
				
			||||||
                enter_result=True,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        _repl_fixture = repl_fixture or rt_repl_fixture
 | 
					        with _maybe_open_repl_fixture(
 | 
				
			||||||
        with _repl_fixture(maybe_bxerr=None) as enter_repl:
 | 
					            repl_fixture=repl_fixture,
 | 
				
			||||||
 | 
					        ) as enter_repl:
 | 
				
			||||||
            # XXX when the fixture doesn't allow it, skip
 | 
					 | 
				
			||||||
            # the crash-handler REPL and raise now!
 | 
					 | 
				
			||||||
            if not enter_repl:
 | 
					            if not enter_repl:
 | 
				
			||||||
                log.pdb(
 | 
					 | 
				
			||||||
                    f'pdbp-REPL blocked by a `repl_fixture()` which yielded `False` !\n'
 | 
					 | 
				
			||||||
                    f'repl_fixture: {repl_fixture}\n'
 | 
					 | 
				
			||||||
                    f'rt_repl_fixture: {rt_repl_fixture}\n'
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            debug_func_name: str = (
 | 
					            debug_func_name: str = (
 | 
				
			||||||
| 
						 | 
					@ -2926,6 +2912,60 @@ _crash_msg: str = (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# TODO, support @acm?
 | 
				
			||||||
 | 
					# -[ ] what about a return-proto for determining
 | 
				
			||||||
 | 
					#     whether the REPL should be allowed to enage?
 | 
				
			||||||
 | 
					# -[ ] consider factoring this `_repl_fixture` block into
 | 
				
			||||||
 | 
					#    a common @cm somehow so it can be repurposed both here and
 | 
				
			||||||
 | 
					#    in `._pause()`??
 | 
				
			||||||
 | 
					#   -[ ] we could also use the `ContextDecorator`-type in that
 | 
				
			||||||
 | 
					#       case to simply decorate the `_enter_repl_sync()` closure?
 | 
				
			||||||
 | 
					#     |_https://docs.python.org/3/library/contextlib.html#using-a-context-manager-as-a-function-decorator
 | 
				
			||||||
 | 
					@cm
 | 
				
			||||||
 | 
					def _maybe_open_repl_fixture(
 | 
				
			||||||
 | 
					    repl_fixture: (
 | 
				
			||||||
 | 
					        AbstractContextManager[bool]
 | 
				
			||||||
 | 
					        |None
 | 
				
			||||||
 | 
					    ) = None,
 | 
				
			||||||
 | 
					    boxed_maybe_exc: BoxedMaybeException|None = None,
 | 
				
			||||||
 | 
					) -> Iterator[bool]:
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    Maybe open a pre/post REPL entry "fixture" `@cm` provided by the
 | 
				
			||||||
 | 
					    user, the caller should use the delivered `bool` to determine
 | 
				
			||||||
 | 
					    whether to engage the `PdbREPL`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    if not (
 | 
				
			||||||
 | 
					        repl_fixture
 | 
				
			||||||
 | 
					        or
 | 
				
			||||||
 | 
					        (rt_repl_fixture := _state._runtime_vars.get('repl_fixture'))
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
 | 
					        _repl_fixture = nullcontext(
 | 
				
			||||||
 | 
					            enter_result=True,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        _repl_fixture = (
 | 
				
			||||||
 | 
					            repl_fixture
 | 
				
			||||||
 | 
					            or
 | 
				
			||||||
 | 
					            rt_repl_fixture
 | 
				
			||||||
 | 
					        )(maybe_bxerr=boxed_maybe_exc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    with _repl_fixture as enter_repl:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # XXX when the fixture doesn't allow it, skip
 | 
				
			||||||
 | 
					        # the crash-handler REPL and raise now!
 | 
				
			||||||
 | 
					        if not enter_repl:
 | 
				
			||||||
 | 
					            log.pdb(
 | 
				
			||||||
 | 
					                f'pdbp-REPL blocked by a `repl_fixture()` which yielded `False` !\n'
 | 
				
			||||||
 | 
					                f'repl_fixture: {repl_fixture}\n'
 | 
				
			||||||
 | 
					                f'rt_repl_fixture: {rt_repl_fixture}\n'
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            yield False  # no don't enter REPL
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        yield True  # yes enter REPL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _post_mortem(
 | 
					def _post_mortem(
 | 
				
			||||||
    repl: PdbREPL,  # normally passed by `_pause()`
 | 
					    repl: PdbREPL,  # normally passed by `_pause()`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2952,40 +2992,11 @@ def _post_mortem(
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    __tracebackhide__: bool = hide_tb
 | 
					    __tracebackhide__: bool = hide_tb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # TODO, support @acm?
 | 
					    with _maybe_open_repl_fixture(
 | 
				
			||||||
    # -[ ] what about a return-proto for determining
 | 
					        repl_fixture=repl_fixture,
 | 
				
			||||||
    #     whether the REPL should be allowed to enage?
 | 
					        boxed_maybe_exc=boxed_maybe_exc,
 | 
				
			||||||
    # -[ ] consider factoring this `_repl_fixture` block into
 | 
					    ) as enter_repl:
 | 
				
			||||||
    #    a common @cm somehow so it can be repurposed both here and
 | 
					 | 
				
			||||||
    #    in `._pause()`??
 | 
					 | 
				
			||||||
    #   -[ ] we could also use the `ContextDecorator`-type in that
 | 
					 | 
				
			||||||
    #       case to simply decorate the `_enter_repl_sync()` closure?
 | 
					 | 
				
			||||||
    #     |_https://docs.python.org/3/library/contextlib.html#using-a-context-manager-as-a-function-decorator
 | 
					 | 
				
			||||||
    if not (
 | 
					 | 
				
			||||||
        repl_fixture
 | 
					 | 
				
			||||||
        or
 | 
					 | 
				
			||||||
        (rt_repl_fixture := _state._runtime_vars.get('repl_fixture'))
 | 
					 | 
				
			||||||
    ):
 | 
					 | 
				
			||||||
        _repl_fixture = nullcontext(
 | 
					 | 
				
			||||||
            enter_result=True,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        _repl_fixture = (
 | 
					 | 
				
			||||||
            repl_fixture
 | 
					 | 
				
			||||||
            or
 | 
					 | 
				
			||||||
            rt_repl_fixture
 | 
					 | 
				
			||||||
        )(maybe_bxerr=boxed_maybe_exc)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    with _repl_fixture as enter_repl:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # XXX when the fixture doesn't allow it, skip
 | 
					 | 
				
			||||||
        # the crash-handler REPL and raise now!
 | 
					 | 
				
			||||||
        if not enter_repl:
 | 
					        if not enter_repl:
 | 
				
			||||||
            log.pdb(
 | 
					 | 
				
			||||||
                f'pdbp-REPL blocked by a `repl_fixture()` which yielded `False` !\n'
 | 
					 | 
				
			||||||
                f'repl_fixture: {repl_fixture}\n'
 | 
					 | 
				
			||||||
                f'rt_repl_fixture: {rt_repl_fixture}\n'
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue