Inspired by David Beazley’s talk on various hacks that can be made to Python’s import system, I whipped up the following script for running a preprocessor over a file at import-time. In most cases, I would say this is far from a good idea, but it might be useful for creating small domain-specific languages, or defining new literals, or something like that.
import sys import re class ImportPreprocessor: def __init__(self, loader, preprocess): self._loader = loader self._preprocess = preprocess def find_spec(self, name, path, target=None): spec = self._loader.find_spec(name, path, target) spec.loader = ImportPreprocessor(spec.loader, self._preprocess) return spec def exec_module(self, mod): source = self.loader.get_source(mod.__name__) source = self._preprocess(source) code = compile(source, mod.__file__, 'exec') exec(code, mod.__dict__) return mod def percent_to_float(source): pattern = r'(\d+)%' source = re.sub(pattern, r'(\1/100)', source) return source sys.meta_path[3] = ImportPreprocessor(sys.meta_path[3], percent_to_float) import test """ # contents of test.py x = 40 * 25% """ print(test.x) # 10.0