66
77import dataclasses
88import functools
9+ import sys
910from pathlib import Path
10- from typing import Any , Dict
11+ from typing import Any
1112
1213import uproot
1314import uproot .reading
1617from rich .text import Text
1718from rich .tree import Tree
1819
20+ if sys .version_info < (3 , 8 ):
21+ from typing_extensions import TypedDict
22+ else :
23+ from typing import TypedDict
24+
1925console = Console ()
2026
21- __all__ = ("make_tree" , "process_item" , "print_tree" , "UprootEntry" , "console" )
27+ __all__ = (
28+ "make_tree" ,
29+ "process_item" ,
30+ "print_tree" ,
31+ "UprootEntry" ,
32+ "console" ,
33+ "MetaDict" ,
34+ )
2235
2336
2437def __dir__ () -> tuple [str , ...]:
2538 return __all__
2639
2740
41+ class MetaDictRequired (TypedDict , total = True ):
42+ label_text : Text
43+ label_icon : str
44+
45+
46+ class MetaDict (MetaDictRequired , total = False ):
47+ guide_style : str
48+
49+
2850@dataclasses .dataclass
2951class UprootEntry :
3052 path : str
@@ -38,11 +60,18 @@ def is_dir(self) -> bool:
3860 return len (self .item .branches ) > 0
3961 return False
4062
41- def meta (self ) -> dict [ str , Any ] :
63+ def meta (self ) -> MetaDict :
4264 return process_item (self .item )
4365
4466 def label (self ) -> Text :
45- return process_item (self .item )["label" ] # type: ignore[no-any-return]
67+ meta = self .meta ()
68+ return Text .assemble (meta ["label_icon" ], meta ["label_text" ])
69+
70+ def tree_args (self ) -> dict [str , Any ]:
71+ d : dict [str , Text | str ] = {"label" : self .label ()}
72+ if "guide_style" in self .meta ():
73+ d ["guide_style" ] = self .meta ()["guide_style" ]
74+ return d
4675
4776 @property
4877 def children (self ) -> list [UprootEntry ]:
@@ -68,7 +97,7 @@ def make_tree(node: UprootEntry, *, tree: Tree | None = None) -> Tree:
6897 Given an object, build a rich.tree.Tree output.
6998 """
7099
71- tree = Tree (** node .meta ()) if tree is None else tree .add (** node .meta ())
100+ tree = Tree (** node .tree_args ()) if tree is None else tree .add (** node .tree_args ())
72101
73102 for child in node .children :
74103 make_tree (child , tree = tree )
@@ -77,24 +106,23 @@ def make_tree(node: UprootEntry, *, tree: Tree | None = None) -> Tree:
77106
78107
79108@functools .singledispatch
80- def process_item (uproot_object : Any ) -> Dict [ str , Any ] :
109+ def process_item (uproot_object : Any ) -> MetaDict :
81110 """
82111 Given an unknown object, return a rich.tree.Tree output. Specialize for known objects.
83112 """
84113 name = getattr (uproot_object , "name" , "<unnamed>" )
85114 classname = getattr (uproot_object , "classname" , uproot_object .__class__ .__name__ )
86- label = Text .assemble (
87- "❓ " ,
115+ label_text = Text .assemble (
88116 (f"{ name } " , "bold" ),
89117 (classname , "italic" ),
90118 )
91- return { "label" : label }
119+ return MetaDict ( label_icon = "❓ " , label_text = label_text )
92120
93121
94122@process_item .register
95123def _process_item_tfile (
96124 uproot_object : uproot .reading .ReadOnlyDirectory ,
97- ) -> Dict [ str , Any ] :
125+ ) -> MetaDict :
98126 """
99127 Given an TFile, return a rich.tree.Tree output.
100128 """
@@ -109,33 +137,34 @@ def _process_item_tfile(
109137 path_name = escape (path .name )
110138 link_text = f"file://{ path } "
111139
112- label = Text .from_markup (f":file_folder: [link { link_text } ]{ path_name } " )
140+ label_text = Text .from_markup (f"[link { link_text } ]{ path_name } " )
113141
114- return {
115- "label" : label ,
116- "guide_style" : "bold bright_blue" ,
117- }
142+ return MetaDict (
143+ label_icon = "📁 " ,
144+ label_text = label_text ,
145+ guide_style = "bold bright_blue" ,
146+ )
118147
119148
120149@process_item .register
121- def _process_item_ttree (uproot_object : uproot .TTree ) -> Dict [ str , Any ] :
150+ def _process_item_ttree (uproot_object : uproot .TTree ) -> MetaDict :
122151 """
123152 Given an tree, return a rich.tree.Tree output.
124153 """
125- label = Text .assemble (
126- "🌴 " ,
154+ label_text = Text .assemble (
127155 (f"{ uproot_object .name } " , "bold" ),
128156 f"({ uproot_object .num_entries :g} )" ,
129157 )
130158
131- return {
132- "label" : label ,
133- "guide_style" : "bold bright_green" ,
134- }
159+ return MetaDict (
160+ label_icon = "🌴 " ,
161+ label_text = label_text ,
162+ guide_style = "bold bright_green" ,
163+ )
135164
136165
137166@process_item .register
138- def _process_item_tbranch (uproot_object : uproot .TBranch ) -> Dict [ str , Any ] :
167+ def _process_item_tbranch (uproot_object : uproot .TBranch ) -> MetaDict :
139168 """
140169 Given an branch, return a rich.tree.Tree output.
141170 """
@@ -148,29 +177,35 @@ def _process_item_tbranch(uproot_object: uproot.TBranch) -> Dict[str, Any]:
148177 if len (uproot_object .branches ):
149178 icon = "🌿 "
150179
151- label = Text .assemble (
152- icon ,
180+ label_text = Text .assemble (
153181 (f"{ uproot_object .name } " , "bold" ),
154182 (f"{ uproot_object .typename } " , "italic" ),
155183 )
156- return {"label" : label }
184+
185+ return MetaDict (
186+ label_icon = icon ,
187+ label_text = label_text ,
188+ guide_style = "bold bright_green" ,
189+ )
157190
158191
159192@process_item .register
160- def _process_item_th (uproot_object : uproot .behaviors .TH1 .Histogram ) -> Dict [ str , Any ] :
193+ def _process_item_th (uproot_object : uproot .behaviors .TH1 .Histogram ) -> MetaDict :
161194 """
162195 Given an histogram, return a rich.tree.Tree output.
163196 """
164197 icon = "📊 " if uproot_object .kind == "COUNT" else "📈 "
165198 sizes = " × " .join (f"{ len (ax )} " for ax in uproot_object .axes )
166199
167- label = Text .assemble (
168- icon ,
200+ label_text = Text .assemble (
169201 (f"{ uproot_object .name } " , "bold" ),
170202 (f"{ uproot_object .classname } " , "italic" ),
171203 f"({ sizes } )" ,
172204 )
173- return {"label" : label }
205+ return MetaDict (
206+ label_icon = icon ,
207+ label_text = label_text ,
208+ )
174209
175210
176211# pylint: disable-next=redefined-outer-name
0 commit comments