def _pull(self): """ A generator that calls C{resumeProducing} on the underlying producer forever. If C{resumeProducing} throws an exception, the producer is unregistered, which should result in streaming stopping. """ while True: try: self._producer.resumeProducing() except: log.err( None, "%s failed, producing will be stopped:" % (safe_str(self._producer), )) try: self._consumer.unregisterProducer() # The consumer should now call stopStreaming() on us, # thus stopping the streaming. except: # Since the consumer blew up, we may not have had # stopStreaming() called, so we just stop on our own: log.err( None, "%s failed to unregister producer:" % (safe_str(self._consumer), )) self._finished = True return yield None
def _pull(self): """ A generator that calls C{resumeProducing} on the underlying producer forever. If C{resumeProducing} throws an exception, the producer is unregistered, which should result in streaming stopping. """ while True: try: self._producer.resumeProducing() except: log.err(None, "%s failed, producing will be stopped:" % (safe_str(self._producer),)) try: self._consumer.unregisterProducer() # The consumer should now call stopStreaming() on us, # thus stopping the streaming. except: # Since the consumer blew up, we may not have had # stopStreaming() called, so we just stop on our own: log.err(None, "%s failed to unregister producer:" % (safe_str(self._consumer),)) self._finished = True return yield None
def test_brokenClassAttribute(self): """ If an object raises an exception when accessing its C{__class__} attribute, L{reflect.safe_str} uses C{type} to retrieve the class object. """ b = NoClassAttr() b.breakStr = True bStr = reflect.safe_str(b) self.assertIn("NoClassAttr instance at 0x", bStr) self.assertIn(os.path.splitext(__file__)[0], bStr) self.assertIn("RuntimeError: str!", bStr)
def test_brokenClassNameAttribute(self): """ If a class raises an exception when accessing its C{__name__} attribute B{and} when calling its C{__str__} implementation, L{reflect.safe_str} returns 'BROKEN CLASS' instead of the class name. """ class X(BTBase): breakName = True xStr = reflect.safe_str(X()) self.assertIn("<BROKEN CLASS AT 0x", xStr) self.assertIn(os.path.splitext(__file__)[0], xStr) self.assertIn("RuntimeError: str!", xStr)
def assertDefaultTraceback(self, captureVars=False): """ Assert that L{printTraceback} produces and prints a default traceback. The default traceback consists of a header:: Traceback (most recent call last): The body with traceback:: File "/twisted/trial/_synctest.py", line 1180, in _run runWithWarningsSuppressed(suppress, method) And the footer:: --- <exception caught here> --- File "twisted/test/test_failure.py", line 39, in getDivisionFailure 1/0 exceptions.ZeroDivisionError: float division @param captureVars: Enables L{Failure.captureVars}. @type captureVars: C{bool} """ if captureVars: exampleLocalVar = 'xyzzy' f = getDivisionFailure(captureVars=captureVars) out = NativeStringIO() f.printTraceback(out) tb = out.getvalue() stack = '' for method, filename, lineno, localVars, globalVars in f.frames: stack += ' File "%s", line %s, in %s\n' % (filename, lineno, method) stack += ' %s\n' % (linecache.getline( filename, lineno).strip(),) self.assertTracebackFormat(tb, "Traceback (most recent call last):", "%s\n%s%s: %s\n" % (failure.EXCEPTION_CAUGHT_HERE, stack, reflect.qual(f.type), reflect.safe_str(f.value))) if captureVars: self.assertEqual(None, re.search('exampleLocalVar.*xyzzy', tb))
def assertDefaultTraceback(self, captureVars=False): """ Assert that L{printTraceback} produces and prints a default traceback. The default traceback consists of a header:: Traceback (most recent call last): The body with traceback:: File "/twisted/trial/_synctest.py", line 1180, in _run runWithWarningsSuppressed(suppress, method) And the footer:: --- <exception caught here> --- File "twisted/test/test_failure.py", line 39, in getDivisionFailure 1/0 exceptions.ZeroDivisionError: float division @param captureVars: Enables L{Failure.captureVars}. @type captureVars: C{bool} """ if captureVars: exampleLocalVar = 'xyzzy' f = getDivisionFailure(captureVars=captureVars) out = NativeStringIO() f.printTraceback(out) tb = out.getvalue() stack = '' for method, filename, lineno, localVars, globalVars in f.frames: stack += ' File "%s", line %s, in %s\n' % (filename, lineno, method) stack += ' %s\n' % (linecache.getline(filename, lineno).strip(), ) self.assertTracebackFormat( tb, "Traceback (most recent call last):", "%s\n%s%s: %s\n" % (failure.EXCEPTION_CAUGHT_HERE, stack, reflect.qual( f.type), reflect.safe_str(f.value))) if captureVars: self.assertEqual(None, re.search('exampleLocalVar.*xyzzy', tb))
def getErrorMessage(self): """Get a string of the exception which caused this Failure.""" if isinstance(self.value, Failure): return self.value.getErrorMessage() return reflect.safe_str(self.value)
def assertDetailedTraceback(self, captureVars=False, cleanFailure=False): """ Assert that L{printDetailedTraceback} produces and prints a detailed traceback. The detailed traceback consists of a header:: *--- Failure #20 --- The body contains the stacktrace:: /twisted/trial/_synctest.py:1180: _run(...) /twisted/python/util.py:1076: runWithWarningsSuppressed(...) --- <exception caught here> --- /twisted/test/test_failure.py:39: getDivisionFailure(...) If C{captureVars} is enabled the body also includes a list of globals and locals:: [ Locals ] exampleLocalVar : 'xyz' ... ( Globals ) ... Or when C{captureVars} is disabled:: [Capture of Locals and Globals disabled (use captureVars=True)] When C{cleanFailure} is enabled references to other objects are removed and replaced with strings. And finally the footer with the L{Failure}'s value:: exceptions.ZeroDivisionError: float division *--- End of Failure #20 --- @param captureVars: Enables L{Failure.captureVars}. @type captureVars: C{bool} @param cleanFailure: Enables L{Failure.cleanFailure}. @type cleanFailure: C{bool} """ if captureVars: exampleLocalVar = 'xyz' f = getDivisionFailure(captureVars=captureVars) out = NativeStringIO() if cleanFailure: f.cleanFailure() f.printDetailedTraceback(out) tb = out.getvalue() start = "*--- Failure #%d%s---\n" % (f.count, (f.pickled and ' (pickled) ') or ' ') end = "%s: %s\n*--- End of Failure #%s ---\n" % (reflect.qual( f.type), reflect.safe_str(f.value), f.count) self.assertTracebackFormat(tb, start, end) # Variables are printed on lines with 2 leading spaces. linesWithVars = [ line for line in tb.splitlines() if line.startswith(' ') ] if captureVars: self.assertNotEqual([], linesWithVars) if cleanFailure: line = ' exampleLocalVar : "\'xyz\'"' else: line = " exampleLocalVar : 'xyz'" self.assertIn(line, linesWithVars) else: self.assertEqual([], linesWithVars) self.assertIn( ' [Capture of Locals and Globals disabled (use ' 'captureVars=True)]\n', tb)
def test_brokenClassRepr(self): class X(BTBase): breakRepr = True reflect.safe_str(X) reflect.safe_str(X())
def printTraceback(self, file=None, elideFrameworkCode=False, detail='default'): """ Emulate Python's standard error reporting mechanism. @param file: If specified, a file-like object to which to write the traceback. @param elideFrameworkCode: A flag indicating whether to attempt to remove uninteresting frames from within Twisted itself from the output. @param detail: A string indicating how much information to include in the traceback. Must be one of C{'brief'}, C{'default'}, or C{'verbose'}. """ if file is None: from twisted.python import log file = log.logerr w = file.write if detail == 'verbose' and not self.captureVars: # We don't have any locals or globals, so rather than show them as # empty make the output explicitly say that we don't have them at # all. formatDetail = 'verbose-vars-not-captured' else: formatDetail = detail # Preamble if detail == 'verbose': w('*--- Failure #%d%s---\n' % (self.count, (self.pickled and ' (pickled) ') or ' ')) elif detail == 'brief': if self.frames: hasFrames = 'Traceback' else: hasFrames = 'Traceback (failure with no frames)' w("%s: %s: %s\n" % (hasFrames, reflect.safe_str( self.type), reflect.safe_str(self.value))) else: w('Traceback (most recent call last):\n') # Frames, formatted in appropriate style if self.frames: if not elideFrameworkCode: format_frames(self.stack[-traceupLength:], w, formatDetail) w("%s\n" % (EXCEPTION_CAUGHT_HERE, )) format_frames(self.frames, w, formatDetail) elif not detail == 'brief': # Yeah, it's not really a traceback, despite looking like one... w("Failure: ") # postamble, if any if not detail == 'brief': w("%s: %s\n" % (reflect.qual(self.type), reflect.safe_str(self.value))) # chaining if isinstance(self.value, Failure): # TODO: indentation for chained failures? file.write(" (chained Failure)\n") self.value.printTraceback(file, elideFrameworkCode, detail) if detail == 'verbose': w('*--- End of Failure #%d ---\n' % self.count)
def test_workingStr(self): x = [1, 2, 3] self.assertEqual(reflect.safe_str(x), str(x))
def test_brokenRepr(self): b = Breakable() b.breakRepr = True reflect.safe_str(b)
def assertDetailedTraceback(self, captureVars=False, cleanFailure=False): """ Assert that L{printDetailedTraceback} produces and prints a detailed traceback. The detailed traceback consists of a header:: *--- Failure #20 --- The body contains the stacktrace:: /twisted/trial/_synctest.py:1180: _run(...) /twisted/python/util.py:1076: runWithWarningsSuppressed(...) --- <exception caught here> --- /twisted/test/test_failure.py:39: getDivisionFailure(...) If C{captureVars} is enabled the body also includes a list of globals and locals:: [ Locals ] exampleLocalVar : 'xyz' ... ( Globals ) ... Or when C{captureVars} is disabled:: [Capture of Locals and Globals disabled (use captureVars=True)] When C{cleanFailure} is enabled references to other objects are removed and replaced with strings. And finally the footer with the L{Failure}'s value:: exceptions.ZeroDivisionError: float division *--- End of Failure #20 --- @param captureVars: Enables L{Failure.captureVars}. @type captureVars: C{bool} @param cleanFailure: Enables L{Failure.cleanFailure}. @type cleanFailure: C{bool} """ if captureVars: exampleLocalVar = 'xyz' f = getDivisionFailure(captureVars=captureVars) out = NativeStringIO() if cleanFailure: f.cleanFailure() f.printDetailedTraceback(out) tb = out.getvalue() start = "*--- Failure #%d%s---\n" % (f.count, (f.pickled and ' (pickled) ') or ' ') end = "%s: %s\n*--- End of Failure #%s ---\n" % (reflect.qual(f.type), reflect.safe_str(f.value), f.count) self.assertTracebackFormat(tb, start, end) # Variables are printed on lines with 2 leading spaces. linesWithVars = [line for line in tb.splitlines() if line.startswith(' ')] if captureVars: self.assertNotEqual([], linesWithVars) if cleanFailure: line = ' exampleLocalVar : "\'xyz\'"' else: line = " exampleLocalVar : 'xyz'" self.assertIn(line, linesWithVars) else: self.assertEqual([], linesWithVars) self.assertIn(' [Capture of Locals and Globals disabled (use ' 'captureVars=True)]\n', tb)
def printTraceback(self, file=None, elideFrameworkCode=False, detail='default'): """ Emulate Python's standard error reporting mechanism. @param file: If specified, a file-like object to which to write the traceback. @param elideFrameworkCode: A flag indicating whether to attempt to remove uninteresting frames from within Twisted itself from the output. @param detail: A string indicating how much information to include in the traceback. Must be one of C{'brief'}, C{'default'}, or C{'verbose'}. """ if file is None: from twisted.python import log file = log.logerr w = file.write if detail == 'verbose' and not self.captureVars: # We don't have any locals or globals, so rather than show them as # empty make the output explicitly say that we don't have them at # all. formatDetail = 'verbose-vars-not-captured' else: formatDetail = detail # Preamble if detail == 'verbose': w( '*--- Failure #%d%s---\n' % (self.count, (self.pickled and ' (pickled) ') or ' ')) elif detail == 'brief': if self.frames: hasFrames = 'Traceback' else: hasFrames = 'Traceback (failure with no frames)' w("%s: %s: %s\n" % ( hasFrames, reflect.safe_str(self.type), reflect.safe_str(self.value))) else: w( 'Traceback (most recent call last):\n') # Frames, formatted in appropriate style if self.frames: if not elideFrameworkCode: format_frames(self.stack[-traceupLength:], w, formatDetail) w("%s\n" % (EXCEPTION_CAUGHT_HERE,)) format_frames(self.frames, w, formatDetail) elif not detail == 'brief': # Yeah, it's not really a traceback, despite looking like one... w("Failure: ") # postamble, if any if not detail == 'brief': w("%s: %s\n" % (reflect.qual(self.type), reflect.safe_str(self.value))) # chaining if isinstance(self.value, Failure): # TODO: indentation for chained failures? file.write(" (chained Failure)\n") self.value.printTraceback(file, elideFrameworkCode, detail) if detail == 'verbose': w('*--- End of Failure #%d ---\n' % self.count)