Coverage for sources/detextive/exceptions.py: 100%

55 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-20 18:02 +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''' Family of exceptions for package API. ''' 

22 

23 

24from . import __ 

25from . import nomina as _nomina 

26 

27 

28class Omniexception( 

29 __.immut.Object, BaseException, 

30 instances_mutables = ( '__cause__', '__context__' ), 

31 instances_visibles = ( 

32 '__cause__', '__context__', __.is_public_identifier ), 

33): 

34 ''' Base for all exceptions raised by package API. ''' 

35 

36 

37class Omnierror( Omniexception, Exception ): 

38 ''' Base for error exceptions raised by package API. ''' 

39 

40 

41class CharsetDetectFailure( Omnierror, TypeError, ValueError ): 

42 

43 def __init__( 

44 self, location: __.Absential[ _nomina.Location ] = __.absent 

45 ) -> None: 

46 message = "Could not detect character set for content" 

47 if not __.is_absent( location ): 

48 message = f"{message} at '{location}'" 

49 super( ).__init__( f"{message}." ) 

50 

51 

52class CharsetInferFailure( Omnierror, TypeError, ValueError ): 

53 

54 def __init__( 

55 self, location: __.Absential[ _nomina.Location ] = __.absent 

56 ) -> None: 

57 message = "Could not infer character set for content" 

58 if not __.is_absent( location ): 

59 message = f"{message} at '{location}'" 

60 super( ).__init__( f"{message}." ) 

61 

62 

63class ContentDecodeImpossibility( Omnierror, TypeError, ValueError ): 

64 

65 def __init__( 

66 self, location: __.Absential[ _nomina.Location ] = __.absent 

67 ) -> None: 

68 message = "Could not decode probable non-textual content" 

69 if not __.is_absent( location ): 

70 message = f"{message} at '{location}'" 

71 super( ).__init__( f"{message}." ) 

72 

73 

74class ContentDecodeFailure( Omnierror, UnicodeError ): 

75 

76 def __init__( 

77 self, 

78 charset: str | __.cabc.Sequence[ str ], 

79 location: __.Absential[ _nomina.Location ] = __.absent, 

80 ) -> None: 

81 message = "Could not decode content" 

82 if not __.is_absent( location ): 

83 message = f"{message} at '{location}'" 

84 if isinstance( charset, str ): charset = ( charset, ) 

85 charsets = ', '.join( f"'{charset_}'" for charset_ in charset ) 

86 message = f"{message} with character sets {charsets}" 

87 super( ).__init__( f"{message}." ) 

88 

89 

90class MimetypeDetectFailure( Omnierror, TypeError, ValueError ): 

91 

92 def __init__( 

93 self, location: __.Absential[ _nomina.Location ] = __.absent 

94 ) -> None: 

95 # TODO: Add 'reason' argument. 

96 message = "Could not detect MIME type for content" 

97 if not __.is_absent( location ): 

98 message = f"{message} at '{location}'" 

99 super( ).__init__( f"{message}." ) 

100 

101 

102class MimetypeInferFailure( Omnierror, TypeError, ValueError ): 

103 

104 def __init__( 

105 self, location: __.Absential[ _nomina.Location ] = __.absent 

106 ) -> None: 

107 message = "Could not infer MIME type for content" 

108 if not __.is_absent( location ): 

109 message = f"{message} at '{location}'" 

110 super( ).__init__( f"{message}." ) 

111 

112 

113class TextInvalidity( Omnierror, TypeError, ValueError ): 

114 

115 def __init__( 

116 self, location: __.Absential[ _nomina.Location ] = __.absent 

117 ) -> None: 

118 # TODO: Add 'reason' argument. 

119 message = "Text is not valid" 

120 if not __.is_absent( location ): 

121 message = f"{message} at '{location}'" 

122 super( ).__init__( f"{message}." ) 

123 

124 

125class TextualMimetypeInvalidity( Omnierror, ValueError ): 

126 

127 def __init__( 

128 self, 

129 mimetype: str, 

130 location: __.Absential[ _nomina.Location ] = __.absent, 

131 ) -> None: 

132 message = "MIME type '{mimetype}' is not textual for content" 

133 if not __.is_absent( location ): 

134 message = f"{message} at '{location}'" 

135 super( ).__init__( f"{message}." )