How do people tend to do debugging client side?

print statements are annoying to have to remove from code and they get confusing if you are debugging for one issue but have all your print statements for a different issue still there…

Here is what I’ve come up with as a solution since the python module logging isn’t available client-side (yet :slightly_smiling_face:) …

in the app your working on… or as a dependency… create a module called logging that has a class Logger

class Logger():
  def __init__(self,debug, msg=''):
    self.debug = debug
    self.msg   = msg

  @property
  def debug(self):
    return self._debug

  @debug.setter
  def debug(self,value):
    if not isinstance(value,bool):
      raise TypeError(f'debug should be a boolean, not {type(value).__name__}')
    self._debug = value

  @property
  def msg(self):
    return self._msg

  @msg.setter
  def msg(self,value):
    if not isinstance(value,str):
      raise TypeError(f'msg should be type str, not {type(value).__name__}')
    self._msg = value
    
  def print(self,*args,**kwargs):
    if self.debug:
      print(self.msg, *args,**kwargs) if self.msg else print(*args,**kwargs)

Then inside the logging module you can define different Loggers

logger    = Logger(debug=True)
timer_log = Logger(debug=True,  msg='timer')
issue1    = Logger(debug=True,  msg='issue1:')
issue2    = Logger(debug=False, msg='issue2:')
critical  = Logger(debug=True,  msg='**critical**:')

Next, inside forms you can import different Loggers like

from .logging import *
# or just specific Loggers
from .logging import timer_log, critical

Dotted throughout your code you can replace your print statements with

issue1.print(f'some value {value}')
timer_log.print(f'{self.__name__} loaded at {time.time() - self.start_time})

Whenever you want to turn off a particular Logger just go into the logging module and set the debug attribute to False :boom:

Do people have other solutions?

8 Likes

That looks great!

What about keeping track of what’s being logged and adding a method that allows to do this:

alert(Label(timer_log.show_all()), large=True)

This would help when the logger prints long lines that are difficult to read on the left panel and when you want to see only one of the logs.

3 Likes

Oooh good suggestions something like:

class Logger():
  def __init__(self, debug, msg=''):
    self.debug = debug
    self.msg = msg
    self._log = [(msg,)]

  def print(self, *args, **kwargs):
    if self.debug:
      print(self.msg, *args, **kwargs) if self.msg else print(*args, **kwargs)
    self._log.append(args)

  def show_log(self):
    log_rows = [' '.join(str(arg) for arg in args) for args in self._log]
    return '\n'.join(log_rows)

  @property
  def debug(self):
    return self._debug

  @debug.setter
  def debug(self, value):
    if not isinstance(value, bool):
      raise TypeError(f'debug should be a boolean, not {type(value).__name__}')
    self._debug = value

  @property
  def msg(self):
    return self._msg

  @msg.setter
  def msg(self, value):
    if not isinstance(value, str):
      raise TypeError(f'msg should be type str, not {type(value).__name__}')
    self._msg = value