[Python-ideas] make Connections iterable

Serhiy Storchaka storchaka at gmail.com
Tue Jan 9 07:51:10 EST 2018


09.01.18 12:46, Nick Coghlan пише:
> On 9 January 2018 at 20:07, Antoine Pitrou <solipsis at pitrou.net> wrote:
>> On Mon, 8 Jan 2018 21:22:56 -0800
>> Nathaniel Smith <njs at pobox.com> wrote:
>>> I'm surprised that multiprocessing.Connection isn't iterable -- it seems
>>> like an obvious oversight.
>>
>> What is obvious about making a connection iterable?  It's the first
>> time I see someone requesting this.
> 
> If you view them as comparable to subprocess pipes, then it can be
> surprising that they're not iterable when using a line-oriented
> protocol.
> 
> If you instead view them as comparable to socket connections, then the
> lack of iteration support seems equally reasonable.
> 
> Hence my suggestion of providing a docs recipe showing an example of
> wrapping a connection in a generator in order to define a suitable way
> of getting from a raw bytestream to iterable chunks.

recv() can raise OSError, and it is more likely than raising OSError in 
file's readline(). The user code inside the loop also can perform 
writing and can raise OSError. This in the case of line-oriented files 
there is a single main source of OSError, but in the case of Connections 
there are two possible sources, and you need a way to distinguish errors 
raised by recv() and by writing. Currently you just use two different 
try-except statements.

     while True:
         try:
             data = conn.recv()
         except EOFError:
             break
         except OSError:
             # error on reading
         try:
             # user code
         except OSError:
             # error on writing

It is very easy extend the case when don't handle OSError to the case 
when handle OSError.

If Connections be iterable the code that don't handle errors looks simple:

     for data in conn:
         # user code

But this simple code is not correct. When add error handling it will 
look like:

     while True:
         try:
             data = next(conn)
         except StopIteration:
             break
         except OSError:
             # error on reading
         try:
             # user code
         except OSError:
             # error on writing

Not too different from the first example and very differen from the 
second example. This feature is not useful if properly handle errors, it 
makes the simpler only a quick code when you don't handle errors or 
handle them improperly.

Yet one concern: the Connections object has the send() method, generator 
objects also have send() methods, but with the different semantic. This 
may be confusing.



More information about the Python-ideas mailing list