code: def _print_tags_for_group(
      obj, group, system_tags, all_tags, skip_per_group_header=False
  ):
      if not obj.is_quiet:
          # Pretty printing computations
          max_length = max(
              [len(t) for t in all_tags] if all_tags else [0]
          )
  
          all_tags = sorted(all_tags)
          if sys.version_info[0] < 3:
              all_tags = [
                  t if t in system_tags else "*%s*" % t.encode("utf-8")
                  for t in all_tags
              ]
          else:
              all_tags = [
                  t if t in system_tags else "*%s*" % t
                  for t in all_tags
              ]
  
          num_tags = len(all_tags)
  
          # We consider 4 spaces in between columns
          # We consider 120 characters as total width
          # We want 120 >= column_count*max_length + (column_count - 1)*4
          column_count = 124 // (max_length + 4)
          if column_count == 0:
              # Make sure we have at least 1 column even for very, very long tags
              column_count = 1
              words_per_column = num_tags
          else:
              words_per_column = (
                  num_tags + column_count - 1
              ) // column_count
  
          # Extend all_tags by empty tags to be able to easily fill up the lines
          addl_tags = words_per_column * column_count - num_tags
          if addl_tags > 0:
              all_tags.extend([" " for _ in range(addl_tags)])
  
          lines = []
          if not skip_per_group_header:
              lines.append("For run %s" % group)
          for i in range(words_per_column):
              line_values = [
                  all_tags[i + j * words_per_column]
                  for j in range(column_count)
              ]
              length_values = [
                  max_length + 2 if l[0] == "*" else max_length
                  for l in line_values
              ]
              formatter = "    ".join(
                  ["{:<%d}" % l for l in length_values]
              )
              lines.append(formatter.format(*line_values))
          lines.append("")
          obj.echo("\n".join(lines), err=False)
      else:
          # In quiet mode, we display things much more simply, so it is parseable.
          # When displaying by run, we output three columns:
          #  - the comma separated list of runs (usually 1 but more if --all-runs for eg)
          #  - the comma separated list of system tags
          #  - the comma separated list of user tags
          # Columns are separated by a semicolon surrounded by a space on each side
          # to make it visually clear when there are no system tags for example
          obj.echo_always(
              " ; ".join(
                  [
                      group,
                      ",".join(sorted(system_tags)),
                      ",".join(
                          sorted(all_tags.difference(system_tags))
                      ),
                  ]
              )
          )
  
imports: import sys
  from itertools import chain
  from metaflow import namespace
  from metaflow.client import Flow, Run
  from metaflow.current import current
  from metaflow.util import resolve_identity
  from metaflow.exception import CommandException, MetaflowNotFound, MetaflowInternalError
  from metaflow.exception import MetaflowNamespaceMismatch
  from metaflow._vendor import click
label_desc: Use image node_id 2 for calling a global function with example usage: _print_tags_for_group(obj, group, system_tags, all_tags, skip_per_group_header) without return types