def test_traceback(self): """ If a L{FlattenerError} is created with traceback frames, they are included in the string representation of the exception. """ # Try to be realistic in creating the data passed in for the traceback # frames. def f(): g() def g(): raise RuntimeError("reason") try: f() except RuntimeError as e: # Get the traceback, minus the info for *this* frame tbinfo = traceback.extract_tb(sys.exc_info()[2])[1:] exc = e else: self.fail("f() must raise RuntimeError") self.assertEqual( str(FlattenerError(exc, [], tbinfo)), "Exception while flattening:\n" " File \"%s\", line %d, in f\n" " g()\n" " File \"%s\", line %d, in g\n" " raise RuntimeError(\"reason\")\n" "RuntimeError: reason\n" % (HERE, f.__code__.co_firstlineno + 1, HERE, g.__code__.co_firstlineno + 1))
def test_string(self): """ If a L{FlattenerError} is created with a string root, up to around 40 bytes from that string are included in the string representation of the exception. """ self.assertEqual( str(FlattenerError(RuntimeError("reason"), ['abc123xyz'], [])), "Exception while flattening:\n" " 'abc123xyz'\n" "RuntimeError: reason\n") self.assertEqual( str(FlattenerError(RuntimeError("reason"), ['0123456789' * 10], [])), "Exception while flattening:\n" " '01234567890123456789<...>01234567890123456789'\n" "RuntimeError: reason\n")
def test_tagWithoutLocation(self): """ If a L{FlattenerError} is created with a L{Tag} instance without source location information, only the tagName is included in the string representation of the exception. """ self.assertEqual( str(FlattenerError(RuntimeError("reason"), [Tag("span")], [])), "Exception while flattening:\n" " Tag <span>\n" "RuntimeError: reason\n", )
def test_unicode(self): """ If a L{FlattenerError} is created with a unicode root, up to around 40 characters from that string are included in the string representation of the exception. """ self.assertEqual( str( FlattenerError(RuntimeError("reason"), [u'abc\N{SNOWMAN}xyz'], [])), "Exception while flattening:\n" " u'abc\\u2603xyz'\n" # Codepoint for SNOWMAN "RuntimeError: reason\n") self.assertEqual( str( FlattenerError(RuntimeError("reason"), [u'01234567\N{SNOWMAN}9' * 10], [])), "Exception while flattening:\n" " u'01234567\\u2603901234567\\u26039<...>01234567\\u2603901234567" "\\u26039'\n" "RuntimeError: reason\n")
def test_tag(self): """ If a L{FlattenerError} is created with a L{Tag} instance with source location information, the source location is included in the string representation of the exception. """ tag = Tag("div", filename="/foo/filename.xhtml", lineNumber=17, columnNumber=12) self.assertEqual( str(FlattenerError(RuntimeError("reason"), [tag], [])), "Exception while flattening:\n" ' File "/foo/filename.xhtml", line 17, column 12, in "div"\n' "RuntimeError: reason\n", )
def test_renderable(self): """ If a L{FlattenerError} is created with an L{IRenderable} provider root, the repr of that object is included in the string representation of the exception. """ @implementer(IRenderable) class Renderable(object): def __repr__(self): return "renderable repr" self.assertEqual( str(FlattenerError(RuntimeError("reason"), [Renderable()], [])), "Exception while flattening:\n" " renderable repr\n" "RuntimeError: reason\n")
def _flattenTree(request, root, write): """ Make C{root} into an iterable of L{bytes} and L{Deferred} by doing a depth first traversal of the tree. @param request: A request object which will be passed to L{IRenderable.render}. @param root: An object to be made flatter. This may be of type C{unicode}, L{bytes}, L{slot}, L{Tag <twisted.web.template.Tag>}, L{tuple}, L{list}, L{types.GeneratorType}, L{Deferred}, or something providing L{IRenderable}. @param write: A callable which will be invoked with each L{bytes} produced by flattening C{root}. @return: An iterator which yields objects of type L{bytes} and L{Deferred}. A L{Deferred} is only yielded when one is encountered in the process of flattening C{root}. The returned iterator must not be iterated again until the L{Deferred} is called back. """ stack = [_flattenElement(request, root, write, [], None, escapeForContent)] while stack: try: frame = stack[-1].gi_frame element = next(stack[-1]) except StopIteration: stack.pop() except Exception as e: stack.pop() roots = [] for generator in stack: roots.append(generator.gi_frame.f_locals["root"]) roots.append(frame.f_locals["root"]) raise FlattenerError(e, roots, extract_tb(exc_info()[2])) else: if isinstance(element, Deferred): def cbx(originalAndToFlatten): original, toFlatten = originalAndToFlatten stack.append(toFlatten) return original yield element.addCallback(cbx) else: stack.append(element)
def _flattenTree(request, root): """ Make C{root} into an iterable of C{str} and L{Deferred} by doing a depth first traversal of the tree. @param request: A request object which will be passed to L{IRenderable.render}. @param root: An object to be made flatter. This may be of type C{unicode}, C{str}, L{slot}, L{Tag}, L{tuple}, L{list}, L{GeneratorType}, L{Deferred}, or something providing L{IRenderable}. @return: An iterator which yields objects of type C{str} and L{Deferred}. A L{Deferred} is only yielded when one is encountered in the process of flattening C{root}. The returned iterator must not be iterated again until the L{Deferred} is called back. """ stack = [_flattenElement(request, root, [], None, False)] while stack: try: # In Python 2.5, after an exception, a generator's gi_frame is # None. frame = stack[-1].gi_frame element = stack[-1].next() except StopIteration: stack.pop() except Exception, e: stack.pop() roots = [] for generator in stack: roots.append(generator.gi_frame.f_locals['root']) roots.append(frame.f_locals['root']) raise FlattenerError(e, roots, extract_tb(exc_info()[2])) else: if type(element) is str: yield element elif isinstance(element, Deferred): def cbx((original, toFlatten)): stack.append(toFlatten) return original yield element.addCallback(cbx) else: stack.append(element)
async def _flattenTree(request: Optional[IRequest], root: Flattenable, write: Callable[[bytes], object]) -> None: """ Make C{root} into an iterable of L{bytes} and L{Deferred} by doing a depth first traversal of the tree. @param request: A request object which will be passed to L{IRenderable.render}. @param root: An object to be made flatter. This may be of type C{unicode}, L{bytes}, L{slot}, L{Tag <twisted.web.template.Tag>}, L{tuple}, L{list}, L{types.GeneratorType}, L{Deferred}, or something providing L{IRenderable}. @param write: A callable which will be invoked with each L{bytes} produced by flattening C{root}. @return: A C{Deferred}-returning coroutine that resolves to C{None}. """ stack: List[Generator] = [ _flattenElement(request, root, write, [], None, escapeForContent) ] while stack: try: frame = stack[-1].gi_frame element = next(stack[-1]) if isinstance(element, Deferred): element = await element except StopIteration: stack.pop() except Exception as e: stack.pop() roots = [] for generator in stack: roots.append(generator.gi_frame.f_locals["root"]) roots.append(frame.f_locals["root"]) raise FlattenerError(e, roots, extract_tb(exc_info()[2])) else: stack.append(element)
""" If a L{FlattenerError} is created with traceback frames, they are included in the string representation of the exception. """ # Try to be realistic in creating the data passed in for the traceback # frames. def f(): g() def g(): raise RuntimeError("reason") try: f() except RuntimeError, exc: # Get the traceback, minus the info for *this* frame tbinfo = traceback.extract_tb(sys.exc_info()[2])[1:] else: self.fail("f() must raise RuntimeError") self.assertEqual( str(FlattenerError(exc, [], tbinfo)), "Exception while flattening:\n" " File \"%s\", line %d, in f\n" " g()\n" " File \"%s\", line %d, in g\n" " raise RuntimeError(\"reason\")\n" "RuntimeError: reason\n" % (HERE, f.func_code.co_firstlineno + 1, HERE, g.func_code.co_firstlineno + 1))