Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pygments/formatters/__init__.py: 42%

77 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:07 +0000

1""" 

2 pygments.formatters 

3 ~~~~~~~~~~~~~~~~~~~ 

4 

5 Pygments formatters. 

6 

7 :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS. 

8 :license: BSD, see LICENSE for details. 

9""" 

10 

11import sys 

12import types 

13from fnmatch import fnmatch 

14from os.path import basename 

15 

16from pygments.formatters._mapping import FORMATTERS 

17from pygments.plugin import find_plugin_formatters 

18from pygments.util import ClassNotFound 

19 

20__all__ = ['get_formatter_by_name', 'get_formatter_for_filename', 

21 'get_all_formatters', 'load_formatter_from_file'] + list(FORMATTERS) 

22 

23_formatter_cache = {} # classes by name 

24 

25def _load_formatters(module_name): 

26 """Load a formatter (and all others in the module too).""" 

27 mod = __import__(module_name, None, None, ['__all__']) 

28 for formatter_name in mod.__all__: 

29 cls = getattr(mod, formatter_name) 

30 _formatter_cache[cls.name] = cls 

31 

32 

33def get_all_formatters(): 

34 """Return a generator for all formatter classes.""" 

35 # NB: this returns formatter classes, not info like get_all_lexers(). 

36 for info in FORMATTERS.values(): 

37 if info[1] not in _formatter_cache: 

38 _load_formatters(info[0]) 

39 yield _formatter_cache[info[1]] 

40 for _, formatter in find_plugin_formatters(): 

41 yield formatter 

42 

43 

44def find_formatter_class(alias): 

45 """Lookup a formatter by alias. 

46 

47 Returns None if not found. 

48 """ 

49 for module_name, name, aliases, _, _ in FORMATTERS.values(): 

50 if alias in aliases: 

51 if name not in _formatter_cache: 

52 _load_formatters(module_name) 

53 return _formatter_cache[name] 

54 for _, cls in find_plugin_formatters(): 

55 if alias in cls.aliases: 

56 return cls 

57 

58 

59def get_formatter_by_name(_alias, **options): 

60 """Lookup and instantiate a formatter by alias. 

61 

62 Raises ClassNotFound if not found. 

63 """ 

64 cls = find_formatter_class(_alias) 

65 if cls is None: 

66 raise ClassNotFound("no formatter found for name %r" % _alias) 

67 return cls(**options) 

68 

69 

70def load_formatter_from_file(filename, formattername="CustomFormatter", 

71 **options): 

72 """Load a formatter from a file. 

73 

74 This method expects a file located relative to the current working 

75 directory, which contains a class named CustomFormatter. By default, 

76 it expects the Formatter to be named CustomFormatter; you can specify 

77 your own class name as the second argument to this function. 

78 

79 Users should be very careful with the input, because this method 

80 is equivalent to running eval on the input file. 

81 

82 Raises ClassNotFound if there are any problems importing the Formatter. 

83 

84 .. versionadded:: 2.2 

85 """ 

86 try: 

87 # This empty dict will contain the namespace for the exec'd file 

88 custom_namespace = {} 

89 with open(filename, 'rb') as f: 

90 exec(f.read(), custom_namespace) 

91 # Retrieve the class `formattername` from that namespace 

92 if formattername not in custom_namespace: 

93 raise ClassNotFound('no valid %s class found in %s' % 

94 (formattername, filename)) 

95 formatter_class = custom_namespace[formattername] 

96 # And finally instantiate it with the options 

97 return formatter_class(**options) 

98 except OSError as err: 

99 raise ClassNotFound('cannot read %s: %s' % (filename, err)) 

100 except ClassNotFound: 

101 raise 

102 except Exception as err: 

103 raise ClassNotFound('error when loading custom formatter: %s' % err) 

104 

105 

106def get_formatter_for_filename(fn, **options): 

107 """Lookup and instantiate a formatter by filename pattern. 

108 

109 Raises ClassNotFound if not found. 

110 """ 

111 fn = basename(fn) 

112 for modname, name, _, filenames, _ in FORMATTERS.values(): 

113 for filename in filenames: 

114 if fnmatch(fn, filename): 

115 if name not in _formatter_cache: 

116 _load_formatters(modname) 

117 return _formatter_cache[name](**options) 

118 for cls in find_plugin_formatters(): 

119 for filename in cls.filenames: 

120 if fnmatch(fn, filename): 

121 return cls(**options) 

122 raise ClassNotFound("no formatter found for file name %r" % fn) 

123 

124 

125class _automodule(types.ModuleType): 

126 """Automatically import formatters.""" 

127 

128 def __getattr__(self, name): 

129 info = FORMATTERS.get(name) 

130 if info: 

131 _load_formatters(info[0]) 

132 cls = _formatter_cache[info[1]] 

133 setattr(self, name, cls) 

134 return cls 

135 raise AttributeError(name) 

136 

137 

138oldmod = sys.modules[__name__] 

139newmod = _automodule(__name__) 

140newmod.__dict__.update(oldmod.__dict__) 

141sys.modules[__name__] = newmod 

142del newmod.newmod, newmod.oldmod, newmod.sys, newmod.types