← eval5_submission

rich_2725

resolved RESOLVED LOOP PASS · 29 tool calls · 256 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 (30)

#ToolArgumentsResult
1run_command
{
 "command": "grep -rn \"Table\" --include=*.py rich | head -20"
}
{"status": "ok", "stdout": "rich/markup.py:244: from rich.table import Table\nrich/markup.py:246: grid = Table(\"Markup\", \"Result\", padding=(0, 1))\nrich/tab
full
{"status": "ok", "stdout": "rich/markup.py:244:    from rich.table import Table\nrich/markup.py:246:    grid = Table(\"Markup\", \"Result\", padding=(0, 1))\nrich/table.py:40:    \"\"\"Defines a column within a ~Table.\nrich/table.py:151:class Table(JupyterMixin):\nrich/table.py:258:    ) -> \"Table\":\nrich/table.py:269:            Table: A table instance.\nrich/table.py:357:    def padding(self, padding: PaddingDimensions) -> \"Table\":\nrich/table.py:395:            ratio (int, optional): Flexible ratio for the column (requires ``Table.expand`` or ``Table.width``). Defaults to None.\nrich/table.py:925:    from rich.table import Table as Table\nrich/table.py:929:    with timer(\"Table render\"):\nrich/table.py:930:        table = Table(\nrich/table.py:968:        header(\"Example Table\")\nrich/default_styles.py:174:    from rich.table import Table\nrich/default_styles.py:183:    table = Table(\"Name\", \"Styling\")\nrich/scope.py:7:from .table import Table\nrich/scope.py:38:    items_table = Table.grid(padding=(0, 1), expand=False)\nrich/palette.py:8:    from rich.table import Table\nrich/palette.py:20:    def __rich__(self) -> \"Table\":\nrich/palette.py:24:        from rich.table import Table\nrich/palette.py:26:        table = Table(\n", "stderr": "", "exit_code": 0}
2read_file
{
 "filepath": "rich/table.py"
}
{"status": "ok", "filepath": "rich/table.py", "content": "from dataclasses import dataclass, field, replace\nfrom typing import (\n TYPE_CHECKING,\n Dict,\n Ite
full
{"status": "ok", "filepath": "rich/table.py", "content": "from dataclasses import dataclass, field, replace\nfrom typing import (\n    TYPE_CHECKING,\n    Dict,\n    Iterable,\n    List,\n    NamedTuple,\n    Optional,\n    Sequence,\n    Tuple,\n    Union,\n)\n\nfrom . import box, errors\nfrom ._loop import loop_first_last, loop_last\nfrom ._pick import pick_bool\nfrom ._ratio import ratio_distribute, ratio_reduce\nfrom .align import VerticalAlignMethod\nfrom .jupyter import JupyterMixin\nfrom .measure import Measurement\nfrom .padding import Padding, PaddingDimensions\nfrom .protocol import is_renderable\nfrom .segment import Segment\nfrom .style import Style, StyleType\nfrom .text import Text, TextType\n\nif TYPE_CHECKING:\n    from .console import (\n        Console,\n        ConsoleOptions,\n        JustifyMethod,\n        OverflowMethod,\n        RenderableType,\n        RenderResult,\n    )\n\n\n@dataclass\nclass Column:\n    \"\"\"Defines a column within a ~Table.\n\n    Args:\n        title (Union[str, Text], optional): The title of the table rendered at the top. Defaults to None.\n        caption (Union[str, Text], optional): The table caption rendered below. Defaults to None.\n        width (int, optional): The width in characters of the table, or ``None`` to automatically fit. Defaults to None.\n        min_width (Optional[int], optional): The minimum width of the table, or ``None`` for no minimum. Defaults to None.\n        box (box.Box, optional): One of the constants in box.py used to draw the edges (see :ref:`appendix_box`), or ``None`` for no box lines. Defaults to box.HEAVY_HEAD.\n        safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True.\n        padding (PaddingDimensions, optional): Padding for cells (top, right, bottom, left). Defaults to (0, 1).\n        collapse_padding (bool, optional): Enable collapsing of padding around cells. Defaults to False.\n
3-7 ×5read_file
{
 "filepath": "rich/table.py",
 "start_line": "600",
 "end_line": "1000"
}
{"status": "error", "error_type": "FileReadError", "error_message": "'>' not supported between instances of 'int' and 'str'"}
full
{"status": "error", "error_type": "FileReadError", "error_message": "'>' not supported between instances of 'int' and 'str'"}
8run_command
{
 "command": "grep -n \"box\" rich/table.py | grep \"mid\""
}
{"status": "ok", "stdout": "784: _Segment(_box.mid_left, border_style),\n785: _Segment(_box.mid_right, border_style),\n786: _Segment(_box.mid_vertical, border_s
full
{"status": "ok", "stdout": "784:                    _Segment(_box.mid_left, border_style),\n785:                    _Segment(_box.mid_right, border_style),\n786:                    _Segment(_box.mid_vertical, border_style),\n908:                            _box.get_row(widths, \"mid\", edge=show_edge) * leading,\n", "stderr": "", "exit_code": 0}
9run_command
{
 "command": "grep -n \"box\" rich/table.py | grep \"foot\""
}
{"status": "ok", "stdout": "779: _Segment(_box.foot_left, border_style),\n780: _Segment(_box.foot_right, border_style),\n781: _Segment(_box.foot_vertical, borde
full
{"status": "ok", "stdout": "779:                    _Segment(_box.foot_left, border_style),\n780:                    _Segment(_box.foot_right, border_style),\n781:                    _Segment(_box.foot_vertical, border_style),\n866:                        _box.get_row(widths, \"foot\", edge=show_edge), border_style\n", "stderr": "", "exit_code": 0}
10-14 ×5read_file
{
 "end_line": "800",
 "filepath": "rich/table.py",
 "start_line": "750"
}
{"status": "error", "error_type": "FileReadError", "error_message": "'>' not supported between instances of 'int' and 'str'"}
full
{"status": "error", "error_type": "FileReadError", "error_message": "'>' not supported between instances of 'int' and 'str'"}
15run_command
{
 "command": "cat rich/table.py | sed -n '750,800p'"
}
{"status": "ok", "stdout": " )\n row_cells: List[Tuple[_Cell, ...]] = list(zip(*_column_cells))\n _box = (\n self.box.substitute(\n options, safe=pick_bool(self
full
{"status": "ok", "stdout": "        )\n        row_cells: List[Tuple[_Cell, ...]] = list(zip(*_column_cells))\n        _box = (\n            self.box.substitute(\n                options, safe=pick_bool(self.safe_box, console.safe_box)\n            )\n            if self.box\n            else None\n        )\n        _box = _box.get_plain_headed_box() if _box and not self.show_header else _box\n\n        new_line = Segment.line()\n\n        columns = self.columns\n        show_header = self.show_header\n        show_footer = self.show_footer\n        show_edge = self.show_edge\n        show_lines = self.show_lines\n        leading = self.leading\n\n        _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", "stderr": "", "exit_code": 0}
16run_command
{
 "command": "cat rich/table.py | sed -n '760,810p'"
}
{"status": "ok", "stdout": "\n new_line = Segment.line()\n\n columns = self.columns\n show_header = self.show_header\n show_footer = self.show_footer\n show_edg
full
{"status": "ok", "stdout": "\n        new_line = Segment.line()\n\n        columns = self.columns\n        show_header = self.show_header\n        show_footer = self.show_footer\n        show_edge = self.show_edge\n        show_lines = self.show_lines\n        leading = self.leading\n\n        _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}
17run_command
{
 "command": "cat rich/table.py | sed -n '810,920p'"
}
{"status": "ok", "stdout": " 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(w
full
{"status": "ok", "stdout": "            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                _Segment.set_shape(\n                    align_cell(\n                        cell,\n                        _cell.vertical,\n                        width,\n                        get_style(_cell.style) + row_style,\n                    ),\n                    width,\n                    max_height,\n                )\n                for width, _cell, cell
18run_command
{
 "command": "cat rich/table.py | sed -n '770,795p'"
}
{"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", "stderr": "", "exit_code": 0}
19run_command
{
 "command": "cat rich/table.py | sed -n '870,885p'"
}
{"status": "ok", "stdout": "\n # If the column divider is whitespace also style it with the row background\n divider = (\n _divider\n if _divider.text.strip()\n
full
{"status": "ok", "stdout": "\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                        yield left\n                    for last_cell, rendered_cell in loop_last(cells):\n                        yield from rendered_cell[line_no]\n                        if not last_cell:\n                            yield divider\n", "stderr": "", "exit_code": 0}
20run_command
{
 "command": "cat rich/table.py | sed -n '860,875p'"
}
{"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", "stderr": "", "exit_code": 0}
21run_command
{
 "command": "cat rich/table.py | sed -n '865,870p'"
}
{"status": "ok", "stdout": " yield _Segment(\n _box.get_row(widths, \"foot\", edge=show_edge), border_style\n )\n yield new_line\n left, right, _divider = box_s
full
{"status": "ok", "stdout": "                    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", "stderr": "", "exit_code": 0}
22run_command
{
 "command": "cat rich/table.py | sed -n '770,795p'"
}
{"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", "stderr": "", "exit_code": 0}
23edit_file
{
 "filepath": "rich/table.py",
 "new_string": "            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.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            ]",
 "old_string": "            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            ]"
}
{"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}
24run_command
{
 "command": "python3 -c \"\nfrom rich.table import Table\nfrom rich.console import Console\nfrom rich import box\n\nconsole = Console(force_terminal=True)\ntable = Table(show_header=True, show_footer=True)\ntable.add_column('Date')\ntable.add_column('Title')\ntable.add_column('Production')\ntable.add_column('Box Office')\n\ntable.box = box.Box(\n    head_left='1', head_vertical='2', head_right='3',\n    mid_left='4', mid_vertical='5', mid_right='6',\n    foot_left='7', foot_vertical='8', foot_right='9'\n)\n\ntable.add_row('Dec 20, 2019', 'Star Wars: The Rise of Skywalker', '$275,000,000', '$375,126,118')\ntable.add_row('May 25, 2018', 'Solo: A Star Wars Story', '$275,000,000', '$393,151,347')\ntable.add_row('Dec 15, 2017', 'Star Wars Ep. VIII: The Last Jedi', '$262,000,000', '$1,332,539,889')\n\n# We need to set footer for the last row to be considered footer_row\n# In rich.Table, footer is handled by show_footer=True and the last row of row_cells\n# But row_cells is constructed from columns.footer.\n# Let's just check the output.\n\nconsole.print(table)\n\""
}
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"<string>\", line 13, in <module>\n table.box = b
full
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n  File \"<string>\", line 13, in <module>\n    table.box = box.Box(\n                ~~~~~~~^\n        head_left='1', head_vertical='2', head_right='3',\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n        mid_left='4', mid_vertical='5', mid_right='6',\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n        foot_left='7', foot_vertical='8', foot_right='9'\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    )\n    ^\nTypeError: Box.__init__() got an unexpected keyword argument 'head_left'\n", "details": {"stdout": "", "stderr": "Traceback (most recent call last):\n  File \"<string>\", line 13, in <module>\n    table.box = box.Box(\n                ~~~~~~~^\n        head_left='1', head_vertical='2', head_right='3',\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n        mid_left='4', mid_vertical='5', mid_right='6',\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n        foot_left='7', foot_vertical='8', foot_right='9'\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    )\n    ^\nTypeError: Box.__init__() got an unexpected keyword argument 'head_left'\n", "exit_code": 1}}
25read_file
{
 "filepath": "rich/box.py"
}
{"status": "ok", "filepath": "rich/box.py", "content": "import sys\nfrom typing import TYPE_CHECKING, Iterable, List\n\nif sys.version_info >= (3, 8):\n from ty
full
{"status": "ok", "filepath": "rich/box.py", "content": "import sys\nfrom typing import TYPE_CHECKING, Iterable, List\n\nif sys.version_info >= (3, 8):\n    from typing import Literal\nelse:\n    from typing_extensions import Literal  # pragma: no cover\n\n\nfrom ._loop import loop_last\n\nif TYPE_CHECKING:\n    from rich.console import ConsoleOptions\n\n\nclass Box:\n    \"\"\"Defines characters to render boxes.\n\n    \u250c\u2500\u252c\u2510 top\n    \u2502 \u2502\u2502 head\n    \u251c\u2500\u253c\u2524 head_row\n    \u2502 \u2502\u2502 mid\n    \u251c\u2500\u253c\u2524 row\n    \u251c\u2500\u253c\u2524 foot_row\n    \u2502 \u2502\u2502 foot\n    \u2514\u2500\u2534\u2518 bottom\n\n    Args:\n        box (str): Characters making up box.\n        ascii (bool, optional): True if this box uses ascii characters only. Default is False.\n    \"\"\"\n\n    def __init__(self, box: str, *, ascii: bool = False) -> None:\n        self._box = box\n        self.ascii = ascii\n        line1, line2, line3, line4, line5, line6, line7, line8 = box.splitlines()\n        # top\n        self.top_left, self.top, self.top_divider, self.top_right = iter(line1)\n        # head\n        self.head_left, _, self.head_vertical, self.head_right = iter(line2)\n        # head_row\n        (\n            self.head_row_left,\n            self.head_row_horizontal,\n            self.head_row_cross,\n            self.head_row_right,\n        ) = iter(line3)\n\n        # mid\n        self.mid_left, _, self.mid_vertical, self.mid_right = iter(line4)\n        # row\n        self.row_left, self.row_horizontal, self.row_cross, self.row_right = iter(line5)\n        # foot_row\n        (\n            self.foot_row_left,\n            self.foot_row_horizontal,\n            self.foot_row_cross,\n            self.foot_row_right,\n        ) = iter(line6)\n        # foot\n        self.foot_left, _, self.foot_vertical, self.foot_right = iter(line7)\n        # bottom\n        self.bottom_left, self.bottom, self.bo
26run_command
{
 "command": "python3 -c \"\nfrom rich.table import Table\nfrom rich.console import Console\nfrom rich import box\n\nconsole = Console(force_terminal=True)\ntable = Table(show_header=True, show_footer=True)\ntable.add_column('Date')\ntable.add_column('Title')\ntable.add_column('Production')\ntable.add_column('Box Office')\n\n# Create a custom box string\n# Line 1: top\n# Line 2: head\n# Line 3: head_row\n# Line 4: mid\n# Line 5: row\n# Line 6: foot_row\n# Line 7: foot\n# Line 8: bottom\nbox_str = (\n    'TLTTR\\n' + # top\n    '1 2 3\\n' + # head\n    'HRHR\\n' + # head_row\n    '4 5 6\\n' + # mid\n    'RRRR\\n' + # row\n    'FRFR\\n' + # foot_row\n    '7 8 9\\n' + # foot\n    'BLBBR'   # bottom\n)\ntable.box = box.Box(box_str)\n\ntable.add_row('Dec 20, 2019', 'Star Wars: The Rise of Skywalker', '$275,000,000', '$375,126,118')\ntable.add_row('May 25, 2018', 'Solo: A Star Wars Story', '$275,000,000', '$393,151,347')\ntable.add_row('Dec 15, 2017', 'Star Wars Ep. VIII: The Last Jedi', '$262,000,000', '$1,332,539,889')\n\nconsole.print(table)\n\""
}
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"<string>\", line 32, in <module>\n table.box = b
full
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n  File \"<string>\", line 32, in <module>\n    table.box = box.Box(box_str)\n                ~~~~~~~^^^^^^^^^\n  File \"/workspace/rich/box.py\", line 38, in __init__\n    self.top_left, self.top, self.top_divider, self.top_right = iter(line1)\n    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nValueError: too many values to unpack (expected 4)\n", "details": {"stdout": "", "stderr": "Traceback (most recent call last):\n  File \"<string>\", line 32, in <module>\n    table.box = box.Box(box_str)\n                ~~~~~~~^^^^^^^^^\n  File \"/workspace/rich/box.py\", line 38, in __init__\n    self.top_left, self.top, self.top_divider, self.top_right = iter(line1)\n    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nValueError: too many values to unpack (expected 4)\n", "exit_code": 1}}
27run_command
{
 "command": "python3 -c \"\nfrom rich.table import Table\nfrom rich.console import Console\nfrom rich import box\n\nconsole = Console(force_terminal=True)\ntable = Table(show_header=True, show_footer=True)\ntable.add_column('Date')\ntable.add_column('Title')\ntable.add_column('Production')\ntable.add_column('Box Office')\n\nbox_str = (\n    'TLTR\\n' + # top\n    '1 2 3\\n' + # head\n    'HRHR\\n' + # head_row\n    '4 5 6\\n' + # mid\n    'RRRR\\n' + # row\n    'FRFR\\n' + # foot_row\n    '7 8 9\\n' + # foot\n    'BLBR'   # bottom\n)\ntable.box = box.Box(box_str)\n\ntable.add_row('Dec 20, 2019', 'Star Wars: The Rise of Skywalker', '$275,000,000', '$375,126,118')\ntable.add_row('May 25, 2018', 'Solo: A Star Wars Story', '$275,000,000', '$393,151,347')\ntable.add_row('Dec 15, 2017', 'Star Wars Ep. VIII: The Last Jedi', '$262,000,000', '$1,332,539,889')\n\nconsole.print(table)\n\""
}
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"<string>\", line 23, in <module>\n table.box = b
full
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n  File \"<string>\", line 23, in <module>\n    table.box = box.Box(box_str)\n                ~~~~~~~^^^^^^^^^\n  File \"/workspace/rich/box.py\", line 40, in __init__\n    self.head_left, _, self.head_vertical, self.head_right = iter(line2)\n    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nValueError: too many values to unpack (expected 4)\n", "details": {"stdout": "", "stderr": "Traceback (most recent call last):\n  File \"<string>\", line 23, in <module>\n    table.box = box.Box(box_str)\n                ~~~~~~~^^^^^^^^^\n  File \"/workspace/rich/box.py\", line 40, in __init__\n    self.head_left, _, self.head_vertical, self.head_right = iter(line2)\n    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nValueError: too many values to unpack (expected 4)\n", "exit_code": 1}}
28-29 ×2run_command
{
 "command": "python3 -c \"\nfrom rich.table import Table\nfrom rich.console import Console\nfrom rich import box\n\nconsole = Console(force_terminal=True)\ntable = Table(show_header=True, show_footer=True)\ntable.add_column('Date')\ntable.add_column('Title')\ntable.add_column('Production')\ntable.add_column('Box Office')\n\nbox_str = (\n    'TLTR\\n' + # top\n    '123 \\n' + # head (4 chars)\n    'HRHR\\n' + # head_row\n    '456 \\n' + # mid (4 chars)\n    'RRRR\\n' + # row\n    'FRFR\\n' + # foot_row\n    '789 \\n' + # foot (4 chars)\n    'BLBR'   # bottom\n)\ntable.box = box.Box(box_str)\n\ntable.add_row('Dec 20, 2019', 'Star Wars: The Rise of Skywalker', '$275,000,000', '$375,126,118')\ntable.add_row('May 25, 2018', 'Solo: A Star Wars Story', '$275,000,000', '$393,151,347')\ntable.add_row('Dec 15, 2017', 'Star Wars Ep. VIII: The Last Jedi', '$262,000,000', '$1,332,539,889')\n\nconsole.print(table)\n\""
}
{"status": "ok", "stdout": "TLLLLLLLLLLLLLLTLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLTLLLLLLLLLLLLTLLLLLLLLLLLLLLR\n1 Date 3 Title 3 Production 3 Box Office \nHRRRRRR
full
{"status": "ok", "stdout": "TLLLLLLLLLLLLLLTLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLTLLLLLLLLLLLLTLLLLLLLLLLLLLLR\n1 Date         3 Title                             3 Production 3 Box Office    \nHRRRRRRRRRRRRRRHRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRHRRRRRRRRRRRRHRRRRRRRRRRRRRRR\n4 Dec 20, 2019 6 Star Wars: The Rise of Skywalker  6 75,000,000 6 75,126,118    \n4 May 25, 2018 6 Solo: A Star Wars Story           6 75,000,000 6 93,151,347    \n4 Dec 15, 2017 6 Star Wars Ep. VIII: The Last Jedi 6 62,000,000 6 ,332,539,889  \nFRRRRRRRRRRRRRRFRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRFRRRRRRRRRRRRFRRRRRRRRRRRRRRR\n7              9                                   9            9               \nBLLLLLLLLLLLLLLBLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLBLLLLLLLLLLLLBLLLLLLLLLLLLLLR\n", "stderr": "", "exit_code": 0}
30submit_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