← eval7_submission_v1n

rich_2725

resolved RESOLVED PASS · 12 tool calls · 53 s · Textualize/rich

Task input

fix table rendering order of box elements

## Type of changes

- [x] Bug fix
- [ ] New feature
- [ ] Documentation / docstrings
- [x] Tests
- [ ] Other

## Checklist

- [x] I've run the latest [black](https://github.com/psf/black) with default args on new code.
- [x] I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate.
- [x] I've added tests for new code.
- [x] I accept that @willmcgugan may be pedantic in the code review.

## Description

* Previously "mid" box elements appeared in last line of table (footer), while "footer" box elements appeared mid table body. Reversed that order so mid is truly mid, footer is truly footer.
* Tested with:

    ```
    table.box.head_left = '1'
    table.box.head_vertical = '2'
    table.box.head_right = '3'

    table.box.mid_left = '4'
    table.box.mid_vertical = '5'
    table.box.mid_right = '6'

    table.box.foot_left = '7'
    table.box.foot_vertical = '8'
    table.box.foot_right = '9'
    ```

  After change, correct ordering:

    ```
    +--------------------------------------------------------------------------+
    1Date        2Title                            2  Production2    Box Office3
    |------------ --------------------------------- ------------ --------------|
    4Dec 20, 20195Star Wars: The Rise of Skywalker 5$275,000,0005  $375,126,1186
    4May 25, 20185Solo: A Star Wars Story          5$275,000,0005  $393,151,3476
    7Dec 15, 20178Star Wars Ep. VIII: The Last Jedi8$262,000,0008$1,332,539,8899
    +--------------------------------------------------------------------------+
    ```

* All non-skipped prior automated tests pass. No automated tests added. Unclear that additional test for box ordering would add proportionate value.

Tool calls (13)

#ToolArgumentsResult
1run_command
{
 "command": "grep -rn \"table\" --include=*.py rich | grep \"box\" | head -20"
}
{"status": "ok", "stdout": "rich/table.py:55: show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.\nrich/table.py:168: show
full
{"status": "ok", "stdout": "rich/table.py:55:        show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.\nrich/table.py:168:        show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.\nrich/markdown.py:255:        table = Table(box=box.SIMPLE_HEAVY)\nrich/box.py:436:    from .table import Table\nrich/box.py:468:        table = Table(\nrich/box.py:471:        table.add_column(\"Header 1\", \"Footer 1\")\nrich/box.py:472:        table.add_column(\"Header 2\", \"Footer 2\")\nrich/box.py:473:        table.add_row(\"Cell\", \"Cell\")\nrich/box.py:474:        table.add_row(\"Cell\", \"Cell\")\nrich/box.py:475:        table.box = getattr(box, box_name)\nrich/box.py:476:        table.title = Text(f\"box.{box_name}\", style=\"magenta\")\nrich/box.py:477:        columns.add_renderable(table)\nrich/__main__.py:91:        table = Table(show_header=False, pad_edge=False, box=None, expand=True)\n", "stderr": "", "exit_code": 0}
2run_command
{
 "command": "grep -rn \"mid\" rich/table.py"
}
{"status": "ok", "stdout": "89: \"\"\"str: How to vertically align content (\"top\", \"middle\", or \"bottom\")\"\"\"\n390: vertical (VerticalAlignMethod, optio
full
{"status": "ok", "stdout": "89:    \"\"\"str: How to vertically align content (\"top\", \"middle\", or \"bottom\")\"\"\"\n390:            vertical (VerticalAlignMethod, optional): Vertical alignment, one of \"top\", \"middle\", or \"bottom\". Defaults to \"top\".\n784:                    _Segment(_box.mid_left, border_style),\n785:                    _Segment(_box.mid_right, border_style),\n786:                    _Segment(_box.mid_vertical, border_style),\n845:                elif vertical == \"middle\":\n846:                    return _Segment.align_middle(cell, width, row_height, style)\n908:                            _box.get_row(widths, \"mid\", edge=show_edge) * leading,\n", "stderr": "", "exit_code": 0}
3run_command
{
 "command": "grep -rn \"foot\" rich/table.py"
}
{"status": "ok", "stdout": "54: show_footer (bool, optional): Show a footer row. Defaults to False.\n61: footer_style (Union[str, Style], optional): Style of th
full
{"status": "ok", "stdout": "54:        show_footer (bool, optional): Show a footer row. Defaults to False.\n61:        footer_style (Union[str, Style], optional): Style of the footer. Defaults to \"table.footer\".\n73:    footer: \"RenderableType\" = \"\"\n74:    \"\"\"RenderableType: Renderable for the footer (typically a string)\"\"\"\n79:    footer_style: StyleType = \"\"\n80:    \"\"\"StyleType: The style of the footer.\"\"\"\n167:        show_footer (bool, optional): Show a footer row. Defaults to False.\n174:        footer_style (Union[str, Style], optional): Style of the footer. Defaults to \"table.footer\".\n200:        show_footer: bool = False,\n207:        footer_style: Optional[StyleType] = \"table.footer\",\n227:        self.show_footer = show_footer\n234:        self.footer_style = footer_style or \"\"\n259:        \"\"\"Get a table with no lines, headers, or footer.\n277:            show_footer=False,\n365:        footer: \"RenderableType\" = \"\",\n368:        footer_style: Optional[StyleType] = None,\n384:            footer (RenderableType, optional): Text or renderable for the footer.\n387:            footer_style (Union[str, Style], optional): Style for the footer, or None for default. Defaults to None.\n402:            footer=footer,\n404:            footer_style=footer_style or \"\",\n671:        if self.show_footer:\n672:            footer_style = get_style(self.footer_style or \"\") + get_style(\n673:                column.footer_style\n675:            _append((footer_style, column.footer))\n765:        show_footer = self.show_footer\n779:                    _Segment(_box.foot_left, border_style),\n780:                    _Segment(_box.foot_right, border_style),\n781:                    _Segment(_box.foot_vertical, border_style),\n800:            footer_row = last and show_footer\n803:                if (not header_row and not footer_row)\n808:            if header_row or footer_row:\n840:                elif footer_row:\n864:                i
4run_command
{
 "command": "python3 -c \"from rich.table import Table; from rich.box import Box; t = Table(box=Box()); t.box.head_left='1'; t.box.head_vertical='2'; t.box.head_right='3'; t.box.mid_left='4'; t.box.mid_vertical='5'; t.box.mid_right='6'; t.box.foot_left='7'; t.box.foot_vertical='8'; t.box.foot_right='9'; t.add_column('Date'); t.add_column('Title'); t.add_row('Dec 20, 2019', 'Star Wars'); t.add_row('May 25, 2018', 'Solo'); t.show_footer = True; t.footer = 'Footer'; print(t)\""
}
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"<string>\", line 1, in <module>\n from rich.tabl
full
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n  File \"<string>\", line 1, in <module>\n    from rich.table import Table; from rich.box import Box; t = Table(box=Box()); t.box.head_left='1'; t.box.head_vertical='2'; t.box.head_right='3'; t.box.mid_left='4'; t.box.mid_vertical='5'; t.box.mid_right='6'; t.box.foot_left='7'; t.box.foot_vertical='8'; t.box.foot_right='9'; t.add_column('Date'); t.add_column('Title'); t.add_row('Dec 20, 2019', 'Star Wars'); t.add_row('May 25, 2018', 'Solo'); t.show_footer = True; t.footer = 'Footer'; print(t)\n                                                                          ~~~^^\nTypeError: Box.__init__() missing 1 required positional argument: 'box'\n", "details": {"stdout": "", "stderr": "Traceback (most recent call last):\n  File \"<string>\", line 1, in <module>\n    from rich.table import Table; from rich.box import Box; t = Table(box=Box()); t.box.head_left='1'; t.box.head_vertical='2'; t.box.head_right='3'; t.box.mid_left='4'; t.box.mid_vertical='5'; t.box.mid_right='6'; t.box.foot_left='7'; t.box.foot_vertical='8'; t.box.foot_right='9'; t.add_column('Date'); t.add_column('Title'); t.add_row('Dec 20, 2019', 'Star Wars'); t.add_row('May 25, 2018', 'Solo'); t.show_footer = True; t.footer = 'Footer'; print(t)\n                                                                          ~~~^^\nTypeError: Box.__init__() missing 1 required positional argument: 'box'\n", "exit_code": 1}}
5run_command
{
 "command": "python3 -c \"from rich.table import Table; from rich.box import Box; t = Table(); t.box.head_left='1'; t.box.head_vertical='2'; t.box.head_right='3'; t.box.mid_left='4'; t.box.mid_vertical='5'; t.box.mid_right='6'; t.box.foot_left='7'; t.box.foot_vertical='8'; t.box.foot_right='9'; t.add_column('Date'); t.add_column('Title'); t.add_row('Dec 20, 2019', 'Star Wars'); t.add_row('May 25, 2018', 'Solo'); t.show_footer = True; t.footer = 'Footer'; print(t)\""
}
{"status": "ok", "stdout": "<rich.table.Table object at 0x78a47e53dd30>\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "<rich.table.Table object at 0x78a47e53dd30>\n", "stderr": "", "exit_code": 0}
6run_command
{
 "command": "python3 -c \"from rich.console import Console; from rich.table import Table; from rich.console import Console; console = Console(force_terminal=True); t = Table(); t.box.head_left='1'; t.box.head_vertical='2'; t.box.head_right='3'; t.box.mid_left='4'; t.box.mid_vertical='5'; t.box.mid_right='6'; t.box.foot_left='7'; t.box.foot_vertical='8'; t.box.foot_right='9'; t.add_column('Date'); t.add_column('Title'); t.add_row('Dec 20, 2019', 'Star Wars'); t.add_row('May 25, 2018', 'Solo'); t.show_footer = True; t.footer = 'Footer'; console.print(t)\""
}
{"status": "ok", "stdout": "\u250f\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2533\u2501\u2501\u2501\u2501\u2501\u2501
full
{"status": "ok", "stdout": "\u250f\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2533\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2513\n1 Date         2 Title     3\n\u2521\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2547\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2529\n7 Dec 20, 2019 8 Star Wars 9\n7 May 25, 2018 8 Solo      9\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n4              5           6\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n", "stderr": "", "exit_code": 0}
7run_command
{
 "command": "sed -n '770,810p' rich/table.py"
}
{"status": "ok", "stdout": " _Segment = Segment\n if _box:\n box_segments = [\n (\n _Segment(_box.head_left, border_style),\n _Segment(_box.head_right, border_s
full
{"status": "ok", "stdout": "        _Segment = Segment\n        if _box:\n            box_segments = [\n                (\n                    _Segment(_box.head_left, border_style),\n                    _Segment(_box.head_right, border_style),\n                    _Segment(_box.head_vertical, border_style),\n                ),\n                (\n                    _Segment(_box.foot_left, border_style),\n                    _Segment(_box.foot_right, border_style),\n                    _Segment(_box.foot_vertical, border_style),\n                ),\n                (\n                    _Segment(_box.mid_left, border_style),\n                    _Segment(_box.mid_right, border_style),\n                    _Segment(_box.mid_vertical, border_style),\n                ),\n            ]\n            if show_edge:\n                yield _Segment(_box.get_top(widths), border_style)\n                yield new_line\n        else:\n            box_segments = []\n\n        get_row_style = self.get_row_style\n        get_style = console.get_style\n\n        for index, (first, last, row_cell) in enumerate(loop_first_last(row_cells)):\n            header_row = first and show_header\n            footer_row = last and show_footer\n            row = (\n                self.rows[index - show_header]\n                if (not header_row and not footer_row)\n                else None\n            )\n            max_height = 1\n            cells: List[List[List[Segment]]] = []\n            if header_row or footer_row:\n                row_style = Style.null()\n            else:\n", "stderr": "", "exit_code": 0}
8run_command
{
 "command": "sed -n '800,870p' rich/table.py"
}
{"status": "ok", "stdout": " footer_row = last and show_footer\n row = (\n self.rows[index - show_header]\n if (not header_row and not footer_row)\n else None\n
full
{"status": "ok", "stdout": "            footer_row = last and show_footer\n            row = (\n                self.rows[index - show_header]\n                if (not header_row and not footer_row)\n                else None\n            )\n            max_height = 1\n            cells: List[List[List[Segment]]] = []\n            if header_row or footer_row:\n                row_style = Style.null()\n            else:\n                row_style = get_style(\n                    get_row_style(console, index - 1 if show_header else index)\n                )\n            for width, cell, column in zip(widths, row_cell, columns):\n                render_options = options.update(\n                    width=width,\n                    justify=column.justify,\n                    no_wrap=column.no_wrap,\n                    overflow=column.overflow,\n                    height=None,\n                )\n                lines = console.render_lines(\n                    cell.renderable,\n                    render_options,\n                    style=get_style(cell.style) + row_style,\n                )\n                max_height = max(max_height, len(lines))\n                cells.append(lines)\n\n            row_height = max(len(cell) for cell in cells)\n\n            def align_cell(\n                cell: List[List[Segment]],\n                vertical: \"VerticalAlignMethod\",\n                width: int,\n                style: Style,\n            ) -> List[List[Segment]]:\n                if header_row:\n                    vertical = \"bottom\"\n                elif footer_row:\n                    vertical = \"top\"\n\n                if vertical == \"top\":\n                    return _Segment.align_top(cell, width, row_height, style)\n                elif vertical == \"middle\":\n                    return _Segment.align_middle(cell, width, row_height, style)\n                return _Segment.align_bottom(cell, width, row_height, style)\n\n            cells[:] = [\n
9run_command
{
 "command": "sed -n '860,880p' rich/table.py"
}
{"status": "ok", "stdout": " for width, _cell, cell, column in zip(widths, row_cell, cells, columns)\n ]\n\n if _box:\n if last and show_footer:\n yield _Segmen
full
{"status": "ok", "stdout": "                for width, _cell, cell, column in zip(widths, row_cell, cells, columns)\n            ]\n\n            if _box:\n                if last and show_footer:\n                    yield _Segment(\n                        _box.get_row(widths, \"foot\", edge=show_edge), border_style\n                    )\n                    yield new_line\n                left, right, _divider = box_segments[0 if first else (2 if last else 1)]\n\n                # If the column divider is whitespace also style it with the row background\n                divider = (\n                    _divider\n                    if _divider.text.strip()\n                    else _Segment(\n                        _divider.text, row_style.background_style + _divider.style\n                    )\n                )\n                for line_no in range(max_height):\n                    if show_edge:\n", "stderr": "", "exit_code": 0}
10run_command
{
 "command": "sed -n '775,795p' rich/table.py"
}
{"status": "ok", "stdout": " _Segment(_box.head_right, border_style),\n _Segment(_box.head_vertical, border_style),\n ),\n (\n _Segment(_box.foot_left, border_s
full
{"status": "ok", "stdout": "                    _Segment(_box.head_right, border_style),\n                    _Segment(_box.head_vertical, border_style),\n                ),\n                (\n                    _Segment(_box.foot_left, border_style),\n                    _Segment(_box.foot_right, border_style),\n                    _Segment(_box.foot_vertical, border_style),\n                ),\n                (\n                    _Segment(_box.mid_left, border_style),\n                    _Segment(_box.mid_right, border_style),\n                    _Segment(_box.mid_vertical, border_style),\n                ),\n            ]\n            if show_edge:\n                yield _Segment(_box.get_top(widths), border_style)\n                yield new_line\n        else:\n            box_segments = []\n\n        get_row_style = self.get_row_style\n", "stderr": "", "exit_code": 0}
11edit_file
{
 "filepath": "rich/table.py",
 "new_string": "                (\n                    _Segment(_box.mid_left, border_style),\n                    _Segment(_box.mid_right, border_style),\n                    _Segment(_box.mid_vertical, border_style),\n                ),\n                (\n                    _Segment(_box.foot_left, border_style),\n                    _Segment(_box.foot_right, border_style),\n                    _Segment(_box.foot_vertical, border_style),\n                ),",
 "old_string": "                (\n                    _Segment(_box.foot_left, border_style),\n                    _Segment(_box.foot_right, border_style),\n                    _Segment(_box.foot_vertical, border_style),\n                ),\n                (\n                    _Segment(_box.mid_left, border_style),\n                    _Segment(_box.mid_right, border_style),\n                    _Segment(_box.mid_vertical, border_style),\n                ),"
}
{"status": "ok", "filepath": "rich/table.py", "occurrences": 1, "strategy": "exact", "diff": "--- a/rich/table.py\n+++ b/rich/table.py\n@@ -776,14 +776,14 @@\n
full
{"status": "ok", "filepath": "rich/table.py", "occurrences": 1, "strategy": "exact", "diff": "--- a/rich/table.py\n+++ b/rich/table.py\n@@ -776,14 +776,14 @@\n                     _Segment(_box.head_vertical, border_style),\n                 ),\n                 (\n+                    _Segment(_box.mid_left, border_style),\n+                    _Segment(_box.mid_right, border_style),\n+                    _Segment(_box.mid_vertical, border_style),\n+                ),\n+                (\n                     _Segment(_box.foot_left, border_style),\n                     _Segment(_box.foot_right, border_style),\n                     _Segment(_box.foot_vertical, border_style),\n-                ),\n-                (\n-                    _Segment(_box.mid_left, border_style),\n-                    _Segment(_box.mid_right, border_style),\n-                    _Segment(_box.mid_vertical, border_style),\n                 ),\n             ]\n             if show_edge:\n", "is_truncated": false}
12run_command
{
 "command": "python3 -c \"from rich.console import Console; from rich.table import Table; console = Console(force_terminal=True); t = Table(); t.box.head_left='1'; t.box.head_vertical='2'; t.box.head_right='3'; t.box.mid_left='4'; t.box.mid_vertical='5'; t.box.mid_right='6'; t.box.foot_left='7'; t.box.foot_vertical='8'; t.box.foot_right='9'; t.add_column('Date'); t.add_column('Title'); t.add_row('Dec 20, 2019', 'Star Wars'); t.add_row('May 25, 2018', 'Solo'); t.show_footer = True; t.footer = 'Footer'; console.print(t)\""
}
{"status": "ok", "stdout": "\u250f\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2533\u2501\u2501\u2501\u2501\u2501\u2501
full
{"status": "ok", "stdout": "\u250f\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2533\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2513\n1 Date         2 Title     3\n\u2521\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2547\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2529\n4 Dec 20, 2019 5 Star Wars 6\n4 May 25, 2018 5 Solo      6\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n7              8           9\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n", "stderr": "", "exit_code": 0}
13submit_patch
{}
{"status": "ok", "patch_size": 1099, "files_changed": 1}
full
{"status": "ok", "patch_size": 1099, "files_changed": 1}

Patch

diff --git a/rich/table.py b/rich/table.py
index fe4054cf..44e457be 100644
--- a/rich/table.py
+++ b/rich/table.py
@@ -775,16 +775,16 @@ class Table(JupyterMixin):
                     _Segment(_box.head_right, border_style),
                     _Segment(_box.head_vertical, border_style),
                 ),
-                (
-                    _Segment(_box.foot_left, border_style),
-                    _Segment(_box.foot_right, border_style),
-                    _Segment(_box.foot_vertical, border_style),
-                ),
                 (
                     _Segment(_box.mid_left, border_style),
                     _Segment(_box.mid_right, border_style),
                     _Segment(_box.mid_vertical, border_style),
                 ),
+                (
+                    _Segment(_box.foot_left, border_style),
+                    _Segment(_box.foot_right, border_style),
+                    _Segment(_box.foot_vertical, border_style),
+                ),
             ]
             if show_edge:
                 yield _Segment(_box.get_top(widths), border_style)

Test output

show
...................                                                      [100%]
19 passed in 0.20s