← eval8_submission_v1a

rich_2725

resolved RESOLVED LOOP PASS · 26 tool calls · 259 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 (27)

#ToolArgumentsResult
1run_command
{
 "command": "grep -rn \"box\" --include=*.py rich | grep \"table\" | head -20"
}
{"status": "ok", "stdout": "rich/table.py:14:from . import box, errors\nrich/table.py:47: box (box.Box, optional): One of the constants in box.py used to draw t
full
{"status": "ok", "stdout": "rich/table.py:14:from . import box, errors\nrich/table.py:47:        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.\nrich/table.py:48:        safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True.\nrich/table.py:55:        show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.\nrich/table.py:160:        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.\nrich/table.py:161:        safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True.\nrich/table.py:168:        show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.\nrich/table.py:193:        box: Optional[box.Box] = box.HEAVY_HEAD,\nrich/table.py:194:        safe_box: Optional[bool] = None,\nrich/table.py:221:        self.box = box\nrich/table.py:222:        self.safe_box = safe_box\nrich/table.py:273:            box=None,\nrich/table.py:297:        if self.box and self.show_edge:\nrich/table.py:299:        if self.box:\nrich/table.py:752:        _box = (\nrich/table.py:753:            self.box.substitute(\nrich/table.py:754:                options, safe=pick_bool(self.safe_box, console.safe_box)\nrich/table.py:756:            if self.box\nrich/table.py:759:        _box = _box.get_plain_headed_box() if _box and not self.show_header else _box\nrich/table.py:771:        if _box:\n", "stderr": "", "exit_code": 0}
2run_command
{
 "command": "grep -n \"box\" rich/table.py | grep -C 5 \"render\" | head -20"
}
{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}
3run_command
{
 "command": "grep -n \"box\" rich/table.py | grep -C 5 \"render\" | tail -20"
}
{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "", "stderr": "", "exit_code": 0}
4-6 ×3run_command
{
 "command": "grep -n \"box\" rich/table.py | grep -C 5 \"render\""
}
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
full
{"status": "error", "error_type": "CommandError", "error_message": "", "details": {"stdout": "", "stderr": "", "exit_code": 1}}
7run_command
{
 "command": "grep -n \"box\" rich/table.py | grep -v \"import\" | head -20"
}
{"status": "ok", "stdout": "47: 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
full
{"status": "ok", "stdout": "47:        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.\n48:        safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True.\n55:        show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.\n160:        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.\n161:        safe_box (Optional[bool], optional): Disable box characters that don't display on windows legacy terminal with *raster* fonts. Defaults to True.\n168:        show_edge (bool, optional): Draw a box around the outside of the table. Defaults to True.\n193:        box: Optional[box.Box] = box.HEAVY_HEAD,\n194:        safe_box: Optional[bool] = None,\n221:        self.box = box\n222:        self.safe_box = safe_box\n273:            box=None,\n297:        if self.box and self.show_edge:\n299:        if self.box:\n752:        _box = (\n753:            self.box.substitute(\n754:                options, safe=pick_bool(self.safe_box, console.safe_box)\n756:            if self.box\n759:        _box = _box.get_plain_headed_box() if _box and not self.show_header else _box\n771:        if _box:\n772:            box_segments = [\n", "stderr": "", "exit_code": 0}
8run_command
{
 "command": "sed -n '750,850p' rich/table.py"
}
{"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            row = (\n                self.rows[index - show_header]\n                if (not header_row and not footer_row)\n        
9run_command
{
 "command": "sed -n '851,950p' rich/table.py"
}
{"status": "ok", "stdout": " 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, _
full
{"status": "ok", "stdout": "                    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, 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                        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                    if show_edge:\n                        yield right\n                    yield new_line\n            else:\n                for line_no in range(max_height):\n                    for rendered_cell in cells:\n                        yield from rendered_cell[line_no]\n                    yield new_line\n            if _box and first and show_header:\n                yield _Segment(\n                    _box.get_row(widths, \"head\", edge=show_edge), border_style\n                )\n                yield ne
10run_command
{
 "command": "sed -n '772,800p' rich/table.py"
}
{"status": "ok", "stdout": " box_segments = [\n (\n _Segment(_box.head_left, border_style),\n _Segment(_box.head_right, border_style),\n _Segment(_box.head_vert
full
{"status": "ok", "stdout": "            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}
11run_command
{
 "command": "sed -n '870,880p' rich/table.py"
}
{"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", "stderr": "", "exit_code": 0}
12run_command
{
 "command": "sed -n '865,875p' rich/table.py"
}
{"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                # 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}
13run_command
{
 "command": "sed -n '866,868p' rich/table.py"
}
{"status": "ok", "stdout": " _box.get_row(widths, \"foot\", edge=show_edge), border_style\n )\n yield new_line\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "                        _box.get_row(widths, \"foot\", edge=show_edge), border_style\n                    )\n                    yield new_line\n", "stderr": "", "exit_code": 0}
14run_command
{
 "command": "sed -n '869,869p' rich/table.py"
}
{"status": "ok", "stdout": " left, right, _divider = box_segments[0 if first else (2 if last else 1)]\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "                left, right, _divider = box_segments[0 if first else (2 if last else 1)]\n", "stderr": "", "exit_code": 0}
15run_command
{
 "command": "cat <<EOF > /tmp/repro.py\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich import box\n\nclass CustomBox(box.Box):\n    head_left = '1'\n    head_vertical = '2'\n    head_right = '3'\n    mid_left = '4'\n    mid_vertical = '5'\n    mid_right = '6'\n    foot_left = '7'\n    foot_vertical = '8'\n    foot_right = '9'\n    \n    def get_top(self, widths): return \"+\" + \"-\"*sum(widths) + \"+\"\n    def get_bottom(self, widths): return \"+\" + \"-\"*sum(widths) + \"+\"\n    def get_row(self, widths, type, edge=True):\n        if type == \"head\": return \"HEAD\"\n        if type == \"foot\": return \"FOOT\"\n        return \"MID\"\n\nconsole = Console(force_terminal=True, width=100)\ntable = Table(box=CustomBox())\ntable.add_column(\"A\")\ntable.add_column(\"B\")\ntable.add_row(\"1\", \"2\")\ntable.add_row(\"3\", \"4\")\ntable.add_row(\"5\", \"6\")\n\nconsole.print(table)\nEOF\npython3 /tmp/repro.py\n"
}
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"/tmp/repro.py\", line 24, in <module>\n table =
full
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n  File \"/tmp/repro.py\", line 24, in <module>\n    table = Table(box=CustomBox())\n                      ~~~~~~~~~^^\nTypeError: Box.__init__() missing 1 required positional argument: 'box'\n", "details": {"stdout": "", "stderr": "Traceback (most recent call last):\n  File \"/tmp/repro.py\", line 24, in <module>\n    table = Table(box=CustomBox())\n                      ~~~~~~~~~^^\nTypeError: Box.__init__() missing 1 required positional argument: 'box'\n", "exit_code": 1}}
16run_command
{
 "command": "grep -n \"class Box\" rich/box.py"
}
{"status": "ok", "stdout": "16:class Box:\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "16:class Box:\n", "stderr": "", "exit_code": 0}
17run_command
{
 "command": "sed -n '16,40p' rich/box.py"
}
{"status": "ok", "stdout": "class Box:\n \"\"\"Defines characters to render boxes.\n\n \u250c\u2500\u252c\u2510 top\n \u2502 \u2502\u2502 head\n \u251c\u2500\u2
full
{"status": "ok", "stdout": "class 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", "stderr": "", "exit_code": 0}
18run_command
{
 "command": "cat <<EOF > /tmp/repro.py\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich import box\n\nclass CustomBox(box.Box):\n    def __init__(self, box_str, *, ascii=False):\n        super().__init__(box_str, ascii=ascii)\n        self.head_left = '1'\n        self.head_vertical = '2'\n        self.head_right = '3'\n        self.mid_left = '4'\n        self.mid_vertical = '5'\n        self.mid_right = '6'\n        self.foot_left = '7'\n        self.foot_vertical = '8'\n        self.foot_right = '9'\n    \n    def get_top(self, widths): return \"+\" + \"-\"*sum(widths) + \"+\"\n    def get_bottom(self, widths): return \"+\" + \"-\"*sum(widths) + \"+\"\n    def get_row(self, widths, type, edge=True):\n        if type == \"head\": return \"HEAD\"\n        if type == \"foot\": return \"FOOT\"\n        return \"MID\"\n\nconsole = Console(force_terminal=True, width=100)\n# Use a dummy box string that has 8 lines\ndummy_box = \"\\n\".join([\"\" for _ in range(8)])\ntable = Table(box=CustomBox(dummy_box))\ntable.add_column(\"A\")\ntable.add_column(\"B\")\ntable.add_row(\"1\", \"2\")\ntable.add_row(\"3\", \"4\")\ntable.add_row(\"5\", \"6\")\n\nconsole.print(table)\nEOF\npython3 /tmp/repro.py\n"
}
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n File \"/tmp/repro.py\", line 28, in <module>\n table =
full
{"status": "error", "error_type": "CommandError", "error_message": "Traceback (most recent call last):\n  File \"/tmp/repro.py\", line 28, in <module>\n    table = Table(box=CustomBox(dummy_box))\n                      ~~~~~~~~~^^^^^^^^^^^\n  File \"/tmp/repro.py\", line 7, in __init__\n    super().__init__(box_str, ascii=ascii)\n    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^\n  File \"/workspace/rich/box.py\", line 36, in __init__\n    line1, line2, line3, line4, line5, line6, line7, line8 = box.splitlines()\n    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nValueError: not enough values to unpack (expected 8, got 7)\n", "details": {"stdout": "", "stderr": "Traceback (most recent call last):\n  File \"/tmp/repro.py\", line 28, in <module>\n    table = Table(box=CustomBox(dummy_box))\n                      ~~~~~~~~~^^^^^^^^^^^\n  File \"/tmp/repro.py\", line 7, in __init__\n    super().__init__(box_str, ascii=ascii)\n    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^\n  File \"/workspace/rich/box.py\", line 36, in __init__\n    line1, line2, line3, line4, line5, line6, line7, line8 = box.splitlines()\n    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nValueError: not enough values to unpack (expected 8, got 7)\n", "exit_code": 1}}
19run_command
{
 "command": "cat <<EOF > /tmp/repro.py\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich import box\n\nclass CustomBox(box.Box):\n    def __init__(self, box_str, *, ascii=False):\n        super().__init__(box_str, ascii=ascii)\n        self.head_left = '1'\n        self.head_vertical = '2'\n        self.head_right = '3'\n        self.mid_left = '4'\n        self.mid_vertical = '5'\n        self.mid_right = '6'\n        self.foot_left = '7'\n        self.foot_vertical = '8'\n        self.foot_right = '9'\n    \n    def get_top(self, widths): return \"+\" + \"-\"*sum(widths) + \"+\"\n    def get_bottom(self, widths): return \"+\" + \"-\"*sum(widths) + \"+\"\n    def get_row(self, widths, type, edge=True):\n        if type == \"head\": return \"HEAD\"\n        if type == \"foot\": return \"FOOT\"\n        return \"MID\"\n\nconsole = Console(force_terminal=True, width=100)\ndummy_box = \"\\n\".join([\"\" for _ in range(8)])\n# Wait, splitlines() on \"\\n\\n\\n\\n\\n\\n\\n\\n\" might not give 8.\n# Let's use a real box string.\nreal_box = box.HEAVY_HEAD._box\ntable = Table(box=CustomBox(real_box))\ntable.add_column(\"A\")\ntable.add_column(\"B\")\ntable.add_row(\"1\", \"2\")\ntable.add_row(\"3\", \"4\")\ntable.add_row(\"5\", \"6\")\n\nconsole.print(table)\nEOF\npython3 /tmp/repro.py\n"
}
{"status": "ok", "stdout": "+------+\n1 A 2 B 3\nHEAD\n7 1 8 2 9\n7 3 8 4 9\n4 5 5 6 6\n+------+\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "+------+\n1 A 2 B 3\nHEAD\n7 1 8 2 9\n7 3 8 4 9\n4 5 5 6 6\n+------+\n", "stderr": "", "exit_code": 0}
20run_command
{
 "command": "cat <<EOF > /tmp/repro.py\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich import box\n\nclass CustomBox(box.Box):\n    def __init__(self, box_str, *, ascii=False):\n        super().__init__(box_str, ascii=ascii)\n        self.head_left = '1'\n        self.head_vertical = '2'\n        self.head_right = '3'\n        self.mid_left = '4'\n        self.mid_vertical = '5'\n        self.mid_right = '6'\n        self.foot_left = '7'\n        self.foot_vertical = '8'\n        self.foot_right = '9'\n    \n    def get_top(self, widths): return \"+\" + \"-\"*sum(widths) + \"+\"\n    def get_bottom(self, widths): return \"+\" + \"-\"*sum(widths) + \"+\"\n    def get_row(self, widths, type, edge=True):\n        if type == \"head\": return \"HEAD\"\n        if type == \"foot\": return \"FOOT\"\n        return \"MID\"\n\nconsole = Console(force_terminal=True, width=100)\nreal_box = box.HEAVY_HEAD._box\ntable = Table(box=CustomBox(real_box))\ntable.add_column(\"A\")\ntable.add_column(\"B\")\ntable.add_row(\"1\", \"2\")\ntable.add_row(\"3\", \"4\")\ntable.add_row(\"5\", \"6\")\n\nconsole.print(table)\nEOF\npython3 /tmp/repro.py\n"
}
{"status": "ok", "stdout": "+------+\n1 A 2 B 3\nHEAD\n7 1 8 2 9\n7 3 8 4 9\n4 5 5 6 6\n+------+\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "+------+\n1 A 2 B 3\nHEAD\n7 1 8 2 9\n7 3 8 4 9\n4 5 5 6 6\n+------+\n", "stderr": "", "exit_code": 0}
21run_command
{
 "command": "sed -n '772,795p' rich/table.py"
}
{"status": "ok", "stdout": " box_segments = [\n (\n _Segment(_box.head_left, border_style),\n _Segment(_box.head_right, border_style),\n _Segment(_box.head_vert
full
{"status": "ok", "stdout": "            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}
22run_command
{
 "command": "sed -n '869,869p' rich/table.py"
}
{"status": "ok", "stdout": " left, right, _divider = box_segments[0 if first else (2 if last else 1)]\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "                left, right, _divider = box_segments[0 if first else (2 if last else 1)]\n", "stderr": "", "exit_code": 0}
23run_command
{
 "command": "sed -n '865,875p' rich/table.py"
}
{"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                # 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}
24edit_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}
25run_command
{
 "command": "python3 /tmp/repro.py"
}
{"status": "ok", "stdout": "+------+\n1 A 2 B 3\nHEAD\n4 1 5 2 6\n4 3 5 4 6\n7 5 8 6 9\n+------+\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": "+------+\n1 A 2 B 3\nHEAD\n4 1 5 2 6\n4 3 5 4 6\n7 5 8 6 9\n+------+\n", "stderr": "", "exit_code": 0}
26run_command
{
 "command": "python3 -m pytest tests/test_table.py -q -k \"box\""
}
{"status": "ok", "stdout": "..... [100%]\n5 passed, 10 deselected in 0.15s\n", "stderr": "", "exit_code": 0}
full
{"status": "ok", "stdout": ".....                                                                    [100%]\n5 passed, 10 deselected in 0.15s\n", "stderr": "", "exit_code": 0}
27submit_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