Closed siuszy closed 3 years ago
Thanks for reporting these issues.
The HTTPStatus.IM_A_TEAPOT
was implemented in Python 3.9, which is the target version for all the examples in the book, unless otherwise noted. See: https://docs.python.org/3/library/http.html#http-status-codes
I am not sure I understood the other problem you reported, please clarify. Thanks!
Thank you for your time and sorry for missing the version problem! My first problem is that the parser function doesn't add a default value to the bind parameter, ant it seems that the socket module would report a mistake like str,bytes or bytearray expected, not NoneType under my environment(Python3.7), the error is thrown out by socketserver.py in my library. So I don't know if it is appropriate to just add an empty string as the default value?
Hi @siuszy, The bind
cmdline argument in slow_server.py
is passed into http.server.test()
, from there into http.server._get_best_family
, and finally into socket.getaddrinfo()
.
The documentation specifies that the host
parameter from getaddrinfo
accepts str
, bytes
or None
.
And None
is exactly what the value of args.bind
will be if the --bind
parameter is not specified and its definition has no default
value, according to the definition of the parser.add_argument()
found in the line 59 you pointed out.
The example runs fine when args.bind
is None, outputing:
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
Which is exactly what is intended.
Can you please specify in detail what problem do you see exactly when the --bind
argument has no default
and is no passed in your environment?
The document said that None is accepted, but the error message thrown by the socket.bind() showed that NoneType is not allowed. I thought maybe when the default value is None, the undergo procedure is somewhat blocked by my environment(Anaconda)?
@siuszy we are unable to reproduce the problem you are having.
python -V
on the command line)?slow_server.py
script, and ending with the line with the final exception message.Thank you.
I managed to track down the problem to Python version 3.7:
$ python slow_server.py
Traceback (most recent call last):
File "slow_server.py", line 92, in <module>
bind=args.bind,
File "/usr/lib/python3.7/http/server.py", line 1230, in test
with ServerClass(server_address, HandlerClass) as httpd:
File "/usr/lib/python3.7/socketserver.py", line 452, in __init__
self.server_bind()
File "slow_server.py", line 85, in server_bind
return super().server_bind()
File "/usr/lib/python3.7/http/server.py", line 137, in server_bind
socketserver.TCPServer.server_bind(self)
File "/usr/lib/python3.7/socketserver.py", line 466, in server_bind
self.socket.bind(self.server_address)
TypeError: str, bytes or bytearray expected, not NoneType
The default value for the bind=
parameter of http.server.test
in that version is the empty string instead of None
.
Adding a default='',
to the argument parser configuration for the bind
parameter fixes it for Python 3.7:
parser.add_argument('--bind', '-b', metavar='ADDRESS', default='',
help='Specify alternate bind address '
'[default: all interfaces]')
But it breaks for more recent versions, which expects None
as the default parameter, so it's not an acceptable solution.
A more complicated solution for stradling these versions would be to try to fetch the default bind=
value from the http.server.test()
function, or to try not to pass the bind=
argument if the value is not given on the command line.
But I believe both these alternatives are out of scope for the code in the book, which should strive for simplicity.
@ramalho @leorochael sorry for causing this trouble and haven't clarified the exact error! Last comment showed the exact trouble I met and further gave me the answer, thank you! I tried to locate the exact function that caused the trouble but I was totally lost (thought it was something in the socket module).
I deployed the local server according to SETTING UP TEST SERVERS, finding two small suspected errors both in slow_server.py.
The first one is about the parser in the main fucncion(Line 59). The sokcet module requires the parameter bind to be str, bytes, or bytearray , so I add a default value as the other part. (This problem is maybe linked to the python environment thing)
The second one is in the doGet function of SlowHTTPRequestHandler(Line41). I get an AttributeError when I first ran the ERROR option, which told me that the HTTPStatus did not have this attribute IM_A_TEAPOT, so maybe we could just throw a number(418 according to the book) instead?