code: def parse_grid_facets(
      facets: str | tuple[str | list[str], str | list[str]],
  ) -> tuple[list[str], list[str]]:
      """
      Return two lists of facetting variables, for the rows & columns
      """
      valid_seqs = [
          "('var1', '.')",
          "('var1', 'var2')",
          "('.', 'var1')",
          "((var1, var2), (var3, var4))",
      ]
      error_msg_s = (
          "Valid sequences for specifying 'facets' look like"
          f" {valid_seqs}"
      )
  
      valid_forms = [
          "var1 ~ .",
          "var1 ~ var2",
          ". ~ var1",
          "var1 + var2 ~ var3 + var4",
          ". ~ func(var1) + func(var2)",
          ". ~ func(var1+var3) + func(var2)",
      ] + valid_seqs
      error_msg_f = (
          "Valid formula for 'facet_grid' look like" f" {valid_forms}"
      )
  
      if not isinstance(facets, str):
          if len(facets) != 2:
              raise PlotnineError(error_msg_s)
  
          rows = ensure_list_spec(facets[0])
          cols = ensure_list_spec(facets[1])
  
          return rows, cols
  
      # Example of allowed formulae
      # "c ~ a + b'
      # '. ~ func(a) + func(b)'
      # 'func(c) ~ func(a+1) + func(b+2)'
      try:
          lhs, rhs = facets.split("~")
      except ValueError as e:
          raise PlotnineError(error_msg_f) from e
      else:
          lhs = lhs.strip()
          rhs = rhs.strip()
  
      rows = ensure_list_spec(lhs)
      cols = ensure_list_spec(rhs)
      return rows, cols
  
file_path: plotnine/plotnine/facets/facet_grid.py
imports: from __future__ import annotations
  import typing
  import pandas
  from .._utils import add_margins, cross_join, join_keys, match, ninteraction
  from ..exceptions import PlotnineError
  from .facet import add_missing_facets, combine_vars, eval_facet_vars, facet, layout_null
  from .strips import Strips, strip
label_desc: Use image node_id 1 for calling a global function with example usage: parse_grid_facets(facets) and returns: rows,  cols, rows,  cols