-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disable spinner when using a debugger #93
Comments
Thanks for a thorough issue submission and solution suggestion. I am not friendly with |
No rush, thank you! I'm also happy to take a crack at it if you prefer. Looking at the spinner code in this library, I don't actually see anywhere to put the fix, and perhaps instead we should open an issue with |
Yep, having refreshed my memory on the spinners code, it seems like a That said, I believe I'll see about setting up |
Sorry, got a little bogged down in life-stuff. This issue is not particularly easy to handle considering the layers and layers of abstraction that are required to deal with the terminal in some sort of elegant way that are included in I've researched the option of hacking it on top of With that in mind, I will probably not be able to get to this in a foreseeable future 😢 Nonetheless, I'll leave the issue open in case anyone else would like to have a crack at it in a meantime. |
Wanted to drop my hacky solution to this issue. import sys
import threading
from contextlib import suppress
from dataclasses import dataclass
from threading import Thread
from time import sleep
from typing import ClassVar, Set
from rich.status import Status
@dataclass
class DebuggableStatus:
"""
This class provides a debuggable version of the `Status` class.\\
It automatically detects if a debugger is running and stops the status if it is, or starts the status if it is not.
Attributes:
- status (Status): The underlying status object.
Example:
```python
from rich.status import Status
from p4dt_shared.rich import DebuggableStatus
with DebuggableStatus(Status("Hello, world!")):
breakpoint() # This will now stop the status from updating.
```
"""
_STATUSES: ClassVar[Set[Status]] = set()
_DEBUG_DETECTION_THREAD: ClassVar[Thread] = None
status: Status
def __post_init__(self):
"""Adds the status to the class's list of statuses and starts the debug detection thread when required."""
DebuggableStatus._STATUSES.add(self.status)
if DebuggableStatus._DEBUG_DETECTION_THREAD is None or not DebuggableStatus._DEBUG_DETECTION_THREAD.is_alive():
DebuggableStatus._DEBUG_DETECTION_THREAD = Thread(target=DebuggableStatus.detect_debug)
DebuggableStatus._DEBUG_DETECTION_THREAD.start()
@staticmethod
def detect_debug():
"""
Detects if a debugger is running and stops or starts the statuses accordingly.
Will run indefinitely until all statuses are closed.
"""
def is_debugger_running():
for thread in threading.enumerate():
if thread is threading.current_thread():
continue
frame = sys._current_frames().get(thread.ident, None)
while frame:
if frame.f_code.co_name == 'interaction':
return True
frame = frame.f_back
return False
while len(DebuggableStatus._STATUSES):
if is_debugger_running():
for status in DebuggableStatus._STATUSES:
status.stop()
else:
for status in DebuggableStatus._STATUSES:
status.start()
sleep(1)
def close(self):
"""Closes the status and removes it from the class's list of statuses."""
with suppress(KeyError):
DebuggableStatus._STATUSES.remove(self.status)
def __enter__(self) -> Status:
"""Enters the context and returns the underlying status object."""
return self.status.__enter__()
def __exit__(self, exc_type, exc_val, exc_tb):
"""Exits the context and calls the __exit__ method of the underlying status object."""
self.close()
return self.status.__exit__(exc_type, exc_val, exc_tb) Usage: console = Console()
with DebuggableStatus(console.status('Running...')):
breakpoint() |
When using a debugging breakpoint when a spinner is running, the text entered in the debugger is continually obscured, while the spinner remains. This means that when debugging, I need to either:
spinner.stop()
when the debugger first comes upMinimum code to reproduce:
This could potentially be fixed by checking for
each time the spinner cycles, and stopping the spinner if that's the case.
The text was updated successfully, but these errors were encountered: