The errata list is a list of errors and their corrections that were found after the product was released.
The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.
Version |
Location |
Description |
Submitted by |
Date submitted |
PDF |
|
example code:
h = HeadlineRetriever()
d = h.getHeadline("1234567890" * 6)
d.addCallbacks(printData, printError)
raise TypeError("Strings are not supported by Failure")
|
John Santiago Jr. |
Aug 24, 2014 |
Printed, PDF |
113, 114 |
In page 114, paragraph "Before writing this test case..." is redundant and confusing.
In the code example at 113 the reactor is already parameterized.
I think one of them should go. Either code example or paragraph.
|
Anton Antonov |
Jan 24, 2015 |
PDF |
Page 17
Example 2-4. quoteclient.py |
Should the QuoteProtocol class be derived from protocol.ClientProtocol instead of the protocol.Protocol?
|
Tom Trop |
Apr 08, 2014 |
PDF |
Page 19
Item 3 in the list |
3. Clients can make make many simultaneous connections to a server.
SHOULD BE CHANGED TO:
3. Clients can make many simultaneous connections to a server.
|
David Z. Han |
Mar 28, 2014 |
PDF |
Page 19
First line |
In the echo server
SHOULD BE CHANGED TO:
In the quote server
|
David Z. Han |
Mar 28, 2014 |
|
27
Example 3-2 |
Example 3-2 demonstrates calling an errback with a string argument (Python type str). This is no longer supported in Twisted as of September 2012: http://twistedmatrix.com/pipermail/twisted-commits/2012-September/036016.html. Running the code verbatim raises an "exceptions.TypeError: Strings are not supported by Failure". Failure expects an Exception or a subclass thereof.
This error affects Example 3-2, and all subsequent examples that call addErrback with a string argument.
Example 3-2 would run if the last line was replaced with:
d.errback(Exception("Triggering errback"))
|
Garrett Robinson |
May 21, 2013 |
PDF |
Page 27
1st example |
example call:
d.errback("Triggering errback.")
produces an unexpected error:
File "/usr/local/lib/python2.7/dist-packages/twisted/python/failure.py", line 204, in __init__
raise TypeError("Strings are not supported by Failure")
TypeError: Strings are not supported by Failure
|
Alex Karpov |
Jun 30, 2013 |
Printed |
Page 27
Example 3-2 Using addErrback |
To generate the correct error message used in Example 3-2, the program should be changed to the following:
from twisted.internet.defer import Deferred
from twisted.python.failure import DefaultException
def myErrback(failure):
print failure
d = Deferred()
d.addErrback(myErrback)
d.errback(DefaultException("Triggering errback."))
When the above is run, it will generate the error message listed for Example 3-2:
[Failure instance: Traceback (failure with no frames): <class 'twisted.python.failure.DefaultException'>: Triggering errback.
]
|
Thomas R. Stevenson |
Oct 04, 2015 |
PDF |
Page 28
Near middle of page |
In the sentence "Example 3-4 retrieves a headline ... or printing an error to stderr if ...", stderr should be stdout, because the printError() function (on the next page) simply calls "print failure", which goes to stdout.
|
Tom Trop |
Apr 09, 2014 |
PDF |
Page 34
Fig. 3-3 |
The example is meatn to illustrate the behaviour of addCallbacks (plural), but the text says:
addCallback(myCallback, myErrback)
|
Alex Karpov |
Jun 30, 2013 |
PDF |
Page 34
First line in Figure 3-3 |
addCallback(myCallback, myErrback)
SHOULD BE CHANGED TO:
addCallbacks(myCallback, myErrback)
|
David Z. Han |
Mar 28, 2014 |
PDF, ePub |
Page 34
Figure 3-3 |
The text in the image:
"addCallback(myCallback, myErrback)"
should be:
"addCallbacks(myCallback, myErrback)"
|
Zoltan Benedek |
Nov 19, 2014 |
PDF, ePub |
Page 43, 46
2nd paragraph |
PDF:
On page 43:
"requestFactory instance variable"
should be:
"requestFactory class variable"
On page 46:
"isLeaf instance variable"
should be:
"isLeaf class variable"
|
Zoltan Benedek |
Nov 26, 2014 |
PDF |
Page 43
2nd paragraph after the code sample |
Typo: "MyRequestHander" supposedly means "MyRequestHandler"
|
Tibor Simon |
May 03, 2016 |
PDF |
Page 47
Line 13 from the bottom |
an instance of twisted.web.error.NoResource
SHOULD BE CHANGED TO:
an instance of twisted.web.resource.NoResource
|
David Z. Han |
Mar 28, 2014 |
PDF |
Page 53
Last line of code Example 5-1. print_resource.py |
Example code 5-1 print_resource.py is calling 'exit(1)'. Because it is importing 'sys' the call to 'exit()' should be prefixed by system module. like 'sys.exit(1)'.
Current example:
```
import sys
# Some code
if len(sys.argv) != 2:
print("...")
exit(1)
```
Expected correction:
```
import sys
# Some code
if len(sys.argv) != 2:
print("...")
sys.exit(1)
```
|
Jaysinh Shukla |
May 10, 2018 |
PDF |
Page 54
Second line in section Downloading a Web Resource |
getPage
SHOULD BE CHANGED TO:
downloadPage
|
David Z. Han |
Mar 28, 2014 |
PDF |
Page 59
Line 7: print statement |
post_resource.py
SHOULD BE CHANGED TO:
post_data.py
|
David Z. Han |
Mar 28, 2014 |
PDF |
Page 59
middle of page starting at ``class ResourcePrinter`` |
Looks like ``class ResourcePrinter`` and beyond is indented into the body of the ``StringProducer`` class.
|
Chapman |
Apr 04, 2014 |
Printed |
Page 193
Example Code multiservice.py |
Due to the change from python2 -> python3, strings are handled differently, which makes it necessary to encode and decode back and forth to feed twisted bytestrings where necessary.
It took some time and python knowledge to get the mutliservice.py example code to run on recent Python (3.9.2)
Hopefully this helps anyone who is as hooked on that piece of code as I am.
>>>>>>>> multiservice.py <<<<<<<<<<<
from twisted.application import service, internet
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic
from twisted.web import resource, server as webserver
class Reverser:
def __init__(self):
self.history = []
def reverse(self, string):
self.history.append(string)
reversed = string[::-1]
return reversed
class ReverserLineProtocol(basic.LineReceiver):
def lineReceived(self, line):
if line == b'quit':
self.handle_quit()
else:
#l = self.factory.reverser.reverse(line)
l = line.decode('utf-8')
rev = self.factory.reverser.reverse(l)
self.sendLine(rev.encode('utf-8'))
def handle_quit(self):
self.transport.loseConnection()
class ReverserLineFactory(protocol.ServerFactory):
protocol = ReverserLineProtocol
def __init__(self, reverser):
self.reverser = reverser
class ReverserPage(resource.Resource):
def __init__(self, reverser):
self.reverser = reverser
def render(self, request):
if b"string" in request.args.keys():
#if request.args.has_key("string"):
string = request.args[b"string"][0]
s = string.decode('utf-8')
reversed = self.reverser.reverse(s)
else:
reversed = ""
html = """
<html><body><form>
<input type='text' name='string' value='%s' />
<input type='submit' value='Go' />
<h2>Previous Strings</h2>
<ul>
%s
</ul>
</form></body></html>
""" % (reversed,
"\n".join(["<li>%s</li>" % s for s in self.reverser.history]))
return html.encode('utf-8')
class ServiceAdminPage(resource.Resource):
def __init__(self, app):
self.app = app
def render_GET(self, request):
request.write(b"""
<html><body>
<h1>Current Services</h1>
<form method='post'>
<ul>
""")
for srv in service.IServiceCollection(self.app):
if srv.running:
checked = "checked='checked'"
else:
checked = ""
services = """
<input type='checkbox' %s name='service' value='%s'>%s<br />
""" % (checked, srv.name, srv.name)
request.write(services.encode('utf-8'))
request.write(b"""
<input type='submit' value='Go' />
</form>
</body></html>
""")
return b''
def render_POST(self, request):
actions = []
#serviceList = request.args.get(b'service', [])
serviceList = [ x.decode('utf-8') for x in request.args.get(b'service', []) ]
#print("[DBG] service: " + serviceList)
print(serviceList) # TODO: this seems to be empty regardless of what it is called with
for srv in service.IServiceCollection(self.app):
if srv.running and not srv.name in serviceList:
stopping = defer.maybeDeferred(srv.stopService)
actions.append(stopping)
elif not srv.running and srv.name in serviceList:
# wouldn't work if this program were using reserved ports
# and running under an unprivileged user id
starting = defer.maybeDeferred(srv.startService)
actions.append(starting)
defer.DeferredList(actions).addCallback(
self._finishedActions, request)
return webserver.NOT_DONE_YET
def _finishedActions(self, results, request):
request.redirect('/')
request.finish()
application = service.Application("Reverser")
reverser = Reverser()
lineService = internet.TCPServer(2323, ReverserLineFactory(reverser))
lineService.setName("Telnet")
lineService.setServiceParent(application)
webRoot = resource.Resource()
webRoot.putChild(b'', ReverserPage(reverser))
webService = internet.TCPServer(8000, webserver.Site(webRoot))
webService.setName("Web")
webService.setServiceParent(application)
webAdminRoot = resource.Resource()
webAdminRoot.putChild(b'', ServiceAdminPage(application))
webAdminService = internet.TCPServer(8001, webserver.Site(webAdminRoot))
webAdminService.setName("WebAdmin")
webAdminService.setServiceParent(application)
|
Anonymous |
Apr 04, 2021 |