99
1010from dataclasses import dataclass
1111from functools import cached_property , lru_cache
12- from marshal import dumps , loads
1312from operator import attrgetter
13+ from pickle import dumps , loads
1414from typing import TYPE_CHECKING , Any , Iterable , Mapping
1515
1616import rich .repr
4141)
4242
4343
44+ _get_simple_attributes = attrgetter (
45+ "background" ,
46+ "foreground" ,
47+ "bold" ,
48+ "dim" ,
49+ "italic" ,
50+ "underline" ,
51+ "underline2" ,
52+ "reverse" ,
53+ "strike" ,
54+ "blink" ,
55+ "link" ,
56+ "_meta" ,
57+ )
58+
59+ _get_simple_attributes_sans_color = attrgetter (
60+ "bold" ,
61+ "dim" ,
62+ "italic" ,
63+ "underline" ,
64+ "underline2" ,
65+ "reverse" ,
66+ "strike" ,
67+ "blink" ,
68+ "link" ,
69+ "_meta" ,
70+ )
71+
72+
73+ _get_attributes = attrgetter (
74+ "background" ,
75+ "foreground" ,
76+ "bold" ,
77+ "dim" ,
78+ "italic" ,
79+ "underline" ,
80+ "underline2" ,
81+ "reverse" ,
82+ "strike" ,
83+ "blink" ,
84+ "link" ,
85+ "meta" ,
86+ "_meta" ,
87+ )
88+
89+
4490@rich .repr .auto ()
4591@dataclass (frozen = True )
4692class Style :
@@ -82,19 +128,19 @@ def __rich_repr__(self) -> rich.repr.Result:
82128
83129 @cached_property
84130 def _is_null (self ) -> bool :
85- return (
86- self . foreground is None
87- and self . background is None
88- and self . bold is None
89- and self . dim is None
90- and self . italic is None
91- and self . underline is None
92- and self . underline2 is None
93- and self . reverse is None
94- and self . strike is None
95- and self . blink is None
96- and self . link is None
97- and self . _meta is None
131+ return _get_simple_attributes ( self ) == (
132+ None ,
133+ None ,
134+ None ,
135+ None ,
136+ None ,
137+ None ,
138+ None ,
139+ None ,
140+ None ,
141+ None ,
142+ None ,
143+ None ,
98144 )
99145
100146 @cached_property
@@ -193,30 +239,62 @@ def markup_tag(self) -> str:
193239 @lru_cache (maxsize = 1024 * 4 )
194240 def __add__ (self , other : object | None ) -> Style :
195241 if isinstance (other , Style ):
242+ (
243+ background ,
244+ foreground ,
245+ bold ,
246+ dim ,
247+ italic ,
248+ underline ,
249+ underline2 ,
250+ reverse ,
251+ strike ,
252+ blink ,
253+ link ,
254+ meta ,
255+ _meta ,
256+ ) = _get_attributes (self )
257+
258+ (
259+ other_background ,
260+ other_foreground ,
261+ other_bold ,
262+ other_dim ,
263+ other_italic ,
264+ other_underline ,
265+ other_underline2 ,
266+ other_reverse ,
267+ other_strike ,
268+ other_blink ,
269+ other_link ,
270+ other_meta ,
271+ other__meta ,
272+ ) = _get_attributes (other )
273+
196274 new_style = Style (
197275 (
198- other . background
199- if (self . background is None or self . background .a == 0 )
200- else self . background + other . background
276+ other_background
277+ if (background is None or background .a == 0 )
278+ else background + other_background
201279 ),
202280 (
203- self . foreground
204- if (other . foreground is None or other . foreground .a == 0 )
205- else other . foreground
281+ foreground
282+ if (other_foreground is None or other_foreground .a == 0 )
283+ else other_foreground
206284 ),
207- self . bold if other . bold is None else other . bold ,
208- self . dim if other . dim is None else other . dim ,
209- self . italic if other . italic is None else other . italic ,
210- self . underline if other . underline is None else other . underline ,
211- self . underline2 if other . underline2 is None else other . underline2 ,
212- self . reverse if other . reverse is None else other . reverse ,
213- self . strike if other . strike is None else other . strike ,
214- self . blink if other . blink is None else other . blink ,
215- self . link if other . link is None else other . link ,
285+ bold if other_bold is None else other_bold ,
286+ dim if other_dim is None else other_dim ,
287+ italic if other_italic is None else other_italic ,
288+ underline if other_underline is None else other_underline ,
289+ underline2 if other_underline2 is None else other_underline2 ,
290+ reverse if other_reverse is None else other_reverse ,
291+ strike if other_strike is None else other_strike ,
292+ blink if other_blink is None else other_blink ,
293+ link if other_link is None else other_link ,
216294 (
217- dumps ({** self . meta , ** other . meta })
218- if self . _meta is not None and other . _meta is not None
219- else (self . _meta if other . _meta is None else other . _meta )
295+ dumps ({** meta , ** other_meta })
296+ if _meta is not None and other__meta is not None
297+ else (_meta if other__meta is None else other__meta )
220298 ),
221299 )
222300 return new_style
@@ -349,26 +427,43 @@ def rich_style(self) -> RichStyle:
349427 Returns:
350428 A Rich style object.
351429 """
352- color = None if self .foreground is None else self .background + self .foreground
430+
431+ (
432+ background ,
433+ foreground ,
434+ bold ,
435+ dim ,
436+ italic ,
437+ underline ,
438+ underline2 ,
439+ reverse ,
440+ strike ,
441+ blink ,
442+ link ,
443+ _meta ,
444+ ) = _get_simple_attributes (self )
445+
446+ color = None if foreground is None else background + foreground
447+
353448 return RichStyle (
354449 color = None if color is None else color .rich_color ,
355- bgcolor = None if self . background is None else self . background .rich_color ,
356- bold = self . bold ,
357- dim = self . dim ,
358- italic = self . italic ,
359- underline = self . underline ,
360- underline2 = self . underline2 ,
361- reverse = self . reverse ,
362- strike = self . strike ,
363- blink = self . blink ,
364- link = self . link ,
365- meta = None if self . _meta is None else self .meta ,
450+ bgcolor = None if background is None else background .rich_color ,
451+ bold = bold ,
452+ dim = dim ,
453+ italic = italic ,
454+ underline = underline ,
455+ underline2 = underline2 ,
456+ reverse = reverse ,
457+ strike = strike ,
458+ blink = blink ,
459+ link = link ,
460+ meta = None if _meta is None else self .meta ,
366461 )
367462
368463 def rich_style_with_offset (self , x : int , y : int ) -> RichStyle :
369464 """Get a Rich style with the given offset included in meta.
370465
371- This is used in text seleciton .
466+ This is used in text selection .
372467
373468 Args:
374469 x: X coordinate.
@@ -377,37 +472,41 @@ def rich_style_with_offset(self, x: int, y: int) -> RichStyle:
377472 Returns:
378473 A Rich Style object.
379474 """
380- color = None if self .foreground is None else self .background + self .foreground
475+ print (self )
476+ (
477+ background ,
478+ foreground ,
479+ bold ,
480+ dim ,
481+ italic ,
482+ underline ,
483+ underline2 ,
484+ reverse ,
485+ strike ,
486+ blink ,
487+ link ,
488+ _meta ,
489+ ) = _get_simple_attributes (self )
490+ color = None if foreground is None else background + foreground
381491 return RichStyle (
382492 color = None if color is None else color .rich_color ,
383- bgcolor = None if self . background is None else self . background .rich_color ,
384- bold = self . bold ,
385- dim = self . dim ,
386- italic = self . italic ,
387- underline = self . underline ,
388- underline2 = self . underline2 ,
389- reverse = self . reverse ,
390- strike = self . strike ,
391- blink = self . blink ,
392- link = self . link ,
493+ bgcolor = None if background is None else background .rich_color ,
494+ bold = bold ,
495+ dim = dim ,
496+ italic = italic ,
497+ underline = underline ,
498+ underline2 = underline2 ,
499+ reverse = reverse ,
500+ strike = strike ,
501+ blink = blink ,
502+ link = link ,
393503 meta = {** self .meta , "offset" : (x , y )},
394504 )
395505
396506 @cached_property
397507 def without_color (self ) -> Style :
398508 """The style without any colors."""
399- return Style (
400- bold = self .bold ,
401- dim = self .dim ,
402- italic = self .italic ,
403- underline = self .underline ,
404- underline2 = self .underline2 ,
405- reverse = self .reverse ,
406- strike = self .strike ,
407- blink = self .blink ,
408- link = self .link ,
409- _meta = self ._meta ,
410- )
509+ return Style (None , None , * _get_simple_attributes_sans_color (self ))
411510
412511 @cached_property
413512 def background_style (self ) -> Style :
0 commit comments