[Python-3000] iostack and sock2

Josiah Carlson jcarlson at uci.edu
Mon Jun 5 20:44:15 CEST 2006


"tomer filiba" <tomerfiliba at gmail.com> wrote:
> 
> > > well, it's too hard to design for a nonexisting module. select is all there
> > > is that's platform independent.
> >
> > It is /relatively/ platform independent.
> 
> if it runs on windows, linux, *bsd, solaris, it's virtually platform
> independent.
> i don't consider the nokia N60 or whatever the name was, as well as other
> esoteric environments, as "platforms", at least not such that should be taken
> into consideration when designing APIs and standard modules.

[the following snipped from a different reply of yours]
> compare
> select([sock1, sock2, sock3], [], [])
> to
> sock1.async_read(100, callback)
> 
> how can you block/wait for multiple streams?

Depending on the constants defined during compile time, the file handle
limit can be lower or higher than expected (I once used a version with a
32 handle limit; was a bit frustrating).  Also, as discussed in the
'epoll implementation' thread on python-dev, an IOCP implementation for
Windows could perhaps be written in such a way to be compatible with the
libevent-python project.  Visiting the libevent-python example script (
http://python-hpio.net/trac/browser/Projects/libevent-python/trunk/exa
mples/echo_server.py) shows us how you can do such things.

[snip]
> > > random idea:
> > > when compiled with universal line support, python unicode should
> > > equate "\n" to any of the forementioned characters.
> > > i.e.
> > >
> > > u"\n" == u"\u2028" # True
> >
> > I'm glad that you later decided for yourself that such a thing would be
> > utterly and completely foolish.
> 
> it's not foolish, it's bad. these are different things (foolish being "lacking
> a proper rationale", and bad being "destroying the very foundations of
> python"). but again, it was kept "for the record".

I don't believe it would "[destroy] the very foundations of python"
(unicode is not the very foundation of Python, and it wouldn't destroy
unicode, only change its comparison semantics), but I do believe it
"[lacks] a proper rationale".  That is; unicode.split() should work as
expected (if not, it should be fixed), and it seems as though line
iteration over files with an encoding specified should deal with those
other line endings - though its behavior in regards to universal
newlines should probably be discussed.


> > > f.position = -10
> > > raises a ValueError, which is logical
> >
> > Raising a ValueError on an unseekable stream would be confusing.
> 
> true, but so are TypeErrors for ArgumentErrors, or TypeErrors for HashErrors,
> etc. besides, why shouldn't attributes raise IOError? after all you are working
> with *IO*, so "s.position = -10" raising an IOError isn't all too strange.
> anyway, that's a technicality and the rest of the framework can suffer delaying
> that decision for later.

What other properties on other classes do is their own business.  We are
talking about this particular implementation of this particular feature
on this particular class (or set of related classes).  If given the
choice of a ValueError or an IOError on f.position failure, I would opt
for IOError; but I would prefer f.seek() and f.tell(), because with
f.seek() you can use the "whence" parameter to get absolute or relative
seeking.


> > > class NetworkStream(InputStream, OutputStream):
> > >    ...
> > >
> > > which version of close() gets called?
> >
> > Both, you use super().
> 
> if an InputStream and OutputStream are just interfaces, that's fine,
> but still, i don't find it acceptable for one method to be defined by
> two interfaces, and then have it intersected in a deriving class.

So have both InputStream and OutputStream use super to handle other
possible .close() calls, rather than making their subclasses do so.


> perhaps the hierarchy should be
> 
> class Stream:
>     def close
>     property closed
>     def seek
>     def tell
> 
> class InputStream(Stream):
>     def read
>     def readexact
>     def readall
> 
> class OutputStream(Stream):
>     def write
> 
> but then, most of the streams, like files, pipes and sockets,
> would need to derive from both InputStream and OutputStream.

But then there are other streams where you want to call two *different* 
.close() methods, and the above would only allow for 1.  Closing
multiple times shouldn't be a problem for most streams, but not closing
enough could be a problem.


> another issue:
> 
> class  InputFile(InputStream)
>     ...
> class OutputFile(OutputStream):
>     ...
> class File(InputStream, OutputStream):
>     ....
> 
> i think there's gonna be much duplication of code, because FIle can't
> inherit from InputFile and OutputFile, as they are each a separate stream,
> while File is a single InOutStream.
> 
> and a huge class hierarchy makes attribute lookups slower.

Have you tried to measure this?  In my tests (with Python 2.3), it's
somewhere on the order of .2 microseconds per operation of difference
between the original class and a 7th level subclass (i subclasses h,
which subclasses g, which subclasses f, which subclasses, e, ...).


 - Josiah



More information about the Python-3000 mailing list