Dubug Print Tool

I’m not entirely sure if this is the most efficient approach, but I’ve found it to be a time-saver when debugging with print statements. It might seem a bit lengthy, and there’s room to add more statements for further refinement, but it serves as a useful debugging tool.

In the debug server module:

import inspect
import os


def print_debug_info(locals=None, details=False, print_keys_list=False):
  """
  Print debug information based on the given locals dictionary.

  Args:
    locals (dict, optional): The locals dictionary containing the variables to print. Defaults to None.
    details (bool, optional): Flag indicating whether to print detailed information about each variable. Defaults to False.
    print_keys_list (bool, optional): Flag indicating whether to print the keys list for dictionaries and search iterators. Defaults to False.
  """

  #Turned off for publised branch
  if anvil.server.get_app_origin() == "YOUR APP URL":
    return

  print('Debug information:')
  if details:
    # Get the caller's frame information
    caller_frame = inspect.currentframe().f_back
    caller_func_name = caller_frame.f_code.co_name
    caller_line_number = caller_frame.f_lineno
    caller_file_path = os.path.abspath(inspect.getfile(caller_frame.f_code))
    print(f"Caller Function: {caller_func_name}")
    print(f"Line Number: {caller_line_number}")
    print(f"File Path: {caller_file_path}")
  
  type_actions = {
    list: lambda key, value: print_list(key, value),
    dict: lambda key, value: print_dict(key, value, print_keys_list),
    tuple: lambda key, value: print_tuple(key, value),
    set: lambda key, value: print_set(key, value),
    str: lambda key, value: print_string(key, value),
    bool: lambda key, value: print_bool(key, value),
    int: lambda key, value: print_int(key, value),
    float: lambda key, value: print_float(key, value),
    type(None): lambda key, value: print_none(key),
    anvil.tables.SearchIterator: lambda key, value: print_search_iterator(key, value, print_keys_list),
    anvil.tables.v2._row.Row: lambda key, value: print_row(key, value, print_keys_list),
  }

  if locals:
    for key, value in locals.items():
      if details:        
        for type_, action in type_actions.items():
          if isinstance(value, type_):
            action(key, value)
            break
        else:
          print(key, "is of unknown type.")
      else:
        print(key, value)

def print_list(key, value):
  print(key, "is a list. With a length", len(value))
  for item in value:
    print(item)

def print_dict(key, value, print_keys_list):
  print(key, "is a dictionary.")
  for k, v in value.items():
    print(f"Key: {k}, Value: {v}")
    if print_keys_list:
      print("Keys:", list(value.keys()))

def print_tuple(key, value):
  print(key, "is a tuple.")
  for item in value:
    print(item)

def print_set(key, value):
  print(key, "is a set.")
  for item in value:
    print(item)

def print_string(key, value):
  print(key, "is a string.")
  print(value)

def print_bool(key, value):
  print(key, "is a boolean.")
  print(value)

def print_int(key, value):
  print(key, "is an integer.")
  print(value)

def print_float(key, value):
  print(key, "is a float.")
  print(value)

def print_none(key):
  print(key, "is None.")

def print_search_iterator(key, value, print_keys_list):
  print(key, "is a SearchIterator object. With a length", len(value))
  print(value)
  if print_keys_list and len(value):
    print_row(key, value[0], print_keys_list)

def print_row(key, value, print_keys_list):
  print(key, "is a Row object.")
  print(value)
  if print_keys_list:
    print(list({key for key, x in value.items()}))

To call from a funcation:

 DebugModule.print_debug_info(locals(), details = True, print_key_list = True)
5 Likes