Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pygments/formatters/__init__.py: 43%
84 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 07:45 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 07:45 +0000
1"""
2 pygments.formatters
3 ~~~~~~~~~~~~~~~~~~~
5 Pygments formatters.
7 :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
11import re
12import sys
13import types
14import fnmatch
15from os.path import basename
17from pygments.formatters._mapping import FORMATTERS
18from pygments.plugin import find_plugin_formatters
19from pygments.util import ClassNotFound
21__all__ = ['get_formatter_by_name', 'get_formatter_for_filename',
22 'get_all_formatters', 'load_formatter_from_file'] + list(FORMATTERS)
24_formatter_cache = {} # classes by name
25_pattern_cache = {}
28def _fn_matches(fn, glob):
29 """Return whether the supplied file name fn matches pattern filename."""
30 if glob not in _pattern_cache:
31 pattern = _pattern_cache[glob] = re.compile(fnmatch.translate(glob))
32 return pattern.match(fn)
33 return _pattern_cache[glob].match(fn)
36def _load_formatters(module_name):
37 """Load a formatter (and all others in the module too)."""
38 mod = __import__(module_name, None, None, ['__all__'])
39 for formatter_name in mod.__all__:
40 cls = getattr(mod, formatter_name)
41 _formatter_cache[cls.name] = cls
44def get_all_formatters():
45 """Return a generator for all formatter classes."""
46 # NB: this returns formatter classes, not info like get_all_lexers().
47 for info in FORMATTERS.values():
48 if info[1] not in _formatter_cache:
49 _load_formatters(info[0])
50 yield _formatter_cache[info[1]]
51 for _, formatter in find_plugin_formatters():
52 yield formatter
55def find_formatter_class(alias):
56 """Lookup a formatter by alias.
58 Returns None if not found.
59 """
60 for module_name, name, aliases, _, _ in FORMATTERS.values():
61 if alias in aliases:
62 if name not in _formatter_cache:
63 _load_formatters(module_name)
64 return _formatter_cache[name]
65 for _, cls in find_plugin_formatters():
66 if alias in cls.aliases:
67 return cls
70def get_formatter_by_name(_alias, **options):
71 """Lookup and instantiate a formatter by alias.
73 Raises ClassNotFound if not found.
74 """
75 cls = find_formatter_class(_alias)
76 if cls is None:
77 raise ClassNotFound("no formatter found for name %r" % _alias)
78 return cls(**options)
81def load_formatter_from_file(filename, formattername="CustomFormatter",
82 **options):
83 """Load a formatter from a file.
85 This method expects a file located relative to the current working
86 directory, which contains a class named CustomFormatter. By default,
87 it expects the Formatter to be named CustomFormatter; you can specify
88 your own class name as the second argument to this function.
90 Users should be very careful with the input, because this method
91 is equivalent to running eval on the input file.
93 Raises ClassNotFound if there are any problems importing the Formatter.
95 .. versionadded:: 2.2
96 """
97 try:
98 # This empty dict will contain the namespace for the exec'd file
99 custom_namespace = {}
100 with open(filename, 'rb') as f:
101 exec(f.read(), custom_namespace)
102 # Retrieve the class `formattername` from that namespace
103 if formattername not in custom_namespace:
104 raise ClassNotFound('no valid %s class found in %s' %
105 (formattername, filename))
106 formatter_class = custom_namespace[formattername]
107 # And finally instantiate it with the options
108 return formatter_class(**options)
109 except OSError as err:
110 raise ClassNotFound('cannot read %s: %s' % (filename, err))
111 except ClassNotFound:
112 raise
113 except Exception as err:
114 raise ClassNotFound('error when loading custom formatter: %s' % err)
117def get_formatter_for_filename(fn, **options):
118 """Lookup and instantiate a formatter by filename pattern.
120 Raises ClassNotFound if not found.
121 """
122 fn = basename(fn)
123 for modname, name, _, filenames, _ in FORMATTERS.values():
124 for filename in filenames:
125 if _fn_matches(fn, filename):
126 if name not in _formatter_cache:
127 _load_formatters(modname)
128 return _formatter_cache[name](**options)
129 for cls in find_plugin_formatters():
130 for filename in cls.filenames:
131 if _fn_matches(fn, filename):
132 return cls(**options)
133 raise ClassNotFound("no formatter found for file name %r" % fn)
136class _automodule(types.ModuleType):
137 """Automatically import formatters."""
139 def __getattr__(self, name):
140 info = FORMATTERS.get(name)
141 if info:
142 _load_formatters(info[0])
143 cls = _formatter_cache[info[1]]
144 setattr(self, name, cls)
145 return cls
146 raise AttributeError(name)
149oldmod = sys.modules[__name__]
150newmod = _automodule(__name__)
151newmod.__dict__.update(oldmod.__dict__)
152sys.modules[__name__] = newmod
153del newmod.newmod, newmod.oldmod, newmod.sys, newmod.types