Skip to content

ascii_tree() raises ValueError whenever its optional df argument is supplied #1224

Description

@ppcvote

Describe the bug

ascii_tree(dt, df) raises ValueError for every non-None value of df, so the optional second parameter in its own signature can never be used.

src/ssvc/decision_tables/helpers.py:375 declares it:

def ascii_tree(dt: DecisionTable, df: pd.DataFrame | None = None) -> str:

and line 380 tests it with ==:

    if df == None:
        df = decision_table_to_longform_df(dt)

== against a DataFrame is elementwise, so it returns a same-shaped boolean DataFrame rather than a scalar. The surrounding if then calls DataFrame.__bool__, which pandas raises from by design.

The default path survives only because None == None is a plain scalar True. Every call site in the repository and both README examples omit df, which is why this has stayed invisible.

src/ssvc/decision_tables/base.py:706 re-exports the same function, so the failure is reachable from both public entry points.

To Reproduce

from ssvc.decision_tables.example.to_play import LATEST as DT
from ssvc.decision_tables.helpers import ascii_tree, decision_table_to_longform_df

ascii_tree(DT)                                  # fine, 17 lines
df = decision_table_to_longform_df(DT)          # DataFrame, shape (6, 3)
ascii_tree(DT, df)                              # ValueError

Output at c2fad50:

case 1 - df omitted
   OK, 17 lines
case 2 - df supplied, exactly as the signature invites
   df is a DataFrame, shape (6, 3)
   ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

why: `df == None` is elementwise on a DataFrame
   type(df == None) = DataFrame, shape (6, 3)
   bool(that) -> ValueError: The truth value of a DataFrame is ambiguous.

base.ascii_tree(DT, df) fails identically.

Expected behavior

Supplying df uses the caller's frame and skips the internal decision_table_to_longform_df(dt) call, which is what the signature and the docstring's "Reads a Pandas data frame" both promise.

Platform details

Windows 10, Python 3.11.6, pandas 3.0.5, SSVC at c2fad50a887f89cb826d1326478ded7af6ad3f26 (main). Not platform-specific: DataFrame.__bool__ raises on every platform and every pandas 1.x/2.x/3.x.

Additional context

is None is the fix rather than isinstance, since the parameter is documented as pd.DataFrame | None and the sentinel is identity.

I have a fix and a regression test ready, and ascii_tree currently has no test coverage of its own. Happy to open a PR against this issue if that is welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions