def _run(self, environment): logging.info("Running %s %s" % (self.__class__.__name__.lower(), self.path)) self.paper.remove_owned_by(self.path) # A string uniquely identifying the paper from which the # calclet is called. Used in Importer. paper_id = hex(id(self.paper))[2:] script = utf8(self.node[...].flat[0]) script = compile(script, ':'.join([paper_id, self.path]), 'exec') self._contents_module = imp.new_module('activepapers.contents') self._contents_module.data = DataGroup(self.paper, None, self.paper.data_group, self) self._contents_module.open = self.open_data_file self._contents_module.open_documentation = self.open_documentation_file self._contents_module.snapshot = self.paper.snapshot # The remaining part of this method is not thread-safe because # of the way the global state in sys.modules is modified. with codelet_lock: try: codelet_registry[(paper_id, self.path)] = self for name, module in self.paper._local_modules.items(): assert name not in sys.modules sys.modules[name] = module sys.modules['activepapers.contents'] = self._contents_module execstring(script, environment) finally: del codelet_registry[(paper_id, self.path)] self._contents_module = None if 'activepapers.contents' in sys.modules: del sys.modules['activepapers.contents'] for name, module in self.paper._local_modules.items(): del sys.modules[name]
def __init__(self, paper, node): self._paper = paper self._node = node self.type = datatype(node) self.language = language(node) self.name = node.name self.code = utf8(node[...].flat[0])
def run_codelet(self, path, debug=False): if path.startswith('/'): assert path.startswith('/code/') path = path[6:] node = APNode(self.code_group)[path] class_ = {'calclet': Calclet, 'importlet': Importlet}[datatype(node)] try: class_(self, node).run() return None except Exception: # TODO: preprocess traceback to show only the stack frames # in the codelet. import traceback type, value, trace = sys.exc_info() stack = traceback.extract_tb(trace) del trace while stack: if stack[0][2] == 'execcode': del stack[0] break del stack[0] fstack = [] for filename, lineno, fn_name, code in stack: if ':' in filename: paper_id, codelet = filename.split(':') paper = paper_registry.get(paper_id) if paper is None: paper_name = '<ActivePaper>' else: paper_name = '<%s>' % paper.file.filename filename = ':'.join([paper_name, codelet]) if code is None and paper is not None: script = utf8(paper.file[codelet][...].flat[0]) code = script.split('\n')[lineno - 1] fstack.append((filename, lineno, fn_name, code)) tb_text = ''.join(["Traceback (most recent call last):\n"] + \ traceback.format_list(fstack) + \ traceback.format_exception_only(type, value)) if debug: sys.stderr.write(tb_text) import pdb pdb.post_mortem() else: return tb_text
def run_codelet(self, path, debug=False): if path.startswith('/'): assert path.startswith('/code/') path = path[6:] node = APNode(self.code_group)[path] class_ = {'calclet': Calclet, 'importlet': Importlet}[datatype(node)] try: class_(self, node).run() return None except Exception: # TODO: preprocess traceback to show only the stack frames # in the codelet. import traceback type, value, trace = sys.exc_info() stack = traceback.extract_tb(trace) del trace while stack: if stack[0][2] == 'execstring': del stack[0] break del stack[0] fstack = [] for filename, lineno, fn_name, code in stack: if ':' in filename: paper_id, codelet = filename.split(':') paper = paper_registry.get(paper_id) if paper is None: paper_name = '<ActivePaper>' else: paper_name = '<%s>' % paper.file.filename filename = ':'.join([paper_name, codelet]) if code is None and paper is not None: script = utf8(paper.file[codelet][...].flat[0]) code = script.split('\n')[lineno-1] fstack.append((filename, lineno, fn_name, code)) tb_text = ''.join(["Traceback (most recent call last):\n"] + \ traceback.format_list(fstack) + \ traceback.format_exception_only(type, value)) if debug: sys.stderr.write(tb_text) import pdb pdb.post_mortem() else: return tb_text