code: def test_debugprint_nested_scans():
      c = dvector("c")
      n = 10
  
      k = iscalar("k")
      A = dvector("A")
  
      def compute_A_k(A, k):
          result, updates = pytensor.scan(
              fn=lambda prior_result, A: prior_result * A,
              outputs_info=pt.ones_like(A),
              non_sequences=A,
              n_steps=k,
          )
  
          A_k = result[-1]
  
          return A_k
  
      components, updates = pytensor.scan(
          fn=lambda c, power, some_A, some_k: c
          * (compute_A_k(some_A, some_k) ** power),
          outputs_info=None,
          sequences=[c, pt.arange(n)],
          non_sequences=[A, k],
      )
      final_result = components.sum()
  
      output_str = debugprint(
          final_result, file="str", print_op_info=True
      )
      lines = output_str.split("\n")
  
      expected_output = """Sum{axes=None} [id A]
       └─ Scan{scan_fn, while_loop=False, inplace=none} [id B] (outer_out_nit_sot-0)
          ├─ Minimum [id C] (outer_in_nit_sot-0)
          │  ├─ Subtensor{i} [id D]
          │  │  ├─ Shape [id E]
          │  │  │  └─ Subtensor{start:} [id F] 'c[0:]'
          │  │  │     ├─ c [id G]
          │  │  │     └─ 0 [id H]
          │  │  └─ 0 [id I]
          │  └─ Subtensor{i} [id J]
          │     ├─ Shape [id K]
          │     │  └─ Subtensor{start:} [id L]
          │     │     ├─ ARange{dtype='int64'} [id M]
          │     │     │  ├─ 0 [id N]
          │     │     │  ├─ 10 [id O]
          │     │     │  └─ 1 [id P]
          │     │     └─ 0 [id Q]
          │     └─ 0 [id R]
          ├─ Subtensor{:stop} [id S] (outer_in_seqs-0)
          │  ├─ Subtensor{start:} [id F] 'c[0:]'
          │  │  └─ ···
          │  └─ ScalarFromTensor [id T]
          │     └─ Minimum [id C]
          │        └─ ···
          ├─ Subtensor{:stop} [id U] (outer_in_seqs-1)
          │  ├─ Subtensor{start:} [id L]
          │  │  └─ ···
          │  └─ ScalarFromTensor [id V]
          │     └─ Minimum [id C]
          │        └─ ···
          ├─ Minimum [id C] (outer_in_nit_sot-0)
          │  └─ ···
          ├─ A [id W] (outer_in_non_seqs-0)
          └─ k [id X] (outer_in_non_seqs-1)
  
      Inner graphs:
  
      Scan{scan_fn, while_loop=False, inplace=none} [id B]
       ← Mul [id Y] (inner_out_nit_sot-0)
          ├─ ExpandDims{axis=0} [id Z]
          │  └─ *0-<Scalar(float64, shape=())> [id BA] -> [id S] (inner_in_seqs-0)
          └─ Pow [id BB]
             ├─ Subtensor{i} [id BC]
             │  ├─ Subtensor{start:} [id BD]
             │  │  ├─ Scan{scan_fn, while_loop=False, inplace=none} [id BE] (outer_out_sit_sot-0)
             │  │  │  ├─ *3-<Scalar(int32, shape=())> [id BF] -> [id X] (inner_in_non_seqs-1) (n_steps)
             │  │  │  ├─ SetSubtensor{:stop} [id BG] (outer_in_sit_sot-0)
             │  │  │  │  ├─ AllocEmpty{dtype='float64'} [id BH]
             │  │  │  │  │  ├─ Add [id BI]
             │  │  │  │  │  │  ├─ *3-<Scalar(int32, shape=())> [id BF] -> [id X] (inner_in_non_seqs-1)
             │  │  │  │  │  │  └─ Subtensor{i} [id BJ]
             │  │  │  │  │  │     ├─ Shape [id BK]
             │  │  │  │  │  │     │  └─ Unbroadcast{0} [id BL]
             │  │  │  │  │  │     │     └─ ExpandDims{axis=0} [id BM]
             │  │  │  │  │  │     │        └─ Second [id BN]
             │  │  │  │  │  │     │           ├─ *2-<Vector(float64, shape=(?,))> [id BO] -> [id W] (inner_in_non_seqs-0)
             │  │  │  │  │  │     │           └─ ExpandDims{axis=0} [id BP]
             │  │  │  │  │  │     │              └─ 1.0 [id BQ]
             │  │  │  │  │  │     └─ 0 [id BR]
             │  │  │  │  │  └─ Subtensor{i} [id BS]
             │  │  │  │  │     ├─ Shape [id BT]
             │  │  │  │  │     │  └─ Unbroadcast{0} [id BL]
             │  │  │  │  │     │     └─ ···
             │  │  │  │  │     └─ 1 [id BU]
             │  │  │  │  ├─ Unbroadcast{0} [id BL]
             │  │  │  │  │  └─ ···
             │  │  │  │  └─ ScalarFromTensor [id BV]
             │  │  │  │     └─ Subtensor{i} [id BJ]
             │  │  │  │        └─ ···
             │  │  │  └─ *2-<Vector(float64, shape=(?,))> [id BO] -> [id W] (inner_in_non_seqs-0) (outer_in_non_seqs-0)
             │  │  └─ 1 [id BW]
             │  └─ -1 [id BX]
             └─ ExpandDims{axis=0} [id BY]
                └─ *1-<Scalar(int64, shape=())> [id BZ] -> [id U] (inner_in_seqs-1)
  
      Scan{scan_fn, while_loop=False, inplace=none} [id BE]
       ← Mul [id CA] (inner_out_sit_sot-0)
          ├─ *0-<Vector(float64, shape=(?,))> [id CB] -> [id BG] (inner_in_sit_sot-0)
          └─ *1-<Vector(float64, shape=(?,))> [id CC] -> [id BO] (inner_in_non_seqs-0)"""
  
      for truth, out in zip(expected_output.split("\n"), lines):
          assert truth.strip() == out.strip()
  
      fg = FunctionGraph([c, k, A], [final_result])
  
      output_str = debugprint(
          fg, file="str", print_op_info=True, print_fgraph_inputs=True
      )
      lines = output_str.split("\n")
  
      expected_output = """→ c [id A]
      → k [id B]
      → A [id C]
      Sum{axes=None} [id D] 13
       └─ Scan{scan_fn, while_loop=False, inplace=none} [id E] 12 (outer_out_nit_sot-0)
          ├─ Minimum [id F] 7 (outer_in_nit_sot-0)
          │  ├─ Subtensor{i} [id G] 6
          │  │  ├─ Shape [id H] 5
          │  │  │  └─ Subtensor{start:} [id I] 'c[0:]' 4
          │  │  │     ├─ c [id A]
          │  │  │     └─ 0 [id J]
          │  │  └─ 0 [id K]
          │  └─ Subtensor{i} [id L] 3
          │     ├─ Shape [id M] 2
          │     │  └─ Subtensor{start:} [id N] 1
          │     │     ├─ ARange{dtype='int64'} [id O] 0
          │     │     │  ├─ 0 [id P]
          │     │     │  ├─ 10 [id Q]
          │     │     │  └─ 1 [id R]
          │     │     └─ 0 [id S]
          │     └─ 0 [id T]
          ├─ Subtensor{:stop} [id U] 11 (outer_in_seqs-0)
          │  ├─ Subtensor{start:} [id I] 'c[0:]' 4
          │  │  └─ ···
          │  └─ ScalarFromTensor [id V] 10
          │     └─ Minimum [id F] 7
          │        └─ ···
          ├─ Subtensor{:stop} [id W] 9 (outer_in_seqs-1)
          │  ├─ Subtensor{start:} [id N] 1
          │  │  └─ ···
          │  └─ ScalarFromTensor [id X] 8
          │     └─ Minimum [id F] 7
          │        └─ ···
          ├─ Minimum [id F] 7 (outer_in_nit_sot-0)
          │  └─ ···
          ├─ A [id C] (outer_in_non_seqs-0)
          └─ k [id B] (outer_in_non_seqs-1)
  
      Inner graphs:
  
      Scan{scan_fn, while_loop=False, inplace=none} [id E]
       → *0-<Scalar(float64, shape=())> [id Y] -> [id U] (inner_in_seqs-0)
       → *1-<Scalar(int64, shape=())> [id Z] -> [id W] (inner_in_seqs-1)
       → *2-<Vector(float64, shape=(?,))> [id BA] -> [id C] (inner_in_non_seqs-0)
       → *3-<Scalar(int32, shape=())> [id BB] -> [id B] (inner_in_non_seqs-1)
       ← Mul [id BC] (inner_out_nit_sot-0)
          ├─ ExpandDims{axis=0} [id BD]
          │  └─ *0-<Scalar(float64, shape=())> [id Y] (inner_in_seqs-0)
          └─ Pow [id BE]
             ├─ Subtensor{i} [id BF]
             │  ├─ Subtensor{start:} [id BG]
             │  │  ├─ Scan{scan_fn, while_loop=False, inplace=none} [id BH] (outer_out_sit_sot-0)
             │  │  │  ├─ *3-<Scalar(int32, shape=())> [id BB] (inner_in_non_seqs-1) (n_steps)
             │  │  │  ├─ SetSubtensor{:stop} [id BI] (outer_in_sit_sot-0)
             │  │  │  │  ├─ AllocEmpty{dtype='float64'} [id BJ]
             │  │  │  │  │  ├─ Add [id BK]
             │  │  │  │  │  │  ├─ *3-<Scalar(int32, shape=())> [id BB] (inner_in_non_seqs-1)
             │  │  │  │  │  │  └─ Subtensor{i} [id BL]
             │  │  │  │  │  │     ├─ Shape [id BM]
             │  │  │  │  │  │     │  └─ Unbroadcast{0} [id BN]
             │  │  │  │  │  │     │     └─ ExpandDims{axis=0} [id BO]
             │  │  │  │  │  │     │        └─ Second [id BP]
             │  │  │  │  │  │     │           ├─ *2-<Vector(float64, shape=(?,))> [id BA] (inner_in_non_seqs-0)
             │  │  │  │  │  │     │           └─ ExpandDims{axis=0} [id BQ]
             │  │  │  │  │  │     │              └─ 1.0 [id BR]
             │  │  │  │  │  │     └─ 0 [id BS]
             │  │  │  │  │  └─ Subtensor{i} [id BT]
             │  │  │  │  │     ├─ Shape [id BU]
             │  │  │  │  │     │  └─ Unbroadcast{0} [id BN]
             │  │  │  │  │     │     └─ ···
             │  │  │  │  │     └─ 1 [id BV]
             │  │  │  │  ├─ Unbroadcast{0} [id BN]
             │  │  │  │  │  └─ ···
             │  │  │  │  └─ ScalarFromTensor [id BW]
             │  │  │  │     └─ Subtensor{i} [id BL]
             │  │  │  │        └─ ···
             │  │  │  └─ *2-<Vector(float64, shape=(?,))> [id BA] (inner_in_non_seqs-0) (outer_in_non_seqs-0)
             │  │  └─ 1 [id BX]
             │  └─ -1 [id BY]
             └─ ExpandDims{axis=0} [id BZ]
                └─ *1-<Scalar(int64, shape=())> [id Z] (inner_in_seqs-1)
  
      Scan{scan_fn, while_loop=False, inplace=none} [id BH]
       → *0-<Vector(float64, shape=(?,))> [id CA] -> [id BI] (inner_in_sit_sot-0)
       → *1-<Vector(float64, shape=(?,))> [id CB] -> [id BA] (inner_in_non_seqs-0)
       ← Mul [id CC] (inner_out_sit_sot-0)
          ├─ *0-<Vector(float64, shape=(?,))> [id CA] (inner_in_sit_sot-0)
          └─ *1-<Vector(float64, shape=(?,))> [id CB] (inner_in_non_seqs-0)"""
  
      for truth, out in zip(expected_output.split("\n"), lines):
          assert truth.strip() == out.strip()
  
file_path: pytensor/tests/scan/test_printing.py
imports: import numpy
  import pytest
  import pytensor
  import pytensor.tensor
  from pytensor.configdefaults import config
  from pytensor.graph.fg import FunctionGraph
  from pytensor.printing import debugprint, pydot_imported, pydotprint
  from pytensor.tensor.type import dvector, iscalar, scalar, vector
label_desc: Use image node_id 4 for calling a global function with example usage: test_debugprint_nested_scans() and returns: A_k