Coverage for sources/ictruck/printers.py: 100%

24 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2025-06-06 03:29 +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''' Printers, printer factories, and auxiliary functions and types. ''' 

22 

23 

24from __future__ import annotations 

25 

26import colorama as _colorama 

27 

28from . import __ 

29from . import configuration as _cfg 

30from . import exceptions as _exceptions 

31 

32 

33_validate_arguments = ( 

34 __.validate_arguments( 

35 globalvars = globals( ), 

36 errorclass = _exceptions.ArgumentClassInvalidity ) ) 

37 

38 

39Printer: __.typx.TypeAlias = __.cabc.Callable[ [ str ], None ] 

40PrinterFactory: __.typx.TypeAlias = ( 

41 __.cabc.Callable[ [ str, _cfg.Flavor ], Printer ] ) 

42PrinterFactoryUnion: __.typx.TypeAlias = __.io.TextIOBase | PrinterFactory 

43 

44 

45@_validate_arguments 

46def produce_simple_printer( 

47 target: __.io.TextIOBase, 

48 mname: str, 

49 flavor: _cfg.Flavor, 

50 force_color: bool = False, 

51) -> Printer: 

52 ''' Produces printer which uses standard Python 'print'. ''' 

53 match __.sys.platform: 

54 case 'win32': 

55 winansi = _colorama.AnsiToWin32( target ) # pyright: ignore 

56 target_ = ( # pragma: no cover 

57 winansi.stream if winansi.convert else target ) 

58 case _: target_ = target 

59 return __.funct.partial( 

60 _simple_print, 

61 target = target_, # pyright: ignore 

62 force_color = force_color ) 

63 

64 

65def _remove_ansi_c1_sequences( text: str ) -> str: 

66 # https://stackoverflow.com/a/14693789/14833542 

67 regex = __.re.compile( r'''\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])''' ) 

68 return regex.sub( '', text ) 

69 

70 

71def _simple_print( 

72 text: str, target: __.io.TextIOBase, force_color = False 

73) -> None: 

74 if not force_color and not target.isatty( ): 

75 print( _remove_ansi_c1_sequences( text ), file = target ) 

76 return 

77 print( text, file = target )