class_docstr: Tracks the current if/else scope with the path that we took. Captures the used and produced
  data nodes, applying the necessary splits based on the scope level where they were produced
  and where they are used.
docstr: Add next level of if/else scope that is predicated with the `predicate`.
  The user might have provided a predicate from a scope of higher level, which means
  that `predicate` might be subject to additional slicing. Apply that slicing and return
  the actual predicate that will be used for slicing when entering this scope.
  
  The situation will happen for example in a case like this, where both predicates are
  produced in global scope:
  
  pred_0 = ...
  pred_1 = ...
  
  if pred_0:  # push_pred(pred_0) -> returns pred_0
      if pred_1:  # push_pred(pred_1) ->
                  # -> returns fn._conditional.slice(pred_1, predicate=pred_0)
  
  Parameters
  ----------
  predicate : DataNode
      Predicate guarding this scope.
  
  Returns
  -------
  DataNode
      Actual predicate after applying necessary slices to use it in this scope.
docstr_tok: ["Add","next","level","of","if\/else","scope","that","is","predicated","with","the","`","predicate","`",".","The","user","might","have","provided","a","predicate","from","a","scope","of","higher","level",",","which","means","that","`","predicate","`","might","be","subject","to","additional","slicing",".","Apply","that","slicing","and","return","the","actual","predicate","that","will","be","used","for","slicing","when","entering","this","scope",".","The","situation","will","happen","for","example","in","a","case","like","this",",","where","both","predicates","are","produced","in","global","scope",":","pred_0","=","...","pred_1","=","...","if","pred_0",":","#","push_pred","(","pred_0",")","-",">","returns","pred_0","if","pred_1",":","#","push_pred","(","pred_1",")","-",">","#","-",">","returns","fn._conditional.slice","(","pred_1",",","predicate=pred_0",")","Parameters","--","--","--","--","--","predicate",":","DataNode","Predicate","guarding","this","scope",".","Returns","--","--","--","-","DataNode","Actual","predicate","after","applying","necessary","slices","to","use","it","in","this","scope","."]
code: def push_predicate(self, predicate):
      """Add next level of if/else scope that is predicated with the `predicate`.
      The user might have provided a predicate from a scope of higher level, which means
      that `predicate` might be subject to additional slicing. Apply that slicing and return
      the actual predicate that will be used for slicing when entering this scope.
  
      The situation will happen for example in a case like this, where both predicates are
      produced in global scope:
  
      pred_0 = ...
      pred_1 = ...
  
      if pred_0:  # push_pred(pred_0) -> returns pred_0
          if pred_1:  # push_pred(pred_1) ->
                      # -> returns fn._conditional.slice(pred_1, predicate=pred_0)
  
      Parameters
      ----------
      predicate : DataNode
          Predicate guarding this scope.
  
      Returns
      -------
      DataNode
          Actual predicate after applying necessary slices to use it in this scope.
      """
      new_pred = self.preprocess_input(predicate)
      new_entry = _StackEntry(new_pred)
      self._stack.append(new_entry)
      return new_pred
  
imports: from nvidia.dali import _autograph
  from nvidia.dali.data_node import DataNode
  from nvidia.dali import fn
  from nvidia.dali._autograph.utils import ag_logging
  from nvidia.dali._autograph.operators import variables
  from contextlib import contextmanager
  from enum import Enum
  import tree
label_desc: Use image node_id 2 for calling the _ConditionStack obj's underlying member method code with example usage: obj.push_predicate(predicate) and returns: new_pred