def __repr__(self): if hasattr(self.f, '__qualname__'): func = self.f.__qualname__ elif hasattr(self.f, '__name__'): func = self.f.__name__ if hasattr(self.f, 'im_class'): func = self.f.im_class.__name__ + '.' + func else: func = reflect.safe_repr(self.f) return 'LoopingCall<%r>(%s, *%s, **%s)' % ( self.interval, func, reflect.safe_repr(self.a), reflect.safe_repr(self.kw))
def test_brokenStr(self): """ L{reflect.safe_repr} isn't affected by a broken C{__str__} method. """ b = Breakable() b.breakStr = True self.assertEqual(reflect.safe_repr(b), repr(b))
def test_workingRepr(self): """ L{reflect.safe_repr} produces the same output as C{repr} on a working object. """ x = [1, 2, 3] self.assertEqual(reflect.safe_repr(x), repr(x))
def __str__(self): if self._str is not None: return self._str if hasattr(self, 'func'): # This code should be replaced by a utility function in reflect; # see ticket #6066: if hasattr(self.func, '__qualname__'): func = self.func.__qualname__ elif hasattr(self.func, '__name__'): func = self.func.func_name if hasattr(self.func, 'im_class'): func = self.func.im_class.__name__ + '.' + func else: func = reflect.safe_repr(self.func) else: func = None now = self.seconds() L = [ "<DelayedCall 0x%x [%ss] called=%s cancelled=%s" % (id(self), self.time - now, self.called, self.cancelled) ] if func is not None: L.extend((" ", func, "(")) if self.args: L.append(", ".join([reflect.safe_repr(e) for e in self.args])) if self.kw: L.append(", ") if self.kw: L.append(", ".join([ '%s=%s' % (k, reflect.safe_repr(v)) for (k, v) in self.kw.items() ])) L.append(")") if self.debug: L.append("\n\ntraceback at creation: \n\n%s" % (' '.join(self.creator))) L.append('>') return "".join(L)
def _safeReprVars(varsDictItems): """ Convert a list of (name, object) pairs into (name, repr) pairs. L{twisted.python.reflect.safe_repr} is used to generate the repr, so no exceptions will be raised by faulty C{__repr__} methods. @param varsDictItems: a sequence of (name, value) pairs as returned by e.g. C{locals().items()}. @returns: a sequence of (name, repr) pairs. """ return [(name, reflect.safe_repr(obj)) for (name, obj) in varsDictItems]
def test_brokenClassAttribute(self): """ If an object raises an exception when accessing its C{__class__} attribute, L{reflect.safe_repr} uses C{type} to retrieve the class object. """ b = NoClassAttr() b.breakRepr = True bRepr = reflect.safe_repr(b) self.assertIn("NoClassAttr instance at 0x", bRepr) self.assertIn(os.path.splitext(__file__)[0], bRepr) self.assertIn("RuntimeError: repr!", bRepr)
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_repr} returns 'BROKEN CLASS' instead of the class name. """ class X(BTBase): breakName = True xRepr = reflect.safe_repr(X()) self.assertIn("<BROKEN CLASS AT 0x", xRepr) self.assertIn(os.path.splitext(__file__)[0], xRepr) self.assertIn("RuntimeError: repr!", xRepr)
def test_brokenRepr(self): """ L{reflect.safe_repr} returns a string with class name, address, and traceback when the repr call failed. """ b = Breakable() b.breakRepr = True bRepr = reflect.safe_repr(b) self.assertIn("Breakable instance at 0x", bRepr) # Check that the file is in the repr, but without the extension as it # can be .py/.pyc self.assertIn(os.path.splitext(__file__)[0], bRepr) self.assertIn("RuntimeError: repr!", bRepr)
def test_brokenReprIncludesID(self): """ C{id} is used to print the ID of the object in case of an error. L{safe_repr} includes a traceback after a newline, so we only check against the first line of the repr. """ class X(BTBase): breakRepr = True xRepr = reflect.safe_repr(X) xReprExpected = ('<BrokenType instance at 0x%x with repr error:' % (id(X),)) self.assertEqual(xReprExpected, xRepr.split('\n')[0])
def test_brokenReprIncludesID(self): """ C{id} is used to print the ID of the object in case of an error. L{safe_repr} includes a traceback after a newline, so we only check against the first line of the repr. """ class X(BTBase): breakRepr = True xRepr = reflect.safe_repr(X) xReprExpected = ('<BrokenType instance at 0x%x with repr error:' % (id(X), )) self.assertEqual(xReprExpected, xRepr.split('\n')[0])
def __str__(self): if self._str is not None: return self._str if hasattr(self, "func"): # This code should be replaced by a utility function in reflect; # see ticket #6066: if hasattr(self.func, "__qualname__"): func = self.func.__qualname__ elif hasattr(self.func, "__name__"): func = self.func.func_name if hasattr(self.func, "im_class"): func = self.func.im_class.__name__ + "." + func else: func = reflect.safe_repr(self.func) else: func = None now = self.seconds() L = [ "<DelayedCall 0x%x [%ss] called=%s cancelled=%s" % (unsignedID(self), self.time - now, self.called, self.cancelled) ] if func is not None: L.extend((" ", func, "(")) if self.args: L.append(", ".join([reflect.safe_repr(e) for e in self.args])) if self.kw: L.append(", ") if self.kw: L.append(", ".join(["%s=%s" % (k, reflect.safe_repr(v)) for (k, v) in self.kw.items()])) L.append(")") if self.debug: L.append("\n\ntraceback at creation: \n\n%s" % (" ".join(self.creator))) L.append(">") return "".join(L)
def test_unsignedID(self): """ L{unsignedID} is used to print ID of the object in case of error, not standard ID value which can be negative. """ class X(BTBase): breakRepr = True ids = {X: 100} def fakeID(obj): try: return ids[obj] except (TypeError, KeyError): return id(obj) self.addCleanup(util.setIDFunction, util.setIDFunction(fakeID)) xRepr = reflect.safe_repr(X) self.assertIn("0x64", xRepr)
def render(self, resrc): """ Ask a resource to render itself. @param resrc: a L{twisted.web.resource.IResource}. """ try: body = resrc.render(self) except UnsupportedMethod as e: allowedMethods = e.allowedMethods if (self.method == b"HEAD") and (b"GET" in allowedMethods): # We must support HEAD (RFC 2616, 5.1.1). If the # resource doesn't, fake it by giving the resource # a 'GET' request and then return only the headers, # not the body. log.msg("Using GET to fake a HEAD request for %s" % (resrc, )) self.method = b"GET" self._inFakeHead = True body = resrc.render(self) if body is NOT_DONE_YET: log.msg("Tried to fake a HEAD request for %s, but " "it got away from me." % resrc) # Oh well, I guess we won't include the content length. else: self.setHeader(b'content-length', intToBytes(len(body))) self._inFakeHead = False self.method = b"HEAD" self.write(b'') self.finish() return if self.method in (supportedMethods): # We MUST include an Allow header # (RFC 2616, 10.4.6 and 14.7) self.setHeader('Allow', ', '.join(allowedMethods)) s = ('''Your browser approached me (at %(URI)s) with''' ''' the method "%(method)s". I only allow''' ''' the method%(plural)s %(allowed)s here.''' % { 'URI': escape(self.uri), 'method': self.method, 'plural': ((len(allowedMethods) > 1) and 's') or '', 'allowed': ', '.join(allowedMethods) }) epage = resource.ErrorPage(http.NOT_ALLOWED, "Method Not Allowed", s) body = epage.render(self) else: epage = resource.ErrorPage( http.NOT_IMPLEMENTED, "Huh?", "I don't know how to treat a %s request." % (escape(self.method.decode("charmap")), )) body = epage.render(self) # end except UnsupportedMethod if body == NOT_DONE_YET: return if not isinstance(body, bytes): body = resource.ErrorPage( http.INTERNAL_SERVER_ERROR, "Request did not return bytes", "Request: " + html.PRE(reflect.safe_repr(self)) + "<br />" + "Resource: " + html.PRE(reflect.safe_repr(resrc)) + "<br />" + "Value: " + html.PRE(reflect.safe_repr(body))).render(self) if self.method == b"HEAD": if len(body) > 0: # This is a Bad Thing (RFC 2616, 9.4) log.msg("Warning: HEAD request %s for resource %s is" " returning a message body." " I think I'll eat it." % (self, resrc)) self.setHeader(b'content-length', intToBytes(len(body))) self.write(b'') else: self.setHeader(b'content-length', intToBytes(len(body))) self.write(body) self.finish()
def test_brokenClassStr(self): class X(BTBase): breakStr = True reflect.safe_repr(X) reflect.safe_repr(X())
def render(self, resrc): """ Ask a resource to render itself. @param resrc: a L{twisted.web.resource.IResource}. """ try: body = resrc.render(self) except UnsupportedMethod as e: allowedMethods = e.allowedMethods if (self.method == b"HEAD") and (b"GET" in allowedMethods): # We must support HEAD (RFC 2616, 5.1.1). If the # resource doesn't, fake it by giving the resource # a 'GET' request and then return only the headers, # not the body. log.msg("Using GET to fake a HEAD request for %s" % (resrc,)) self.method = b"GET" self._inFakeHead = True body = resrc.render(self) if body is NOT_DONE_YET: log.msg("Tried to fake a HEAD request for %s, but " "it got away from me." % resrc) # Oh well, I guess we won't include the content length. else: self.setHeader(b'content-length', intToBytes(len(body))) self._inFakeHead = False self.method = b"HEAD" self.write(b'') self.finish() return if self.method in (supportedMethods): # We MUST include an Allow header # (RFC 2616, 10.4.6 and 14.7) self.setHeader('Allow', ', '.join(allowedMethods)) s = ('''Your browser approached me (at %(URI)s) with''' ''' the method "%(method)s". I only allow''' ''' the method%(plural)s %(allowed)s here.''' % { 'URI': escape(self.uri), 'method': self.method, 'plural': ((len(allowedMethods) > 1) and 's') or '', 'allowed': ', '.join(allowedMethods) }) epage = resource.ErrorPage(http.NOT_ALLOWED, "Method Not Allowed", s) body = epage.render(self) else: epage = resource.ErrorPage( http.NOT_IMPLEMENTED, "Huh?", "I don't know how to treat a %s request." % (escape(self.method.decode("charmap")),)) body = epage.render(self) # end except UnsupportedMethod if body == NOT_DONE_YET: return if not isinstance(body, bytes): body = resource.ErrorPage( http.INTERNAL_SERVER_ERROR, "Request did not return bytes", "Request: " + html.PRE(reflect.safe_repr(self)) + "<br />" + "Resource: " + html.PRE(reflect.safe_repr(resrc)) + "<br />" + "Value: " + html.PRE(reflect.safe_repr(body))).render(self) if self.method == b"HEAD": if len(body) > 0: # This is a Bad Thing (RFC 2616, 9.4) log.msg("Warning: HEAD request %s for resource %s is" " returning a message body." " I think I'll eat it." % (self, resrc)) self.setHeader(b'content-length', intToBytes(len(body))) self.write(b'') else: self.setHeader(b'content-length', intToBytes(len(body))) self.write(body) self.finish()