def runsource(self, source, filename="<input>", symbol="single"): try: code = self.compile(source, filename, symbol) except (OverflowError, SyntaxError, ValueError): code = "" pass if code is None: # This means it's incomplete return True try: tree = ast.parse(source) bindings = detect_macros(tree) for p, names in bindings: __import__(p) self.bindings.extend([(sys.modules[p], bindings) for (p, bindings) in bindings]) tree = expand_entire_ast(tree, source, self.bindings) tree = ast.Interactive(tree.body) code = compile(tree, filename, symbol, self.compile.compiler.flags, 1) except (OverflowError, SyntaxError, ValueError): # Case 1 self.showsyntaxerror(filename) # This means there's a syntax error return False self.runcode(code) # This means it was successfully compiled; `runcode` takes care of # any runtime failures return False
def runsource(self, source, filename="<input>", symbol="single"): try: code = self.compile(source, filename, symbol) except (OverflowError, SyntaxError, ValueError): code = "" pass if code is None: # This means it's incomplete return True try: tree = ast.parse(source) required_pkgs = detect_macros(tree) for p in required_pkgs: __import__(p) self.modules.update(sys.modules[p] for p in required_pkgs) tree = process_ast(tree, self.modules) tree = ast.Interactive(tree.body) code = compile(tree, filename, symbol, self.compile.compiler.flags, 1) except (OverflowError, SyntaxError, ValueError): # Case 1 self.showsyntaxerror(filename) # This means there's a syntax error return False self.runcode(code) # This means it was successfully compiled; `runcode` takes care of # any runtime failures return False
def visit(self, tree): try: bindings = detect_macros(tree, '__main__') # macro imports if bindings: self.ext.macro_bindings_changed = True for fullname, macro_bindings in bindings: mod = importlib.import_module(fullname) self.bindings[fullname] = (mod, macro_bindings) newtree = ModuleExpansionContext( tree, self.ext.src, self.bindings.values()).expand_macros() self.ext.src = _placeholder return newtree except Exception as err: # see IPython.core.interactiveshell.InteractiveShell.transform_ast() raise InputRejected(*err.args)
def runsource(self, source, filename="<input>", symbol="single"): # ? and ?? help syntax if source == "macros?": self._list_macros() return False # complete input elif source.endswith("??"): return self.runsource(f'imacropy.sourcecode({source[:-2]})') elif source.endswith("?"): return self.runsource(f"imacropy.doc({source[:-1]})") try: code = self.compile(source, filename, symbol) except (OverflowError, SyntaxError, ValueError): code = "" if code is None: # incomplete input return True try: tree = ast.parse(source) # Must reload modules before detect_macros, because detect_macros reads the macro registry # of each module from which macros are imported. _reload_macro_modules(tree, '__main__') # If detect_macros returns normally, it means each fullname (module) can be imported successfully. try: bindings = detect_macros(tree, '__main__') except AttributeError: # module 'foo' has no attribute 'macros' pass else: if bindings: self._stubs_dirty = True for fullname, macro_bindings in bindings: # validate before committing mod = importlib.import_module( fullname ) # already imported so just a sys.modules lookup for origname, _ in macro_bindings: try: getattr(mod, origname) except AttributeError: raise ImportError( f"cannot import name '{origname}'") for fullname, macro_bindings in bindings: mod = importlib.import_module(fullname) self._bindings[fullname] = (mod, macro_bindings) tree = ModuleExpansionContext( tree, source, self._bindings.values()).expand_macros() tree = ast.Interactive(tree.body) code = compile(tree, filename, symbol, self.compile.compiler.flags, 1) except (OverflowError, SyntaxError, ValueError): self.showsyntaxerror(filename) return False # erroneous input except ModuleNotFoundError as err: # during macro module lookup # In this case, the standard stack trace is long and points only to our code and the stdlib, # not the erroneous input that's the actual culprit. Better ignore it, and emulate showsyntaxerror. # TODO: support sys.excepthook. self.write(f"{err.__class__.__name__}: {str(err)}\n") return False # erroneous input except ImportError as err: # during macro lookup in a successfully imported module self.write(f"{err.__class__.__name__}: {str(err)}\n") return False # erroneous input self.runcode(code) self._refresh_stubs() return False # Successfully compiled. `runcode` takes care of any runtime failures.