[BUG] rich.inspect() does not appear to honor the "sort" keyword argument
- [x] I've checked docs and closed issues for possible solutions.
- [x] I can't find my issue in the FAQ.
Describe the bug
Performing rich.inspect() on a class object with sort=False and sort=True results in the same output for class attributes which are not already naturally in alphabetical order (i.e. both appear sorted alphabetically).
import rich
class Test:
def __init__(self):
self.c = 1
self.b = 2
self.a = 3
test = Test()
rich.inspect(test)
Result:
import rich
class Test:
def __init__(self):
self.c = 1
self.b = 2
self.a = 3
test = Test()
rich.inspect(test, sort=False)
Result:
Platform Python 3.11.3 WSL: Ubuntu-22.04
If you're using Rich in a terminal:
python -m rich.diagnose
pip freeze | grep rich
If you're using Rich in a Jupyter Notebook, run the following snippet in a cell and paste the output in your bug report.
from rich.diagnose import report
report()
╭────────────────────── <class 'rich.console.Console'> ──────────────────────╮
│ A high level console interface. │
│ │
│ ╭────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=115 ColorSystem.TRUECOLOR> │ │
│ ╰────────────────────────────────────────────────────────────────────────╯ │
│ │
│ color_system = 'truecolor' │
│ encoding = 'utf-8' │
│ file = <ipykernel.iostream.OutStream object at 0x7f96e251ab90> │
│ height = 100 │
│ is_alt_screen = False │
│ is_dumb_terminal = False │
│ is_interactive = False │
│ is_jupyter = True │
│ is_terminal = False │
│ legacy_windows = False │
│ no_color = False │
│ options = ConsoleOptions( │
│ size=ConsoleDimensions(width=115, height=100), │
│ legacy_windows=False, │
│ min_width=1, │
│ max_width=115, │
│ is_terminal=False, │
│ encoding='utf-8', │
│ max_height=100, │
│ justify=None, │
│ overflow=None, │
│ no_wrap=False, │
│ highlight=None, │
│ markup=None, │
│ height=None │
│ ) │
│ quiet = False │
│ record = False │
│ safe_box = True │
│ size = ConsoleDimensions(width=115, height=100) │
│ soft_wrap = False │
│ stderr = False │
│ style = None │
│ tab_size = 8 │
│ width = 115 │
╰────────────────────────────────────────────────────────────────────────────╯
╭─── <class 'rich._windows.WindowsConsoleFeatures'> ────╮
│ Windows features available. │
│ │
│ ╭───────────────────────────────────────────────────╮ │
│ │ WindowsConsoleFeatures(vt=False, truecolor=False) │ │
│ ╰───────────────────────────────────────────────────╯ │
│ │
│ truecolor = False │
│ vt = False │
╰───────────────────────────────────────────────────────╯
╭────── Environment Variables ───────╮
│ { │
│ 'TERM': 'xterm-color', │
│ 'COLORTERM': None, │
│ 'CLICOLOR': '1', │
│ 'NO_COLOR': None, │
│ 'TERM_PROGRAM': None, │
│ 'COLUMNS': None, │
│ 'LINES': None, │
│ 'JUPYTER_COLUMNS': None, │
│ 'JUPYTER_LINES': None, │
│ 'JPY_PARENT_PID': None, │
│ 'VSCODE_VERBOSE_LOGGING': None │
│ } │
╰────────────────────────────────────╯
platform="Linux"
rich==13.7.1
Thank you for your issue. Give us a little time to review it.
PS. You might want to check the FAQ if you haven't done so already.
This is an automated reply, generated by FAQtory
Presumably rich.inspect relies on Python's dir where the "resulting list is sorted alphabetically"? If that's the case the sort argument doesn't really make sense!
Presumably
rich.inspectrelies on Python'sdir
It does: https://github.com/Textualize/rich/blob/a060eed19bfa1d6a9159efcc784ae504fa938e17/rich/_inspect.py#L136-L145
Even if the object defines __dir__() and returns unsorted entries, calling dir() on it will sort them. So I agree with your analysis.
Ahh interesting, look at that, they will always be sorted. So then, what behavior should I expect from the rich.inspect sort keyword argument?
I suspect in an older version, the output could be unsorted. But it does seem redundant now.
Removing the option would be sensible, but that would constitute a breaking change.
Out of curiosity, I went looking through the old Python docs and it looks like the results of dir() have been sorted for a long time! https://docs.python.org/release/1.4/lib/node26.html#1169
My goal is to have a natural sort of the values in attributes. as I do not want to have a list like the following
value_0_etc
value_10_etc
value_11_etc
value_1_etc
value_2_etc
...
I want
value_0_etc
value_1_etc
value_2_etc
...
value_10_etc
value_11_etc
So I first though to customize the sort on the output of __dir__, unfortunately the builtin dir internally sorts the output in C.
Then I thought about monkey patching the sort method, and nested closure functions are not trivial monkey patches.
My ideal solution would be to allow sort to take either a bool or a callable key to do the sorting.
if self.sort:
items.sort(key=self.sort if callable(self.sort) else sort_items)
This way I can pass in sort = natsort.natsort_key, to get my desired sorting.
I just implemented my preferred sort using this line.
if self.sort:
items.sort(key=natsort_keygen(key=sort_items))