Coverage for sources/ictr/standard/core.py: 100%

37 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-26 12:43 +0000

1# vim: set filetype=python fileencoding=utf-8: 

2# -*- coding: utf-8 -*- 

3 

4#============================================================================# 

5# # 

6# Licensed under the Apache License, Version 2.0 (the "License"); # 

7# you may not use this file except in compliance with the License. # 

8# You may obtain a copy of the License at # 

9# # 

10# http://www.apache.org/licenses/LICENSE-2.0 # 

11# # 

12# Unless required by applicable law or agreed to in writing, software # 

13# distributed under the License is distributed on an "AS IS" BASIS, # 

14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

15# See the License for the specific language governing permissions and # 

16# limitations under the License. # 

17# # 

18#============================================================================# 

19 

20 

21''' Core data structures and utilities. ''' 

22 

23 

24from . import __ 

25 

26 

27class Auxiliaries( __.immut.DataclassObject ): 

28 ''' Auxiliary functions used by textualizers and interpolation. 

29 

30 Typically used by unit tests to inject mock dependencies, 

31 but can also be used to deeply customize output. 

32 ''' 

33 

34 pid_discoverer: __.typx.Annotated[ 

35 __.typx.Callable[ [ ], int ], 

36 __.ddoc.Doc( ''' Returns ID of current process. ''' ), 

37 ] = __.os.getpid 

38 thread_discoverer: __.typx.Annotated[ 

39 __.typx.Callable[ [ ], __.threads.Thread ], 

40 __.ddoc.Doc( ''' Returns current thread. ''' ), 

41 ] = __.threads.current_thread 

42 time_formatter: __.typx.Annotated[ 

43 __.typx.Callable[ [ str ], str ], 

44 __.ddoc.Doc( ''' Returns current time in specified format. ''' ), 

45 ] = lambda fmt: __.Datetime.now( __.Timezone.utc ).strftime( fmt ) 

46 

47 

48class ColumnsConstraints( __.enum.Enum ): 

49 ''' How to constrain text which exceeds maximum columns. ''' 

50 

51 Complect = __.enum.auto( ) # fold/wrap 

52 Exceed = __.enum.auto( ) # overflow 

53 # Truncate = __.enum.auto( ) # chop/cut 

54 

55 

56class IncisionBoundaries( __.enum.Enum ): 

57 ''' Where to constrain text which exceeds maximum columns. ''' 

58 

59 Nowhere = __.enum.auto( ) 

60 Whitespace = __.enum.auto( ) # horizontal spaces and tabs 

61 Wordsplits = __.enum.auto( ) # hyphens + whitespace 

62 Anywhere = __.enum.auto( ) 

63 

64 

65class Style( __.immut.DataclassObject ): 

66 ''' Style for text. Corresponds to terminal attributes. ''' 

67 

68 bgcolor: __.typx.Optional[ str ] = None 

69 fgcolor: __.typx.Optional[ str ] = None 

70 # TODO: Int flag enum for bold, blink, etc... 

71 

72 

73InterpolantsStylesRegistry: __.typx.TypeAlias = ( 

74 __.accret.Dictionary[ str, Style ] ) 

75 

76 

77class LabelPresentations( __.enum.IntFlag ): 

78 ''' How introduction labels should be presented. ''' 

79 

80 Nothing = 0 

81 Words = __.enum.auto( ) 

82 Emoji = __.enum.auto( ) 

83 

84 

85class ExceptionsConfiguration( __.immut.DataclassObject ): 

86 ''' Configuration pertaining to exceptions. ''' 

87 

88 discoverer: __.typx.Annotated[ 

89 __.typx.Callable[ [ ], __.ExceptionInfo ], 

90 __.ddoc.Doc( ''' Returns information on current exception. ''' ), 

91 ] = __.sys.exc_info 

92 enable_discovery: __.typx.Annotated[ 

93 bool, __.ddoc.Doc( ''' Discover active exception? ''' ) 

94 ] = False 

95 enable_stacktraces: __.typx.Annotated[ 

96 bool, __.ddoc.Doc( ''' Render tracebacks? ''' ) 

97 ] = False 

98 recursive_stacktraces: __.typx.Annotated[ 

99 bool, __.ddoc.Doc( 

100 ''' Render traceback for each exception group member? ''' ), 

101 ] = False 

102 template: __.typx.Annotated[ 

103 str, __.ddoc.Doc( ''' Template for exception message. ''' ) 

104 ] = '[{name}] {message}' 

105 

106 def discover( self ) -> __.typx.Optional[ BaseException ]: 

107 ''' Discovers active exception. ''' 

108 return self.discoverer( )[ 1 ] if self.enable_discovery else None 

109 

110 def interpolate( self, exception: BaseException ) -> tuple[ str, ... ]: 

111 ''' Interpolates exception attributes into message template. ''' 

112 eclass = type( exception ) 

113 name = eclass.__name__ 

114 qname = eclass.__qualname__ 

115 mname = eclass.__module__ 

116 interpolants = dict( 

117 name = name, qname = qname, mname = mname, 

118 message = str( exception ) ) 

119 interpolants[ 'fqname' ] = f"{mname}.{qname}" 

120 return tuple( self.template.format( **interpolants ).split( '\n' ) )