def run(src, file_path=None): t0 = time.perf_counter() msg = '' try: ns = {'__name__':'__main__'} if file_path is not None: ns['__file__'] = file_path exec(src, ns) state = 1 except Exception as exc: msg = traceback.format_exc() print(msg, file=sys.stderr) state = 0 t1 = time.perf_counter() return state, t0, t1, msg
def render(self, **ns): """Returns the HTML code for the template, with the key / values in the keyword argument ns. """ # Set attribute "data" to an instance of class ElementData. self.data = ElementData(**ns) # Add names "__write__" and "__render_attr__" to namespace. ns.update({"__write__": self.write, "__render_attr__": self.render_attr}) self.html = "" # Executing the Python code will store HTML code in self.html. try: exec(self.python, ns) except Exception as exc: msg = traceback.format_exc() if isinstance(exc, SyntaxError): line_no = exc.args[2] else: tb = exc.traceback while tb is not None: line_no = tb.tb_lineno tb = tb.tb_next elt = self.line_mapping[line_no] print("Error rendering the element:") try: print(elt.outerHTML) except AttributeError: print('no outerHTML for', elt) print(elt.html) print(f"{exc.__class__.__name__}: {exc}") return # Replace element content by generated html. # Since we reset outerHTML (this is necessary because the element may # have dynamic attributes), we must reset the reference to the element # because self.element would still point to the previous version (cf. # https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML, # section Notes). if self.element.nodeType != 9: rank = self.element.index() parent = self.element.parent self.element.outerHTML = self.html self.element = parent.childNodes[rank] else: # If the template is the document, only reset (inner)html self.element.html = self.html # Bindings. self.element.unbind() callbacks = {} for callback in self.callbacks: callbacks[callback.__name__] = callback # Bindings are specified with the attribute b-on. Its value has the # form "event1:callback1;event2:callback2". for element in self.element.select("*[b-on]"): bindings = element.getAttribute("b-on") bindings = bindings.split(";") for binding in bindings: parts = binding.split(":") if not len(parts) == 2: raise TemplateError(f"wrong binding: {binding}") event, func_name = [x.strip() for x in parts] if not func_name in callbacks: print(element.outerHTML) raise TemplateError(f"unknown callback: {func_name}") self.on(element, event, callbacks[func_name])
def render(self, **ns): """Returns the HTML code for the template, with the key / values in the keyword argument ns. """ # Set attribute "data" to an instance of class ElementData. self.data = ElementData(**ns) # Add names "__write__" and "__render_attr__" to namespace. ns.update({ "__write__": self.write, "__render_attr__": self.render_attr }) self.html = "" # Executing the Python code will store HTML code in self.html. try: exec(self.python, ns) except Exception as exc: msg = traceback.format_exc() if isinstance(exc, SyntaxError): line_no = exc.args[2] else: tb = exc.traceback while tb is not None: line_no = tb.tb_lineno tb = tb.tb_next elt = self.line_mapping[line_no] print("Error rendering the element:") try: print(elt.outerHTML) except AttributeError: print('no outerHTML for', elt) print(elt.html) print(f"{exc.__class__.__name__}: {exc}") return # Replace element content by generated html. # Since we reset outerHTML (this is necessary because the element may # have dynamic attributes), we must reset the reference to the element # because self.element would still point to the previous version (cf. # https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML, # section Notes). if self.element.nodeType != 9: rank = self.element.index() parent = self.element.parent self.element.outerHTML = self.html self.element = parent.childNodes[rank] else: # If the template is the document, only reset (inner)html self.element.html = self.html # Bindings. self.element.unbind() callbacks = {} for callback in self.callbacks: callbacks[callback.__name__] = callback # Bindings are specified with the attribute b-on. Its value has the # form "event1:callback1;event2:callback2". for element in self.element.select("*[b-on]"): bindings = element.getAttribute("b-on") bindings = bindings.split(";") for binding in bindings: parts = binding.split(":") if not len(parts) == 2: raise TemplateError(f"wrong binding: {binding}") event, func_name = [x.strip() for x in parts] if not func_name in callbacks: print(element.outerHTML) raise TemplateError(f"unknown callback: {func_name}") self.on(element, event, callbacks[func_name])