This commit is contained in:
Nabeel Shar 2025-12-22 13:59:39 -05:00 committed by GitHub
commit adcd90293f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 51 additions and 0 deletions

View file

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Fixed
- Fixed `inspect()` not respecting `sort=False` parameter for instance attributes https://github.com/Textualize/rich/issues/3432
## [14.2.0] - 2025-10-09
### Changed

View file

@ -93,4 +93,5 @@ The following people have contributed to the development of Rich:
- [chthollyphile](https://github.com/chthollyphile)
- [Jonathan Helmus](https://github.com/jjhelmus)
- [Brandon Capener](https://github.com/bcapener)
- [Nab](https://github.com/Nabeelshar)
- [Alex Zheng](https://github.com/alexzheng111)

View file

@ -135,6 +135,16 @@ class Inspect(JupyterMixin):
obj = self.obj
keys = dir(obj)
total_items = len(keys)
# When sort=False, prefer __dict__ order for instance attributes
if not self.sort and hasattr(obj, "__dict__"):
# Get instance attributes in insertion order
instance_keys = list(vars(obj).keys())
# Get remaining attributes from dir() that aren't in __dict__
class_keys = [key for key in keys if key not in instance_keys]
# Combine: instance attributes first (in order), then class attributes
keys = instance_keys + class_keys
if not self.dunder:
keys = [key for key in keys if not key.startswith("__")]
if not self.private:

View file

@ -501,3 +501,37 @@ def test_object_is_one_of_types(
obj: object, types: Sequence[str], expected_result: bool
):
assert is_object_one_of_types(obj, types) is expected_result
def test_inspect_sort_parameter():
"""Test that sort=False preserves insertion order of instance attributes."""
class Test:
def __init__(self):
self.c = 1
self.b = 2
self.a = 3
test = Test()
# Test sort=False preserves insertion order (c, b, a)
console = Console(width=50, file=io.StringIO(), legacy_windows=False)
inspect(test, console=console, sort=False, value=False, docs=False)
result_unsorted = console.file.getvalue()
# Check that 'c' appears before 'b' and 'b' appears before 'a'
pos_c = result_unsorted.find("c = 1")
pos_b = result_unsorted.find("b = 2")
pos_a = result_unsorted.find("a = 3")
assert pos_c < pos_b < pos_a, "sort=False should preserve insertion order"
# Test sort=True sorts alphabetically (a, b, c)
console = Console(width=50, file=io.StringIO(), legacy_windows=False)
inspect(test, console=console, sort=True, value=False, docs=False)
result_sorted = console.file.getvalue()
# Check that 'a' appears before 'b' and 'b' appears before 'c'
pos_a = result_sorted.find("a = 3")
pos_b = result_sorted.find("b = 2")
pos_c = result_sorted.find("c = 1")
assert pos_a < pos_b < pos_c, "sort=True should sort alphabetically"