[Python-3000] iostack and sock2

tomer filiba tomerfiliba at gmail.com
Mon Jun 5 21:26:21 CEST 2006


> 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"

no, it would break the basic rules of comparisson. all of the sudden,
0x0a == 0x2028 == 0x85, etc. so you can't tell whether you got a
"\x0a" character of "\x85" one... it would make python inconsistent.
but this discussion is silly, let's quit it. we are both -1 on it.

> 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.

unicode being native to python is gonna be one big pain to implement :)

> If given the
> choice of a ValueError or an IOError on f.position failure, I would opt
> for IOError;

so would i.

> 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.

yes, but +=/-= can be overriden to provide "efficient seeking". and, just
thought about it: just like negative indexes of sequences, negative positions
should be relative to the end of the stream. for example:

f.position = 4     # absolute -- seek(4, "start")
f.position += 6   # relative to current -- seek(6, "curr")
f.position = -7    # relative to end of stream -- seek(-7, "end")

that's easy to implement and easy AND efficient to work with.

> 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.

hrrm... what do you mean by "closing multiple times"? like socket.shutdown
for reading or for writing? but other than sockets, what else can be closed
in multiple ways? you can't close the "reading" of a file, while keeping it
open for writing.

f = FileStream(...)
InputStream.close(f)
f.write(...) # exception: stream closed

> 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.

i didn't see this before. i'll look into it.

> > 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

no, i guess i fell for the common urban legend. sorry.

thanks for the feedback.


-tomer

On 6/5/06, Josiah Carlson <jcarlson at uci.edu> wrote:
>
> "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