Question about DAG pretty‑printing and new PR to handle nested dicts/lists

Hi everyone,

While working with DAGNode pretty‑printing, I noticed that the string representation was dropping dictionary keys and not handling nested containers very well. I also saw a couple of TODOs in python/ray/dag/format_utils.py about missing keys, indentation being off, and nested containers not being handled.

To address this, I opened a PR here: [DAG] Fix DAGNode string formatting to support nested dicts and lists by AyushKashyapII · Pull Request #63641 · ray-project/ray · GitHub

In short, the PR does the following:

Adds a recursive _format_value helper that:

Preserves dict keys and formats them as key: value, with nested contents correctly indented.

Handles lists/tuples/sets recursively, including nested DAGNode instances.

Falls back to standard string representations for primitives and other types.

Refactors _get_args_lines / _get_kwargs_lines to rely on _format_value so that nested DAG structures render in a more readable, multi‑line form.

Adds unit tests in python/ray/dag/tests/test_formatting.py to cover nested dicts, lists, and nested DAGNode arguments.

Behavior‑wise, the goal is to keep the existing top‑level structure the same, but make nested containers and DAGNodes render more faithfully and readably.

I had a couple of questions:

Is this the kind of change you’d like to see for the DAG pretty‑printer, or is there a preferred direction / design for formatting DAGs that I should align with?

Are there any edge cases or internal uses of get_dag_node_str / str where a more conservative change would be better?

I’d really appreciate any feedback from the maintainers or folks familiar with the DAG internals, and I’m happy to adjust the implementation or tests based on guidance.

Thanks!

Your PR aligns well with the outstanding TODOs in python/ray/dag/format_utils.py regarding missing dictionary keys, indentation, and nested container handling. The recursive _format_value approach, which preserves keys and formats nested containers and DAGNodes, directly addresses these issues and improves readability, as confirmed by your summary and the PR description. Unit tests for nested structures are also a best practice and help ensure correctness (PR 63641).

There is no documented alternative or preferred formatting design for DAG pretty-printing in the current Ray codebase; the existing code contains explicit TODOs for these improvements. However, reviewers have suggested refactoring duplicated logic for sequence formatting and ensuring deterministic output for sets by sorting, as well as adding sets to test coverage. No internal use of get_dag_node_str or str is documented that would require a more conservative approach, but you may want to confirm with maintainers if any legacy integrations depend on the current (less informative) output (PR 63641). Would you like a step-by-step breakdown of the relevant code and review comments?

Sources:

Hint: Mention @RunLLM in the post for followups.

Thanks for the summary and guidance, @RunLLM!

I have pushed the latest updates to fully address the reviewer suggestions and outstanding TODOs:

  1. Deterministic Set Formatting: To prevent flaky tests across different environments, sets are now explicitly sorted alphabetically using sorted(val, key=str). I have also added explicit set coverage to the unit tests to verify this behavior.
  2. Refactored Duplicated Logic: I completely DRY’d up the sequence formatting. I removed the repetitive _get_args_lines, _get_kwargs_lines, _get_options_lines, and _get_other_args functions (~100 lines of duplicated code). They are now replaced by a clean, single format_attr closure inside get_dag_node_str that flawlessly handles relative multi-line indentation.

The code is now much cleaner, deterministic, and the unit tests are 100% green. Could you take a quick look when you have a moment? Let me know if you need any other adjustments!

Your updates directly address all reviewer feedback and outstanding TODOs: sets are now deterministically sorted (using sorted(val, key=str)) to avoid flaky tests, and explicit set coverage is included in the unit tests. The duplicated sequence formatting logic has been consolidated into a single closure (format_attr) within get_dag_node_str, resulting in cleaner, more maintainable code and correct multi-line indentation (PR 63641).

All unit tests pass, and the approach is consistent with the maintainers’ suggestions. No further adjustments are indicated by the current review comments, but you may want to confirm with maintainers if there are any legacy formatting dependencies. Would you like a detailed breakdown of the new formatting logic or test coverage?

Sources:

Hint: Mention @RunLLM in the post for followups.