Re: [Python-Dev] Changing string constants to byte arrays ([Python-checkins] r55119 - in python/branches/py3k-struni/Lib: codecs.py test/test_codecs.py)
Hi Walter, if the bytes type does turn out to be a mutable type as suggested in PEP 358, then please make sure that no code (C code in particular), relies on the constantness of these byte objects. This is especially important when it comes to codecs, since the error callback logic would allow the callback to manipulate the byte object contents and length without the codec taking note of this change. I expect there to be other places in the interpreter which would break as well. Otherwise, you end up opening the door for segfaults and easy DOS attacks on Python3. Regards, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, May 04 2007)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 On 2007-05-04 15:05, walter.doerwald wrote:
Author: walter.doerwald Date: Fri May 4 15:05:09 2007 New Revision: 55119
Modified: python/branches/py3k-struni/Lib/codecs.py python/branches/py3k-struni/Lib/test/test_codecs.py Log: Make the BOM constants in codecs.py bytes.
Make the buffered input for decoders a bytes object.
M.-A. Lemburg wrote:
Hi Walter,
if the bytes type does turn out to be a mutable type as suggested in PEP 358,
it is.
then please make sure that no code (C code in particular), relies on the constantness of these byte objects.
This is especially important when it comes to codecs, since the error callback logic would allow the callback to manipulate the byte object contents and length without the codec taking note of this change.
Encoding is not a problem because the error callback never sees or returns a byte object. However decoding is a problem. After the callback returns the codec has to recalculate it's variables.
I expect there to be other places in the interpreter which would break as well.
Otherwise, you end up opening the door for segfaults and easy DOS attacks on Python3.
True, registering an even callback could crash the interpreter. Seems we have to update all decoding functions. Servus, Walter
M.-A. Lemburg schrieb:
Hi Walter,
if the bytes type does turn out to be a mutable type as suggested in PEP 358, then please make sure that no code (C code in particular), relies on the constantness of these byte objects.
This is especially important when it comes to codecs, since the error callback logic would allow the callback to manipulate the byte object contents and length without the codec taking note of this change.
I expect there to be other places in the interpreter which would break as well.
Otherwise, you end up opening the door for segfaults and easy DOS attacks on Python3.
If the user does not need to change these bytes objects and this is needed in more places, adding an "immutable" flag for "internal" bytes objects only settable from C, or even an immutable byte base class might be an idea. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.
On 2007-05-04 18:53, Georg Brandl wrote:
M.-A. Lemburg schrieb:
Hi Walter,
if the bytes type does turn out to be a mutable type as suggested in PEP 358, then please make sure that no code (C code in particular), relies on the constantness of these byte objects.
This is especially important when it comes to codecs, since the error callback logic would allow the callback to manipulate the byte object contents and length without the codec taking note of this change.
I expect there to be other places in the interpreter which would break as well.
Otherwise, you end up opening the door for segfaults and easy DOS attacks on Python3.
If the user does not need to change these bytes objects and this is needed in more places, adding an "immutable" flag for "internal" bytes objects only settable from C, or even an immutable byte base class might be an idea.
+1 I also suggest making all bytes literals immutable to avoid running into any issues like the above. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, May 04 2007)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611
On Friday 04 May 2007, M.-A. Lemburg wrote:
I also suggest making all bytes literals immutable to avoid running into any issues like the above.
+1 from me. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org>
[-python-dev] On 5/4/07, Fred L. Drake, Jr. <fdrake@acm.org> wrote:
On Friday 04 May 2007, M.-A. Lemburg wrote:
I also suggest making all bytes literals immutable to avoid running into any issues like the above.
+1 from me.
Rather than adding immutability to bytes objects (which has big implementation and type checking implications), consider using buffer(b"123") as an immutable bytes literal. You can freely concatenate and compare buffer objects with bytes objects. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
On 2007-05-04 19:51, Guido van Rossum wrote:
[-python-dev]
On 5/4/07, Fred L. Drake, Jr. <fdrake@acm.org> wrote:
On Friday 04 May 2007, M.-A. Lemburg wrote:
I also suggest making all bytes literals immutable to avoid running into any issues like the above.
+1 from me.
Rather than adding immutability to bytes objects (which has big implementation and type checking implications), consider using buffer(b"123") as an immutable bytes literal. You can freely concatenate and compare buffer objects with bytes objects.
I like Georg's idea of having an immutable bytes subclass. b"abc" could then be a shortcut constructor for this subclass. In general, I don't think it's a good idea to have literals turn into mutable objects, since literals are normally perceived as being constant. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, May 05 2007)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611
On 5/5/07, M.-A. Lemburg <mal@egenix.com> wrote:
On 2007-05-04 19:51, Guido van Rossum wrote:
[-python-dev]
On 5/4/07, Fred L. Drake, Jr. <fdrake@acm.org> wrote:
On Friday 04 May 2007, M.-A. Lemburg wrote:
I also suggest making all bytes literals immutable to avoid running into any issues like the above.
+1 from me.
Rather than adding immutability to bytes objects (which has big implementation and type checking implications), consider using buffer(b"123") as an immutable bytes literal. You can freely concatenate and compare buffer objects with bytes objects.
I like Georg's idea of having an immutable bytes subclass. b"abc" could then be a shortcut constructor for this subclass.
In general, I don't think it's a good idea to have literals turn into mutable objects, since literals are normally perceived as being constant.
Does that mean you want list literals to be immutable too? lst = ['a', 'b', 'c'] lst.append('d') # raises an error? STeVe -- I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a tiny blip on the distant coast of sanity. --- Bucky Katt, Get Fuzzy
On 2007-05-05 18:11, Steven Bethard wrote:
On 5/5/07, M.-A. Lemburg <mal@egenix.com> wrote:
On 2007-05-04 19:51, Guido van Rossum wrote:
[-python-dev]
On 5/4/07, Fred L. Drake, Jr. <fdrake@acm.org> wrote:
On Friday 04 May 2007, M.-A. Lemburg wrote:
I also suggest making all bytes literals immutable to avoid running into any issues like the above.
+1 from me.
Rather than adding immutability to bytes objects (which has big implementation and type checking implications), consider using buffer(b"123") as an immutable bytes literal. You can freely concatenate and compare buffer objects with bytes objects.
I like Georg's idea of having an immutable bytes subclass. b"abc" could then be a shortcut constructor for this subclass.
In general, I don't think it's a good idea to have literals turn into mutable objects, since literals are normally perceived as being constant.
Does that mean you want list literals to be immutable too?
lst = ['a', 'b', 'c'] lst.append('d') # raises an error?
Sorry, I was referring to Python literals: http://docs.python.org/ref/literals.html ie. strings and numeric constant values defined in a Python program. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, May 05 2007)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611
In general, I don't think it's a good idea to have literals turn into mutable objects, since literals are normally perceived as being constant.
Does that mean you want list literals to be immutable too?
lst = ['a', 'b', 'c'] lst.append('d') # raises an error?
That's not a literal, it's a display. The difference is that a literal denotes the same object every time it is executed. A display creates a new object every time it is executed. (another difference is that a display is a constructed thing which may contain runtime-computed components, unlike a literal). So if bytes are mutable and also have source-level representation, they should be displays, not literals. Regards, Martin
On 5/5/07, "Martin v. Löwis" <martin@v.loewis.de> wrote:
In general, I don't think it's a good idea to have literals turn into mutable objects, since literals are normally perceived as being constant.
Does that mean you want list literals to be immutable too?
lst = ['a', 'b', 'c'] lst.append('d') # raises an error?
That's not a literal, it's a display. The difference is that a literal denotes the same object every time it is executed. A display creates a new object every time it is executed. (another difference is that a display is a constructed thing which may contain runtime-computed components, unlike a literal).
So if bytes are mutable and also have source-level representation, they should be displays, not literals.
So is having mutable bytes just a matter of calling them "byte displays" instead of "byte literals" or does that also require changing something in the back end? STeVe -- I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a tiny blip on the distant coast of sanity. --- Bucky Katt, Get Fuzzy
That's not a literal, it's a display. The difference is that a literal denotes the same object every time it is executed. A display creates a new object every time it is executed. (another difference is that a display is a constructed thing which may contain runtime-computed components, unlike a literal).
So if bytes are mutable and also have source-level representation, they should be displays, not literals.
So is having mutable bytes just a matter of calling them "byte displays" instead of "byte literals" or does that also require changing something in the back end?
It's certainly also an issue of language semantics (i.e. changes to interpreter code). There are a number of options: 1. don't support creation of byte values through syntax. Instead, create bytes through a constructor function. 2. if there is syntax support, make it a display: every time you execute a bytes display, create a new value, which can then be mutated. 3. if you want it to be a literal, make it immutable: change the type, or add a flag so that it is immutable. Then put it into the co_consts array of the code object. The original complaint was that it shouldn't be in co_consts if it is mutable. In case these three options aren't clear yet, some examples: 1. def foo(): return bytes([1,2,3]) print foo() is foo() # False x = foo() x[0] = 5 # supported 2. def foo(): return b"\x01\x02\x03" print foo() is foo() # False x = foo() x[0] = 5 # supported 3. def foo(): return b"\x01\x02\x03" print foo() is foo() # True x = foo() x[0] = 5 # TypeError HTH, Martin
>> So is having mutable bytes just a matter of calling them "byte >> displays" instead of "byte literals" or does that also require >> changing something in the back end? Martin> It's certainly also an issue of language semantics (i.e. changes Martin> to interpreter code). There are a number of options: Martin> 1. don't support creation of byte values through syntax. Instead, Martin> create bytes through a constructor function. I don't read the py3k mailing list. I presume the distinction between "display" and "literal" is old hat to those folks. I've never seen the term. Can someone explain it? Thx, Skip
skip@pobox.com wrote:
>> So is having mutable bytes just a matter of calling them "byte >> displays" instead of "byte literals" or does that also require >> changing something in the back end?
Martin> It's certainly also an issue of language semantics (i.e. changes Martin> to interpreter code). There are a number of options: Martin> 1. don't support creation of byte values through syntax. Instead, Martin> create bytes through a constructor function.
I don't read the py3k mailing list. I presume the distinction between "display" and "literal" is old hat to those folks. I've never seen the term. Can someone explain it?
A literal refers to an immutable constant (i.e. 'assert 1 is 1' is allowed to be true) A display always creates a new mutable object (i.e. 'assert [] is []' is *required* to be false) The question is whether we have byte literals or displays in Py3k, and if we make them literals, whether it is still permissible for them to be mutable. Mutable objects pose all sorts of caching and aliasing problems that just don't come up with immutable objects like strings or numbers. For the work I do with low level hardware control, I suspect not having an immutable bytes variant to throw in a dictionary would be something of an inconvenience (that said, work only switched to Python 2.4 relatively recently, so I doubt Py3k will pose me any significant practical concerns on that front for quite some time :). I would personally like an interoperable bytes/frozenbytes pair (along the lines of set/frozenset) with a literal syntax to produce instances of the latter. However, I don't have a great deal of development time to devote to helping to make that happen. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
Steven Bethard wrote:
On 5/5/07, M.-A. Lemburg <mal@egenix.com> wrote:
On 2007-05-04 19:51, Guido van Rossum wrote:
[-python-dev]
On 5/4/07, Fred L. Drake, Jr. <fdrake@acm.org> wrote:
On Friday 04 May 2007, M.-A. Lemburg wrote:
I also suggest making all bytes literals immutable to avoid running into any issues like the above.
+1 from me. Rather than adding immutability to bytes objects (which has big implementation and type checking implications), consider using buffer(b"123") as an immutable bytes literal. You can freely concatenate and compare buffer objects with bytes objects. I like Georg's idea of having an immutable bytes subclass. b"abc" could then be a shortcut constructor for this subclass.
In general, I don't think it's a good idea to have literals turn into mutable objects, since literals are normally perceived as being constant.
Does that mean you want list literals to be immutable too?
lst = ['a', 'b', 'c'] lst.append('d') # raises an error?
STeVe
I think the point is rather that changes to the list linked by lst after the initial assignment shouldn't result in the assignemtn of a different value to lst if the statement is executed again (as part of a function body or in a loop, for example). regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://del.icio.us/steve.holden ------------------ Asciimercial --------------------- Get on the web: Blog, lens and tag your way to fame!! holdenweb.blogspot.com squidoo.com/pythonology tagged items: del.icio.us/steve.holden/python All these services currently offer free registration! -------------- Thank You for Reading ----------------
Steven Bethard wrote:
Does that mean you want list literals to be immutable too?
There are no "list literals" in Python, only expressions that construct lists. You might argue that b"abc" is not a literal either, but an expression that constructs a bytes object. However, it *looks* so much like a string literal that this would be a difficult distinction to keep in mind, and very likely to trip people up. -- Greg
On Fri, May 04, 2007, Guido van Rossum wrote:
[-python-dev]
On 5/4/07, Fred L. Drake, Jr. <fdrake@acm.org> wrote:
On Friday 04 May 2007, M.-A. Lemburg wrote:
I also suggest making all bytes literals immutable to avoid running into any issues like the above.
+1 from me.
Rather than adding immutability to bytes objects (which has big implementation and type checking implications), consider using buffer(b"123") as an immutable bytes literal. You can freely concatenate and compare buffer objects with bytes objects.
I'm with MAL and Fred on making literals immutable -- that's safe and lots of newbies will need to use byte literals early in their Python experience if they pick up Python to operate on network data. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "Look, it's your affair if you want to play with five people, but don't go calling it doubles." --John Cleese anticipates Usenet
On Saturday 05 May 2007, Aahz wrote:
I'm with MAL and Fred on making literals immutable -- that's safe and lots of newbies will need to use byte literals early in their Python experience if they pick up Python to operate on network data.
Yes; there are lots of places where bytes literals will be used the way str literals are today. buffer(b'...') might be good enough, but it seems more than a little idiomatic, and doesn't seem particularly readable. I'm not suggesting that /all/ literals result in constants, but bytes literals seem like a case where what's wanted is the value. If b'...' results in a new object on every reference, that's a lot of overhead for a network protocol implementation, where the data is just going to be written to a socket or concatenated with other data. An immutable bytes type would be very useful as a dictionary key as well, and more space-efficient than tuple(b'...'). Whether there should be one type with a flag indicating mutability, or two separate types (as with set and frozenset), I'm not sure. The later offers some small performance benefits, but I don't expect there's enough to really matter there. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org>
"Fred L. Drake, Jr." <fdrake@acm.org> wrote:
On Saturday 05 May 2007, Aahz wrote:
I'm with MAL and Fred on making literals immutable -- that's safe and lots of newbies will need to use byte literals early in their Python experience if they pick up Python to operate on network data.
Yes; there are lots of places where bytes literals will be used the way str literals are today. buffer(b'...') might be good enough, but it seems more than a little idiomatic, and doesn't seem particularly readable.
I'm not suggesting that /all/ literals result in constants, but bytes literals seem like a case where what's wanted is the value. If b'...' results in a new object on every reference, that's a lot of overhead for a network protocol implementation, where the data is just going to be written to a socket or concatenated with other data. An immutable bytes type would be very useful as a dictionary key as well, and more space-efficient than tuple(b'...').
I was saying the exact same thing last summer. See my discussion with Martin about parsing/unmarshaling. What I expect will happen with bytes as dictionary keys is that people will end up subclassing dictionaries (with varying amounts of success and correctness) to do something like the following... class bytesKeys(dict): ... def __setitem__(self, key, value): if isinstance(key, bytes): key = key.decode('latin-1') else: raise KeyError("only bytes can be used as keys") dict.__setitem__(self, key, value) ... Is it optimal? No. Would it be nice to have immtable bytes? Yes. Do I think it will really be a problem in parsing/unmarshaling? I don't know, but the fact that there now exists a reasonable literal syntax b'...' rather than the previous bytes([1, 2, 3, ...]) means that we are coming much closer to having what really is about the best way to handle this; Python 2.x str. - Josiah
[+python-3000; replies please remove python-dev] On 5/5/07, Josiah Carlson <jcarlson@uci.edu> wrote:
"Fred L. Drake, Jr." <fdrake@acm.org> wrote:
On Saturday 05 May 2007, Aahz wrote:
I'm with MAL and Fred on making literals immutable -- that's safe and lots of newbies will need to use byte literals early in their Python experience if they pick up Python to operate on network data.
Yes; there are lots of places where bytes literals will be used the way str literals are today. buffer(b'...') might be good enough, but it seems more than a little idiomatic, and doesn't seem particularly readable.
I'm not suggesting that /all/ literals result in constants, but bytes literals seem like a case where what's wanted is the value. If b'...' results in a new object on every reference, that's a lot of overhead for a network protocol implementation, where the data is just going to be written to a socket or concatenated with other data. An immutable bytes type would be very useful as a dictionary key as well, and more space-efficient than tuple(b'...').
I was saying the exact same thing last summer. See my discussion with Martin about parsing/unmarshaling. What I expect will happen with bytes as dictionary keys is that people will end up subclassing dictionaries (with varying amounts of success and correctness) to do something like the following...
class bytesKeys(dict): ... def __setitem__(self, key, value): if isinstance(key, bytes): key = key.decode('latin-1') else: raise KeyError("only bytes can be used as keys") dict.__setitem__(self, key, value) ...
Is it optimal? No. Would it be nice to have immtable bytes? Yes. Do I think it will really be a problem in parsing/unmarshaling? I don't know, but the fact that there now exists a reasonable literal syntax b'...' rather than the previous bytes([1, 2, 3, ...]) means that we are coming much closer to having what really is about the best way to handle this; Python 2.x str.
I don't know how this will work out yet. I'm not convinced that having both mutable and immutable bytes is the right thing to do; but I'm also not convinced of the opposite. I am slowly working on the string/unicode unification, and so far, unfortunately, it is quite daunting to get rid of 8-bit strings even at the Python level let alone at the C level. I suggest that the following exercise, to be carried out in the py3k-struni branch, might be helpful: (1) change the socket module to return bytes instead of strings (it already takes bytes, by virtue of the buffer protocol); (2) change its makefile() method so that it uses the new io.py library, in particular the SocketIO wrapper there; (3) fix up the httplib module and perhaps other similar ones. Take copious notes while doing this. Anyone up for this? I will listen! (I'd do it myself but I don't know where I'd find the time). -- --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
[+python-3000; replies please remove python-dev]
On 5/5/07, Josiah Carlson <jcarlson@uci.edu> wrote:
On Saturday 05 May 2007, Aahz wrote:
I'm with MAL and Fred on making literals immutable -- that's safe and lots of newbies will need to use byte literals early in their Python experience if they pick up Python to operate on network data.
Yes; there are lots of places where bytes literals will be used the way str literals are today. buffer(b'...') might be good enough, but it seems more than a little idiomatic, and doesn't seem particularly readable.
I'm not suggesting that /all/ literals result in constants, but bytes literals seem like a case where what's wanted is the value. If b'...' results in a new object on every reference, that's a lot of overhead for a network protocol implementation, where the data is just going to be written to a socket or concatenated with other data. An immutable bytes type would be very useful as a dictionary key as well, and more space-efficient than tuple(b'...'). I was saying the exact same thing last summer. See my discussion with Martin about parsing/unmarshaling. What I expect will happen with bytes as dictionary keys is that people will end up subclassing dictionaries (with varying amounts of success and correctness) to do something like
"Fred L. Drake, Jr." <fdrake@acm.org> wrote: the following...
class bytesKeys(dict): ... def __setitem__(self, key, value): if isinstance(key, bytes): key = key.decode('latin-1') else: raise KeyError("only bytes can be used as keys") dict.__setitem__(self, key, value) ...
Is it optimal? No. Would it be nice to have immtable bytes? Yes. Do I think it will really be a problem in parsing/unmarshaling? I don't know, but the fact that there now exists a reasonable literal syntax b'...' rather than the previous bytes([1, 2, 3, ...]) means that we are coming much closer to having what really is about the best way to handle this; Python 2.x str.
I don't know how this will work out yet. I'm not convinced that having both mutable and immutable bytes is the right thing to do; but I'm also not convinced of the opposite. I am slowly working on the string/unicode unification, and so far, unfortunately, it is quite daunting to get rid of 8-bit strings even at the Python level let alone at the C level.
I suggest that the following exercise, to be carried out in the py3k-struni branch, might be helpful: (1) change the socket module to return bytes instead of strings (it already takes bytes, by virtue of the buffer protocol); (2) change its makefile() method so that it uses the new io.py library, in particular the SocketIO wrapper there; (3) fix up the httplib module and perhaps other similar ones. Take copious notes while doing this. Anyone up for this? I will listen! (I'd do it myself but I don't know where I'd find the time).
I'm having a hard time understanding why bytes literals would be a good thing. OK, displays require the work of creating a new object (since bytes types will be mutable) but surely a mutable literal is always going to make programs potentially hard to read. If you want a representation of a bytes object in your program text doesn't that always (like other mutable types) have to represent the same value, creating new objects as necessary if previously-created objects could have been mutated. What am I missing here? regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://del.icio.us/steve.holden ------------------ Asciimercial --------------------- Get on the web: Blog, lens and tag your way to fame!! holdenweb.blogspot.com squidoo.com/pythonology tagged items: del.icio.us/steve.holden/python All these services currently offer free registration! -------------- Thank You for Reading ----------------
participants (13)
-
"Martin v. Löwis"
-
Aahz
-
Fred L. Drake, Jr.
-
Georg Brandl
-
Greg Ewing
-
Guido van Rossum
-
Josiah Carlson
-
M.-A. Lemburg
-
Nick Coghlan
-
skip@pobox.com
-
Steve Holden
-
Steven Bethard
-
Walter Dörwald