From 381f5dcdc09469864d3797877bceb7762eaaa635 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 14 Jul 2025 15:20:03 -0700 Subject: [PATCH 1/3] feat: support RNTuple Signed-off-by: Henry Schreiner --- src/uproot_browser/plot.py | 2 +- src/uproot_browser/tree.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/uproot_browser/plot.py b/src/uproot_browser/plot.py index bb5fc1b..0cf5a49 100644 --- a/src/uproot_browser/plot.py +++ b/src/uproot_browser/plot.py @@ -51,7 +51,7 @@ def plot(tree: Any) -> None: @plot.register -def plot_branch(tree: uproot.TBranch) -> None: +def plot_branch(tree: uproot.TBranch | uproot.models.RNTuple.RField) -> None: """ Plot a single tree branch. """ diff --git a/src/uproot_browser/tree.py b/src/uproot_browser/tree.py index 946a9c6..491d34c 100644 --- a/src/uproot_browser/tree.py +++ b/src/uproot_browser/tree.py @@ -51,11 +51,14 @@ def is_dir(item: Any) -> bool: # noqa: ARG001 def _(item: uproot.reading.ReadOnlyDirectory) -> Literal[True]: # noqa: ARG001 return True - @is_dir.register def _(item: uproot.behaviors.TBranch.HasBranches) -> bool: return len(item.branches) > 0 +@is_dir.register +def _(item: uproot.behaviors.RNTuple.HasFields) -> bool: + return len(item.keys()) > 0 + def get_children(item: Mapping[str, Any]) -> set[str]: return { @@ -153,7 +156,7 @@ def _process_item_tfile( @process_item.register -def _process_item_ttree(uproot_object: uproot.TTree) -> MetaDict: +def _process_item_ttree(uproot_object: uproot.TTree | uproot.behaviors.RNTuple.RNTuple) -> MetaDict: """ Given an tree, return a rich.tree.Tree output. """ From 3aa67d7e94802ec099793fd7145d090d413654e7 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Mon, 14 Jul 2025 20:56:02 -0700 Subject: [PATCH 2/3] fix: support Python before 3.11 Signed-off-by: Henry Schreiner --- src/uproot_browser/plot.py | 4 +++- src/uproot_browser/tree.py | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/uproot_browser/plot.py b/src/uproot_browser/plot.py index 0cf5a49..623f6f3 100644 --- a/src/uproot_browser/plot.py +++ b/src/uproot_browser/plot.py @@ -50,7 +50,9 @@ def plot(tree: Any) -> None: raise RuntimeError(msg) -@plot.register +# Simpler in Python 3.11+ +@plot.register(uproot.TBranch) +@plot.register(uproot.models.RNTuple.RField) def plot_branch(tree: uproot.TBranch | uproot.models.RNTuple.RField) -> None: """ Plot a single tree branch. diff --git a/src/uproot_browser/tree.py b/src/uproot_browser/tree.py index 491d34c..3114f9a 100644 --- a/src/uproot_browser/tree.py +++ b/src/uproot_browser/tree.py @@ -51,10 +51,12 @@ def is_dir(item: Any) -> bool: # noqa: ARG001 def _(item: uproot.reading.ReadOnlyDirectory) -> Literal[True]: # noqa: ARG001 return True + @is_dir.register def _(item: uproot.behaviors.TBranch.HasBranches) -> bool: return len(item.branches) > 0 + @is_dir.register def _(item: uproot.behaviors.RNTuple.HasFields) -> bool: return len(item.keys()) > 0 @@ -155,8 +157,12 @@ def _process_item_tfile( ) -@process_item.register -def _process_item_ttree(uproot_object: uproot.TTree | uproot.behaviors.RNTuple.RNTuple) -> MetaDict: +# Python 3.11 can just use `|` directly for register +@process_item.register(uproot.TTree) +@process_item.register(uproot.behaviors.RNTuple.RNTuple) +def _process_item_ttree( + uproot_object: uproot.TTree | uproot.behaviors.RNTuple.RNTuple, +) -> MetaDict: """ Given an tree, return a rich.tree.Tree output. """ From 6b9ea28fd3ab42e9f3ebaba7ba86511c20d907f1 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 15 Jul 2025 15:12:28 -0700 Subject: [PATCH 3/3] fix: conditional RNtuple Signed-off-by: Henry Schreiner --- src/uproot_browser/plot.py | 5 ++++- src/uproot_browser/tree.py | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/uproot_browser/plot.py b/src/uproot_browser/plot.py index 623f6f3..52a3724 100644 --- a/src/uproot_browser/plot.py +++ b/src/uproot_browser/plot.py @@ -52,7 +52,6 @@ def plot(tree: Any) -> None: # Simpler in Python 3.11+ @plot.register(uproot.TBranch) -@plot.register(uproot.models.RNTuple.RField) def plot_branch(tree: uproot.TBranch | uproot.models.RNTuple.RField) -> None: """ Plot a single tree branch. @@ -71,6 +70,10 @@ def plot_branch(tree: uproot.TBranch | uproot.models.RNTuple.RField) -> None: plt.title(make_hist_title(tree, histogram)) +if hasattr(uproot.models, "RNTuple") and hasattr(uproot.models.RNTuple, "RField"): + plot.register(uproot.models.RNTuple.RField)(plot_branch) # type: ignore[no-untyped-call] + + @plot.register def plot_hist(tree: uproot.behaviors.TH1.Histogram) -> None: """ diff --git a/src/uproot_browser/tree.py b/src/uproot_browser/tree.py index 3114f9a..414d77b 100644 --- a/src/uproot_browser/tree.py +++ b/src/uproot_browser/tree.py @@ -57,9 +57,13 @@ def _(item: uproot.behaviors.TBranch.HasBranches) -> bool: return len(item.branches) > 0 -@is_dir.register -def _(item: uproot.behaviors.RNTuple.HasFields) -> bool: - return len(item.keys()) > 0 +if hasattr(uproot.behaviors, "RNTuple") and hasattr( + uproot.behaviors.RNTuple, "HasFields" +): + + @is_dir.register + def _(item: uproot.behaviors.RNTuple.HasFields) -> bool: + return len(item.keys()) > 0 def get_children(item: Mapping[str, Any]) -> set[str]: @@ -159,7 +163,6 @@ def _process_item_tfile( # Python 3.11 can just use `|` directly for register @process_item.register(uproot.TTree) -@process_item.register(uproot.behaviors.RNTuple.RNTuple) def _process_item_ttree( uproot_object: uproot.TTree | uproot.behaviors.RNTuple.RNTuple, ) -> MetaDict: @@ -178,6 +181,12 @@ def _process_item_ttree( ) +if hasattr(uproot.behaviors, "RNTuple") and hasattr( + uproot.behaviors.RNTuple, "HasFields" +): + process_item.register(uproot.behaviors.RNTuple.RNTuple)(_process_item_ttree) # type: ignore[no-untyped-call] + + @process_item.register def _process_item_tbranch(uproot_object: uproot.TBranch) -> MetaDict: """