class_docstr: A collection of tasks.
  
  When set_downstream() or set_upstream() are called on the TaskGroup, it is applied across
  all tasks within the group if necessary.
  
  :param group_id: a unique, meaningful id for the TaskGroup. group_id must not conflict
      with group_id of TaskGroup or task_id of tasks in the DAG. Root TaskGroup has group_id
      set to None.
  :param prefix_group_id: If set to True, child task_id and group_id will be prefixed with
      this TaskGroup's group_id. If set to False, child task_id and group_id are not prefixed.
      Default is True.
  :param parent_group: The parent TaskGroup of this TaskGroup. parent_group is set to None
      for the root TaskGroup.
  :param dag: The DAG that this TaskGroup belongs to.
  :param default_args: A dictionary of default parameters to be used
      as constructor keyword parameters when initialising operators,
      will override default_args defined in the DAG level.
      Note that operators have the same hook, and precede those defined
      here, meaning that if your dict contains `'depends_on_past': True`
      here and `'depends_on_past': False` in the operator's call
      `default_args`, the actual value will be `False`.
  :param tooltip: The tooltip of the TaskGroup node when displayed in the UI
  :param ui_color: The fill color of the TaskGroup node when displayed in the UI
  :param ui_fgcolor: The label color of the TaskGroup node when displayed in the UI
  :param add_suffix_on_collision: If this task group name already exists,
      automatically add `__1` etc suffixes
class_docstr_tok: ["A","collection","of","tasks",".","When","set_downstream","(",")","or","set_upstream","(",")","are","called","on","the","TaskGroup",",","it","is","applied","across","all","tasks","within","the","group","if","necessary",".",":","param","group_id",":","a","unique",",","meaningful","id","for","the","TaskGroup",".","group_id","must","not","conflict","with","group_id","of","TaskGroup","or","task_id","of","tasks","in","the","DAG",".","Root","TaskGroup","has","group_id","set","to","None",".",":","param","prefix_group_id",":","If","set","to","True",",","child","task_id","and","group_id","will","be","prefixed","with","this","TaskGroup","'s","group_id",".","If","set","to","False",",","child","task_id","and","group_id","are","not","prefixed",".","Default","is","True",".",":","param","parent_group",":","The","parent","TaskGroup","of","this","TaskGroup",".","parent_group","is","set","to","None","for","the","root","TaskGroup",".",":","param","dag",":","The","DAG","that","this","TaskGroup","belongs","to",".",":","param","default_args",":","A","dictionary","of","default","parameters","to","be","used","as","constructor","keyword","parameters","when","initialising","operators",",","will","override","default_args","defined","in","the","DAG","level",".","Note","that","operators","have","the","same","hook",",","and","precede","those","defined","here",",","meaning","that","if","your","dict","contains","`","'depends_on_past","'",":","True","`","here","and","`","'depends_on_past","'",":","False","`","in","the","operator","'s","call","`","default_args","`",",","the","actual","value","will","be","`","False","`",".",":","param","tooltip",":","The","tooltip","of","the","TaskGroup","node","when","displayed","in","the","UI",":","param","ui_color",":","The","fill","color","of","the","TaskGroup","node","when","displayed","in","the","UI",":","param","ui_fgcolor",":","The","label","color","of","the","TaskGroup","node","when","displayed","in","the","UI",":","param","add_suffix_on_collision",":","If","this","task","group","name","already","exists",",","automatically","add","`","__1","`","etc","suffixes"]
docstr: Override TaskMixin.update_relative.
  
  Update upstream_group_ids/downstream_group_ids/upstream_task_ids/downstream_task_ids
  accordingly so that we can reduce the number of edges when displaying Graph view.
docstr_tok: ["Override","TaskMixin.update_relative",".","Update","upstream_group_ids\/downstream_group_ids\/upstream_task_ids\/downstream_task_ids","accordingly","so","that","we","can","reduce","the","number","of","edges","when","displaying","Graph","view","."]
code: def update_relative(
      self,
      other: DependencyMixin,
      upstream: bool = True,
      edge_modifier: EdgeModifier | None = None,
  ) -> None:
      """
      Override TaskMixin.update_relative.
  
      Update upstream_group_ids/downstream_group_ids/upstream_task_ids/downstream_task_ids
      accordingly so that we can reduce the number of edges when displaying Graph view.
      """
      if isinstance(other, TaskGroup):
          # Handles setting relationship between a TaskGroup and another TaskGroup
          if upstream:
              parent, child = (self, other)
              if edge_modifier:
                  edge_modifier.add_edge_info(
                      self.dag,
                      other.downstream_join_id,
                      self.upstream_join_id,
                  )
          else:
              parent, child = (other, self)
              if edge_modifier:
                  edge_modifier.add_edge_info(
                      self.dag,
                      self.downstream_join_id,
                      other.upstream_join_id,
                  )
  
          parent.upstream_group_ids.add(child.group_id)
          child.downstream_group_ids.add(parent.group_id)
      else:
          # Handles setting relationship between a TaskGroup and a task
          for task in other.roots:
              if not isinstance(task, DAGNode):
                  raise AirflowException(
                      "Relationships can only be set between TaskGroup "
                      f"or operators; received {task.__class__.__name__}"
                  )
  
              # Do not set a relationship between a TaskGroup and a Label's roots
              if self == task:
                  continue
  
              if upstream:
                  self.upstream_task_ids.add(task.node_id)
                  if edge_modifier:
                      edge_modifier.add_edge_info(
                          self.dag, task.node_id, self.upstream_join_id
                      )
              else:
                  self.downstream_task_ids.add(task.node_id)
                  if edge_modifier:
                      edge_modifier.add_edge_info(
                          self.dag,
                          self.downstream_join_id,
                          task.node_id,
                      )
  
imports: from __future__ import annotations
  import copy
  import functools
  import operator
  import weakref
  from typing import TYPE_CHECKING, Any, Generator, Iterator, Sequence
  import re2
  from airflow.compat.functools import cache
  from airflow.exceptions import AirflowDagCycleException, AirflowException, DuplicateTaskIdFound, TaskAlreadyInTaskGroup
  from airflow.models.taskmixin import DAGNode
  from airflow.serialization.enums import DagAttributeTypes
  from airflow.utils.helpers import validate_group_key
label_desc: Use image node_id 13 for calling the TaskGroup obj's underlying member method code with example usage: obj.update_relative(other, upstream, edge_modifier) without return types