classification
Title: asyncio create_server() not always accepts the 'port' parameter as str
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.6
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: docs@python Nosy List: berker.peksag, docs@python, giampaolo.rodola, gvanrossum, pitrou, vstinner, xdegaye, yselivanov
Priority: normal Keywords:

Created on 2016-02-25 13:51 by xdegaye, last changed 2016-06-08 11:01 by berker.peksag. This issue is now closed.

Messages (3)
msg260857 - (view) Author: Xavier de Gaye (xdegaye) * (Python triager) Date: 2016-02-25 13:51
create_server() used to accept the 'port' parameter as a string before in all cases (until last december at least).
The following session shows the difference in behavior when the listening address is INADDR_ANY and '127.0.0.1':

============================
$ python
Python 3.6.0a0 (default:47fa003aa9f1, Feb 24 2016, 13:09:02) 
[GCC 5.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from asyncio import *
>>> loop = get_event_loop()
>>> coro = loop.create_server(Protocol(), '', '12345')
>>> loop.run_until_complete(coro)
<Server sockets=[<socket.socket fd=7, family=AddressFamily.AF_INET, type=2049, proto=6, laddr=('0.0.0.0', 12345)>, <socket.socket fd=9, family=AddressFamily.AF_INET6, type=2049, proto=6, laddr=('::', 12345, 0, 0)>]>
>>> coro = loop.create_server(Protocol(), '127.0.0.1', '12345')
>>> loop.run_until_complete(coro)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/asyncio/base_events.py", line 373, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.6/asyncio/futures.py", line 274, in result
    raise self._exception
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 240, in _step
    result = coro.send(None)
  File "/usr/local/lib/python3.6/asyncio/base_events.py", line 946, in create_server
    sock.bind(sa)
TypeError: an integer is required (got type str)
============================

IMPHO python should consistently either accept 'port' as str or require 'port' as int.
msg260877 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-02-25 18:42
I don't know why it used to accept a string port, but I can't find anything in the docs indicating that is acceptable. I am guessing the doc authors assumed it was so obvious that a port is an integer they forgot to mention it.

I can guess that in the past some system API was used that considered the port a "servname" to be looked up in /etc/services (likely the getaddrinfo() call).

But if you were passing '12345' instead of 12345, well, you always had a latent bug in your program.

I don't think the code ought to be adjusted to explicitly reject string ports; but I do think the docs should be clarified on the issue.
msg267833 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2016-06-08 11:01
After changeset 3ec208c01418 this is no longer an issue:

>>> from asyncio import *
>>> loop = get_event_loop()
>>> coro = loop.create_server(Protocol(), '', '12345')
>>> loop.run_until_complete(coro)
<Server sockets=[<socket.socket fd=7, family=AddressFamily.AF_INET, type=2049, proto=6, laddr=('0.0.0.0', 
>>> coro = loop.create_server(Protocol(), '127.0.0.1', '12345')
>>> loop.run_until_complete(coro)
Traceback (most recent call last):
  File "/home/berker/projects/cpython/default/Lib/asyncio/base_events.py", line 981, in create_server
    sock.bind(sa)
OSError: [Errno 98] Address already in use

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/berker/projects/cpython/default/Lib/asyncio/base_events.py", line 404, in run_until_complete
    return future.result()
  File "/home/berker/projects/cpython/default/Lib/asyncio/futures.py", line 274, in result
    raise self._exception
  File "/home/berker/projects/cpython/default/Lib/asyncio/tasks.py", line 240, in _step
    result = coro.send(None)
  File "/home/berker/projects/cpython/default/Lib/asyncio/base_events.py", line 985, in create_server
    % (sa, err.strerror.lower()))
OSError: [Errno 98] error while attempting to bind on address ('127.0.0.1', 12345): address already in use

The traceback looks a bit noisy though. Perhaps it needs ``... from None`` or something like that.
History
Date User Action Args
2016-06-08 11:01:06berker.peksagsetstatus: open -> closed

nosy: + berker.peksag
messages: + msg267833

resolution: out of date
stage: resolved
2016-02-25 18:42:38gvanrossumsetnosy: + docs@python
messages: + msg260877

assignee: docs@python
components: + Documentation, - Library (Lib)
2016-02-25 13:51:59xdegayecreate