jazzband / prettytable

Display tabular data in a visually appealing ASCII table format
https://pypi.org/project/PrettyTable/
Other
1.37k stars 160 forks source link

Dividers don't render correctly at cell intersections with other styles #237

Open con-f-use opened 1 year ago

con-f-use commented 1 year ago

What did you do?

Set a row divider using an alternate style and print the resulting table.

What did you expect to happen?

$ python t.py
┌─────────┬─────────┬─────────┬─────────┐
│ Field 1 │ Field 2 │ Field 3 │ Field 4 │
├─────────┼─────────┼─────────┼─────────┤
│    11   │    12   │    13   │    14   │
│    21   │    22   │    23   │    24   │
│    31   │    32   │    33   │    34   │
├─────────┼─────────┼─────────┼─────────┤
│    41   │    42   │    43   │    44   │
└─────────┴─────────┴─────────┴─────────┘

What actually happened?

$ python t.py
┌─────────┬─────────┬─────────┬─────────┐
│ Field 1 │ Field 2 │ Field 3 │ Field 4 │
├─────────┼─────────┼─────────┼─────────┤
│    11   │    12   │    13   │    14   │
│    21   │    22   │    23   │    24   │
│    31   │    32   │    33   │    34   │
└─────────┴─────────┴─────────┴─────────┘  <---- should be three-way intersection
│    41   │    42   │    43   │    44   │
└─────────┴─────────┴─────────┴─────────┘

Note the transition into the row below the 2nd divider. The whole 2nd divider should look like the first one (after the "fields" row).

What versions are you using?

# t.py
import prettytable

for style in [
    "DEFAULT", "MSWORD_FRIENDLY", "PLAIN_COLUMNS", "MARKDOWN",
    "ORGMODE", "DOUBLE_BORDER", "SINGLE_BORDER"
]:
    t = prettytable.PrettyTable()
    t.set_style(getattr(prettytable, style))
    t.add_row([11, 12, 13, 14])
    t.add_row([21, 22, 23, 24])
    t.add_row([31, 32, 33, 34])  # also happens with `divider=True`
    t.add_row([41, 42, 43, 44])
    t._dividers[2] = True  # gentle nudge that we need a better non-private API to set dividers after the fact
    print(t, style, "\n\n")     
hugovk commented 1 year ago

To be explicit, here's a reproducer that doesn't use the internal/private _dividers:

import prettytable

t = prettytable.PrettyTable()
t.set_style(prettytable.SINGLE_BORDER)
t.add_row([11,12,13,14])
t.add_row([21,22,23,24])
t.add_row([31,32,33,34], divider=True)
t.add_row([41,42,43,44])
print(t)

Dividers were added in https://github.com/jazzband/prettytable/pull/185, and only tested with the default style.

Here's the results with some other styles (https://github.com/jazzband/prettytable#setting-a-table-style).

DOUBLE_BORDER

Also needs a three-way:

╔═════════╦═════════╦═════════╦═════════╗
║ Field 1 ║ Field 2 ║ Field 3 ║ Field 4 ║
╠═════════╬═════════╬═════════╬═════════╣
║    11   ║    12   ║    13   ║    14   ║
║    21   ║    22   ║    23   ║    24   ║
║    31   ║    32   ║    33   ║    34   ║
╚═════════╩═════════╩═════════╩═════════╝
║    41   ║    42   ║    43   ║    44   ║
╚═════════╩═════════╩═════════╩═════════╝

MARKDOWN

Not sure what to do here:

| Field 1 | Field 2 | Field 3 | Field 4 |
|:-------:|:-------:|:-------:|:-------:|
|    11   |    12   |    13   |    14   |
|    21   |    22   |    23   |    24   |
|    31   |    32   |    33   |    34   |
|:-------:|:-------:|:-------:|:-------:|
|    41   |    42   |    43   |    44   |

Renders like:

Field 1 Field 2 Field 3 Field 4
11 12 13 14
21 22 23 24
31 32 33 34
:-------: :-------: :-------: :-------:
41 42 43 44

ORGMODE

Looks okay?

|---------+---------+---------+---------|
| Field 1 | Field 2 | Field 3 | Field 4 |
|---------+---------+---------+---------|
|    11   |    12   |    13   |    14   |
|    21   |    22   |    23   |    24   |
|    31   |    32   |    33   |    34   |
|---------+---------+---------+---------|
|    41   |    42   |    43   |    44   |
|---------+---------+---------+---------|

PLAIN_COLUMNS

Should maybe omit it here?

Field 1        Field 2        Field 3        Field 4
   11             12             13             14
   21             22             23             24
   31             32             33             34

   41             42             43             44

cc @myheroyuki

con-f-use commented 1 year ago

For plain column's I'd argue that is the expected behavior, because how else would you display a divider. Something like

Field 1        Field 2        Field 3        Field 4
   11             12             13             14
   21             22             23             24
   31             32             33             34
    -              -              -              -            <---- empty line is better in my opinion
   41             42             43             44

might imply "null"-values in that row to some users instead of a separator and a "----------" bar would go against the plain columns style.

In fact, one could argue, that a divider should look a little separate from the field separator, so it might be a feature, not a bug, but then it should be so across all styles. Not arguing for that, in fact, I'd vote against, just putting it out.

rajarshidcoder commented 1 year ago

this bug can be fixed, by changing one line in the main code (around line number 1781) lines.append(self._stringifyhrule(options, where="")) #bottom replace this line of code, it should work