diff --git a/CHANGELOG.md b/CHANGELOG.md index e53205666f..d405c77d62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Python3.14 compatibility https://github.com/Textualize/rich/pull/3861 +### Fixed + +- Fixed exception when callling `inspect` on objects with unusual `__qualname__` attribute https://github.com/Textualize/rich/pull/3894 + ## [14.1.0] - 2025-06-25 ### Changed diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 4b04786b9c..f4c8010c0e 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -94,3 +94,4 @@ The following people have contributed to the development of Rich: - [Jonathan Helmus](https://github.com/jjhelmus) - [Brandon Capener](https://github.com/bcapener) - [Alex Zheng](https://github.com/alexzheng111) +- [Sebastian Speitel](https://github.com/SebastianSpeitel) diff --git a/rich/_inspect.py b/rich/_inspect.py index 27d65cec93..05d5eecc15 100644 --- a/rich/_inspect.py +++ b/rich/_inspect.py @@ -101,6 +101,10 @@ def _get_signature(self, name: str, obj: Any) -> Optional[Text]: signature_text = self.highlighter(_signature) qualname = name or getattr(obj, "__qualname__", name) + if not isinstance(qualname, str): + qualname = getattr(obj, "__name__", name) + if not isinstance(qualname, str): + qualname = name # If obj is a module, there may be classes (which are callable) to display if inspect.isclass(obj): diff --git a/tests/test_inspect.py b/tests/test_inspect.py index 3f6e5b9fe8..d6972fb5ed 100644 --- a/tests/test_inspect.py +++ b/tests/test_inspect.py @@ -404,6 +404,19 @@ class Thing: assert render(module, methods=True) == expected +def test_qualname_in_slots(): + from functools import lru_cache + + @lru_cache + class Klass: + __slots__ = ("__qualname__",) + + try: + inspect(Klass) + except Exception as e: + assert False, f"Class with __qualname__ in __slots__ shouldn't raise {e}" + + @pytest.mark.parametrize( "special_character,expected_replacement", (