Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Dataclass pretty repr can contain a trailing separator and whitespace #1599

Closed
ochilly opened this issue Oct 16, 2021 · 1 comment · Fixed by #1656
Closed

[BUG] Dataclass pretty repr can contain a trailing separator and whitespace #1599

ochilly opened this issue Oct 16, 2021 · 1 comment · Fixed by #1656

Comments

@ochilly
Copy link

ochilly commented Oct 16, 2021

When rich printing a dataclass:
If the last field has its repr disabled: repr=False
Then, the pretty_repr will contain a trailing comma and whitespace.

To Reproduce

from dataclasses import dataclass, field, fields
import rich
from rich import pretty, _loop

@dataclass
class ExpectedCase:
    first: bool = True
    _none: bool = field(init=False, repr=False)
    last: bool = True

@dataclass
class TrailingComma:
    first: bool = True
    last: bool = True
    _none: bool = field(init=False, repr=False)

if __name__ == '__main__':

    # demonstration
    rich.print(TrailingComma())

    # highlight
    trailing_repr = rich.pretty.pretty_repr(TrailingComma())
    print(' ' * (len(trailing_repr) - 4), '^^ \n')

    # show the issues source
    for example in [ExpectedCase(), TrailingComma()]:
        print('rich.print():  ', end='')
        rich.print(example)
        rich.print(f'rich f-string: {example}')
        print('builtin print:', example, '\n')

        print(f'dataclass Fields: ')
        example_fields = fields(example)
        for field in example_fields:
            rich.print(f'    {field.name!r:7} -> repr={field.repr}')
        print()

        print('rich._loop.loop_last() yields: ')
        for last, field in rich._loop.loop_last(example_fields):
            rich.print(f'    {last=!r:5}, field={field.name!r}')
        print()

        # possible to have no node marked as the last:
        print('rich.pretty.traverse() returns Nodes: ')
        for node in rich.pretty.traverse(example).children:
            rich.print(f'    {node.key_repr=}, {node.last=}')
        print('\n')

Outputs:

TrailingComma(first=True, last=True, )
                                   ^^

rich.print():  ExpectedCase(first=True, last=True)
rich f-string: ExpectedCase(first=True, last=True)
builtin print: ExpectedCase(first=True, last=True)

dataclass Fields:
    'first' -> repr=True
    '_none' -> repr=False
    'last'  -> repr=True

rich._loop.loop_last() yields:
    last=False, field='first'
    last=False, field='_none'
    last=True , field='last'

rich.pretty.traverse() returns Nodes:
    node.key_repr='first', node.last=False
    node.key_repr='last', node.last=True


rich.print():  TrailingComma(first=True, last=True, )
rich f-string: TrailingComma(first=True, last=True)
builtin print: TrailingComma(first=True, last=True)

dataclass Fields:
    'first' -> repr=True
    'last'  -> repr=True
    '_none' -> repr=False

rich._loop.loop_last() yields:
    last=False, field='first'
    last=False, field='last'
    last=True , field='_none'

rich.pretty.traverse() returns Nodes:
    node.key_repr='first', node.last=False
    node.key_repr='last', node.last=False

Platform
Windows, Windows Terminal/Powershell 7

Diagnose
I may ask you to cut and paste the output of the following commands. It may save some time if you do it now.

python -m rich.diagnose

╭───────────────────────── <class 'rich.console.Console'> ─────────────────────────╮
│ A high level console interface.                                                  │
│                                                                                  │
│ ╭──────────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=178 ColorSystem.TRUECOLOR>                                    │ │
│ ╰──────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                  │
│     color_system = 'truecolor'                                                   │
│         encoding = 'utf-8'                                                       │
│             file = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> │
│           height = 22                                                            │
│    is_alt_screen = False                                                         │
│ is_dumb_terminal = False                                                         │
│   is_interactive = True                                                          │
│       is_jupyter = False                                                         │
│      is_terminal = True                                                          │
│   legacy_windows = False                                                         │
│         no_color = False                                                         │
│          options = ConsoleOptions(                                               │
│                        size=ConsoleDimensions(width=178, height=22),             │
│                        legacy_windows=False,                                     │
│                        min_width=1,                                              │
│                        max_width=178,                                            │
│                        is_terminal=True,                                         │
│                        encoding='utf-8',                                         │
│                        max_height=22,                                            │
│                        justify=None,                                             │
│                        overflow=None,                                            │
│                        no_wrap=False,                                            │
│                        highlight=None,                                           │
│                        markup=None,                                              │
│                        height=None                                               │
│                    )                                                             │
│            quiet = False                                                         │
│           record = False                                                         │
│         safe_box = True                                                          │
│             size = ConsoleDimensions(width=178, height=22)                       │
│        soft_wrap = False                                                         │
│           stderr = False                                                         │
│            style = None                                                          │
│         tab_size = 8                                                             │
│            width = 178                                                           │
╰──────────────────────────────────────────────────────────────────────────────────╯

python -m rich._windows

platform="Windows"
WindowsConsoleFeatures(vt=True, truecolor=True)

pip freeze | grep rich

grep: The term 'grep' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
ochilly added a commit to ochilly/rich that referenced this issue Oct 16, 2021
Dataclass pretty repr can contain a trailing separator and whitespace

Fixed pretty_repr() for dataclass fields with repr=False.
Fixed corresponding test.
@github-actions
Copy link

github-actions bot commented Nov 7, 2021

Did I solve your problem?

Consider sponsoring the ongoing work on Rich and Textual.

Or buy me a coffee to say thanks.

Will McGugan

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Nov 14, 2021
10.13.0

Added

Added json.dumps parameters to print_json Textualize/rich#1638

Fixed

Fixed an edge case bug when console module try to detect if they are in a tty at the end of a pytest run
Fixed a bug where logging handler raises an exception when running with pythonw (related to https://bugs.python.org/issue13807)
Fixed issue with TERM env vars that have more than one hyphen Textualize/rich#1640
Fixed missing new line after progress bar when terminal is not interactive Textualize/rich#1606
Fixed exception in IPython when disabling pprint with %pprint Textualize/rich#1646
Fixed issue where values longer than the console width produced invalid JSON Textualize/rich#1653
Fixes trailing comma when pretty printing dataclass with last field repr=False Textualize/rich#1599

Changed

Markdown codeblocks now word-wrap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant