class_docstr: A graph of processing steps.
  
  The processing steps can have multiple parents, and multiple children (next processing steps, found automatically
    by traversing the graph).
  The graph can have multiple roots.
  
  Args:
      specification (ProcessingGraphSpecification): The specification of the graph.
  
  Raises:
      ValueError: If the graph is not a DAG.
      ValueError: If a processing step provides dataset config names but its input type is not 'dataset', or if a
        processing step provides config split names but its input type is not 'config'.
      ValueError: If a root processing step (ie. a processing step with no parent) is not a dataset processing step.
class_docstr_tok: ["A","graph","of","processing","steps",".","The","processing","steps","can","have","multiple","parents",",","and","multiple","children","(","next","processing","steps",",","found","automatically","by","traversing","the","graph",")",".","The","graph","can","have","multiple","roots",".","Args",":","specification","(","ProcessingGraphSpecification",")",":","The","specification","of","the","graph",".","Raises",":","ValueError",":","If","the","graph","is","not","a","DAG",".","ValueError",":","If","a","processing","step","provides","dataset","config","names","but","its","input","type","is","not","'dataset","'",",","or","if","a","processing","step","provides","config","split","names","but","its","input","type","is","not","'config","'",".","ValueError",":","If","a","root","processing","step","(","ie",".","a","processing","step","with","no","parent",")","is","not","a","dataset","processing","step","."]
docstr: Get the processing steps.
  
  The returned processing steps are copies of the original ones, so that they can be modified without affecting
  the original ones.
  
  Args:
      order (Optional[Literal["alphabetical", "topological"]], optional): The order in which to return the
        processing steps. If None, the order is alphabetical. Defaults to None.
  
  Returns:
      list[ProcessingStep]: The list of processing steps
docstr_tok: ["Get","the","processing","steps",".","The","returned","processing","steps","are","copies","of","the","original","ones",",","so","that","they","can","be","modified","without","affecting","the","original","ones",".","Args",":","order","(","Optional","[","Literal","[","``","alphabetical","''",",","``","topological","''","]","]",",","optional",")",":","The","order","in","which","to","return","the","processing","steps",".","If","None",",","the","order","is","alphabetical",".","Defaults","to","None",".","Returns",":","list","[","ProcessingStep","]",":","The","list","of","processing","steps"]
code: def get_processing_steps(
      self,
      order: Optional[Literal["alphabetical", "topological"]] = None,
  ) -> list[ProcessingStep]:
      """
      Get the processing steps.
  
      The returned processing steps are copies of the original ones, so that they can be modified without affecting
      the original ones.
  
      Args:
          order (Optional[Literal["alphabetical", "topological"]], optional): The order in which to return the
            processing steps. If None, the order is alphabetical. Defaults to None.
  
      Returns:
          list[ProcessingStep]: The list of processing steps
      """
      if order == "topological":
          return self.get_topologically_ordered_processing_steps()
      # default
      return self.get_alphabetically_ordered_processing_steps()
  
imports: from __future__ import annotations
  from collections.abc import Mapping
  from dataclasses import dataclass, field
  from typing import Any, Literal, Optional, TypedDict, Union, get_args
  import networkx
  from libcommon.constants import DEFAULT_DIFFICULTY, DEFAULT_INPUT_TYPE, DEFAULT_JOB_RUNNER_VERSION, MIN_BYTES_FOR_BONUS_DIFFICULTY
  from libcommon.utils import inputs_to_string
label_desc: Use image node_id 10 for calling the ProcessingGraph obj's underlying member method code with example usage: obj.get_processing_steps(order) and returns: self, self