You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Having issues with printing from another thread seems like a very common issue. In an app I'm writing, everything is using the python logging module, so I had this handler for directing output to poutput or perror based on the record level. But of course any prints would interfere with the prompt. So I changed it like so:
class Shell(cmd2.Cmd):
class LoggingHandler(logging.Handler):
def __init__(self, shell: cmd2.Cmd):
super().__init__()
self._shell = shell
def emit(self, record: logging.LogRecord):
if record.levelno < logging.WARNING:
msg = record.getMessage()
else:
msg = f"[{record.levelname}] {record.getMessage()}"
if threading.current_thread() is threading.main_thread():
self._shell.poutput(msg)
else:
self._shell.async_alert(msg)
But there are two issues with this:
The messages in async_alert do not get piped to poutput or perror; depending on the readline type it might go to stderr directly.
async_alert doesn't work while on the main thread, so I have to check for both conditions and do one or the other.
Couldn't the poutput or perror functions handle the functionality of async_alert() automatically? This is one of the biggest gripes with cmd that I feel like cmd2 could automatically handle.
poutput() and async_alert() have two different purposes.
poutput() writes all output to self.stdout which could be a terminal, a file if redirecting, or even a cmd2.utils.StdSim when capturing output for a cmd2 pyscript. This is mainly used to print or capture the output of commands while they're running.
async_alert() is only for printing alerts to the terminal when the user is sitting at a prompt. It's also capable of dynamically updating prompt to reflect a change in status. Alerts could be any sort of status updates or in your case, logged events. You're supposed to acquire self.terminal_lock before calling it to ensure you're at a prompt. Otherwise async_alert() will raise a RuntimeError if you aren't.
Right, but if you have a terminal application where things are happening in the background, it would make sense to put them above the prompt (whether it's going to stdout or stderr). So the functionality that async_alert() provides WRT moving the prompt would be useful in that context. What I ended up doing is checking the thread and either calling poutput() or async_alert() depending on which thread the message is coming in, but I think it should be possible to handle that logic internally to poutput() or perror() when those streams are going to the same output as the prompt.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Having issues with printing from another thread seems like a very common issue. In an app I'm writing, everything is using the python logging module, so I had this handler for directing output to poutput or perror based on the record level. But of course any prints would interfere with the prompt. So I changed it like so:
But there are two issues with this:
Couldn't the poutput or perror functions handle the functionality of async_alert() automatically? This is one of the biggest gripes with cmd that I feel like cmd2 could automatically handle.
Beta Was this translation helpful? Give feedback.
All reactions