From f1fe1ab82a74d26b76549eabcc53682961243603 Mon Sep 17 00:00:00 2001 From: Mateusz Wozny Date: Thu, 29 Feb 2024 09:40:54 +0100 Subject: [PATCH 1/2] adding the ability to display selected attributes --- pyproject.toml | 2 +- rich/__init__.py | 10 +++++++++- rich/_inspect.py | 12 +++++++++++- tests/test_inspect.py | 32 ++++++++++++++++++++++++++++++-- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0e9a3b74e..e4f32c991 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "rich" homepage = "https://github.com/Textualize/rich" documentation = "https://rich.readthedocs.io/en/latest/" -version = "13.7.1" +version = "13.7.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" authors = ["Will McGugan "] license = "MIT" diff --git a/rich/__init__.py b/rich/__init__.py index b631d5449..13e7974d3 100644 --- a/rich/__init__.py +++ b/rich/__init__.py @@ -1,7 +1,7 @@ """Rich text and beautiful formatting in the terminal.""" import os -from typing import IO, TYPE_CHECKING, Any, Callable, Optional, Union +from typing import IO, TYPE_CHECKING, Any, Callable, Optional, Union, Collection from ._extension import load_ipython_extension # noqa: F401 @@ -130,11 +130,15 @@ def inspect( sort: bool = True, all: bool = False, value: bool = True, + attributes: bool = True, + attributes_to_display: Collection[str] = (), ) -> None: """Inspect any Python object. * inspect() to see summarized info. * inspect(, methods=True) to see methods. + * inspect(, attributes=True) to see attributes. + * inspect(, attributes=True, attributes_to_display=["attr1", "attr2"]) to see only specified attributes. * inspect(, help=True) to see full (non-abbreviated) help. * inspect(, private=True) to see private attributes (single underscore). * inspect(, dunder=True) to see attributes beginning with double underscore. @@ -151,6 +155,8 @@ def inspect( sort (bool, optional): Sort attributes alphabetically. Defaults to True. all (bool, optional): Show all attributes. Defaults to False. value (bool, optional): Pretty print value. Defaults to True. + attributes (bool, optional): Show object attributes. Defaults to True. + attributes_to_display (Collection[str], optional): List of attributes to display. Defaults to (). If empty, all attributes are displayed. """ _console = console or get_console() from rich._inspect import Inspect @@ -169,6 +175,8 @@ def inspect( sort=sort, all=all, value=value, + attributes=attributes, + attributes_to_display=attributes_to_display, ) _console.print(_inspect) diff --git a/rich/_inspect.py b/rich/_inspect.py index 30446ceb3..6d50b3a7f 100644 --- a/rich/_inspect.py +++ b/rich/_inspect.py @@ -34,6 +34,8 @@ class Inspect(JupyterMixin): sort (bool, optional): Sort attributes alphabetically. Defaults to True. all (bool, optional): Show all attributes. Defaults to False. value (bool, optional): Pretty print value of object. Defaults to True. + attributes (bool, optional): Show object attributes. Defaults to True. + attributes_to_display (Collection[str], optional): List of attributes to display. Defaults to (). If empty, all attributes are displayed. """ def __init__( @@ -49,14 +51,18 @@ def __init__( sort: bool = True, all: bool = True, value: bool = True, + attributes: bool = True, + attributes_to_display: Collection[str] = (), ) -> None: self.highlighter = ReprHighlighter() self.obj = obj self.title = title or self._make_title(obj) if all: - methods = private = dunder = True + methods = private = dunder = attributes = True self.help = help self.methods = methods + self.attributes = attributes + self.attributes_to_display = attributes_to_display self.docs = docs or help self.private = private or dunder self.dunder = dunder @@ -204,6 +210,10 @@ def safe_getattr(attr_name: str) -> Tuple[Any, Any]: add_row(key_text, _signature_text) else: + if not self.attributes: + continue + if self.attributes_to_display and key not in self.attributes_to_display: + continue add_row(key_text, Pretty(value, highlighter=highlighter)) if items_table.row_count: yield items_table diff --git a/tests/test_inspect.py b/tests/test_inspect.py index a9d553936..021fca125 100644 --- a/tests/test_inspect.py +++ b/tests/test_inspect.py @@ -49,9 +49,18 @@ ) -def render(obj, methods=False, value=False, width=50) -> str: +def render( + obj, methods=False, value=False, width=50, attributes=True, attributes_to_display=() +) -> str: console = Console(file=io.StringIO(), width=width, legacy_windows=False) - inspect(obj, console=console, methods=methods, value=value) + inspect( + obj, + console=console, + methods=methods, + value=value, + attributes=attributes, + attributes_to_display=attributes_to_display, + ) return console.file.getvalue() @@ -208,6 +217,25 @@ def test_inspect_integer(): assert expected == render(1) +def test_inspect_integer_without_attributes(): + expected = ("╭──────────────── ─────────────────╮\n" + "│ int([x]) -> integer │\n" + "│ int(x, base=10) -> integer │\n" + "│ │\n" + "│ 62 attribute(s) not shown. Run │\n" + "│ inspect(inspect) for options. │\n" + "╰────────────────────────────────────────────────╯\n") + assert expected == render(1, attributes=False) + +def test_inspect_integer_with_denominator(): + expected = ("╭────── ───────╮\n" + "│ int([x]) -> integer │\n" + "│ int(x, base=10) -> integer │\n" + "│ │\n" + "│ denominator = 1 │\n" + "╰────────────────────────────╯\n") + assert expected == render(1, attributes=True, attributes_to_display=["denominator"]) + def test_inspect_integer_with_value(): expected = "╭────── ───────╮\n│ int([x]) -> integer │\n│ int(x, base=10) -> integer │\n│ │\n│ ╭────────────────────────╮ │\n│ │ 1 │ │\n│ ╰────────────────────────╯ │\n│ │\n│ denominator = 1 │\n│ imag = 0 │\n│ numerator = 1 │\n│ real = 1 │\n╰────────────────────────────╯\n" value = render(1, value=True) From c13f37a701037d1510664efbf522a77154a65a52 Mon Sep 17 00:00:00 2001 From: Mateusz Wozny Date: Thu, 29 Feb 2024 09:48:16 +0100 Subject: [PATCH 2/2] update changelog and contributors --- CHANGELOG.md | 6 ++++++ CONTRIBUTORS.md | 1 + pyproject.toml | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12512dc3f..765e150c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 + +### Added + +- Add the ability to display selected attributes using rich.inspect + ## [13.7.1] - 2023-02-28 ### Fixed diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 22b1be0db..3f018b69e 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -75,4 +75,5 @@ The following people have contributed to the development of Rich: - [James Addison](https://github.com/jayaddison) - [Pierro](https://github.com/xpierroz) - [Bernhard Wagner](https://github.com/bwagner) +- [Mateusz Wozny](https://github.com/mateusz-wozny) - [Aaron Beaudoin](https://github.com/AaronBeaudoin) diff --git a/pyproject.toml b/pyproject.toml index e4f32c991..0e9a3b74e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "rich" homepage = "https://github.com/Textualize/rich" documentation = "https://rich.readthedocs.io/en/latest/" -version = "13.7.2" +version = "13.7.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" authors = ["Will McGugan "] license = "MIT"