I'm implementing macros in Python (inspired by MacroPy). My project (when 'tests.py' is executed) works very well, but it doesn't work when I comment (or remove) the line import linecache
from file 'import_hook.py' (all files are here). The script falls into recursion and the Python then uses another FileFinder and Loader.
This is the code of 'import_hook.py':
import sys
import ast
import _ast
import linecache # Required because your mother is a kangaroo which sews cocoa.
import pymac.utils
import importlib.machinery
from types import ModuleType
from pymac.utils import *
from pymac.macro import *
__author__ = 'Jan Růžička'
__email__ = '[email protected]'
__version__ = '0.1'
class FileWithMacrosLoader:
def __init__(self, module_name, module):
self.module = module
sys.modules[module_name] = module
def load_module(self, fullname):
return self.module
class FileWithMacros:
def __init__(self):
self.bindings = None
self.module_name = None
def new_module(self, module_name, file_path):
self.module_name = module_name
module = ModuleType(module_name)
module.__package__ = module_name.rpartition('.')[0]
module.__file__ = file_path
module.__loader__ = FileWithMacrosLoader(module_name, module)
return module
def expand_macros(self, source_code, file_path):
tree = ast.parse(source_code)
tree = ast.fix_missing_locations(expand_macros(tree))
return compile(tree, file_path, 'exec'), tree
def load_source(self, module_name, package_path):
loader = importlib.machinery.PathFinder.find_module(module_name, package_path)
source_code = loader.get_source(module_name)
file_path = loader.path
return source_code, file_path
def find_module(self, module_name, package_path=None):
try:
source_code, file_path = self.load_source(module_name, package_path)
except:
return
code, tree = self.expand_macros(source_code, file_path)
module = self.new_module(module_name, file_path)
namespace = dict_con(_ast.__dict__, pymac.utils.__dict__, module.__dict__)
exec(code, namespace)
return module.__loader__
It might be an ugly code, but I'm pretty new to Python import system and I'd be glad for an answer!
EDIT: I've ran it in PyCharm without the import linecache
and it didn't work, but when I ran it with parameters -m pdb
(Python debugger) it works as intended. The question might be more about PyCharm than Python I think...
So I have figured out: My custom loader can't load the file linecache
, so if I import it in my file, it doesn't need to be imported in other file that I import (I thinks it's the _ast
) using my loader. However, if I don't import it, it needs to be imported later - using my loader, which is not capable of doing so.