Documentation Error for __hash__
Hello all, The documentation for __hash__ seems to be outdated. I'm happy to submit a patch, so long as I am not misunderstanding something. http://docs.python.org/dev/reference/datamodel.html#object.__hash__ The documentation states: If a class does not define a __cmp__() or __eq__() method it should not define a __hash__() operation either; if it defines __cmp__() or __eq__() but not __hash__(), its instances will not be usable as dictionary keys. If a class defines mutable objects and implements a __cmp__() or __eq__() method, it should not implement __hash__(), since the dictionary implementation requires that a key’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket). This may have been true for old style classes, but as new style classes inherit a default __hash__ from object - mutable objects *will* be usable as dictionary keys (hashed on identity) *unless* they implement a __hash__ method that raises a type error. Shouldn't the advice be that classes that implement comparison methods should always implement __hash__ (wasn't this nearly enforced?), and that mutable objects should raise a TypeError in __hash__. Additionally the following documentation states that __reversed__ is new in Python 2.6 and I think it was actually new in Python 2.4 (it certainly works for Python 2.5 and IronPython 1 which targets 2.4...). http://docs.python.org/dev/reference/datamodel.html#object.__reversed__ Michael Foord -- http://www.ironpythoninaction.com/ http://www.voidspace.org.uk/ http://www.trypython.org/ http://www.ironpython.info/ http://www.theotherdelia.co.uk/ http://www.resolverhacks.net/
I'm not sure about the first but as for the __reversed__ we had a discussion yesterday and it was indeed added in 2.4 (oddly, my 2.5 documentation has this correct... ) -- Haikus are easy Most make very little sense Refrigerator
Jeff Hall wrote:
I'm not sure about the first but as for the __reversed__ we had a discussion yesterday and it was indeed added in 2.4 (oddly, my 2.5 documentation has this correct... )
2.4 doc: reversed( seq) Return a reverse iterator. seq must be an object which supports the sequence protocol (the __len__() method and the __getitem__() method with integer arguments starting at 0). New in version 2.4. [no mention of __reversed__] 3.3.6 Additional methods for emulation of sequence types [ditto] However, I confirmed that __reversed__ is used by reverse() class C: def __reversed__(self): return 'abc' c=C() print(reversed(c))
abc
Michael Foord wrote:
This may have been true for old style classes, but as new style classes inherit a default __hash__ from object - mutable objects *will* be usable as dictionary keys (hashed on identity) *unless* they implement a __hash__ method that raises a type error.
Shouldn't the advice be that classes that implement comparison methods should always implement __hash__ (wasn't this nearly enforced?), and that mutable objects should raise a TypeError in __hash__.
Hmm, I thought I fixed those docs when I did the PyObject_HashNotImplemented patch... (you can set __hash__ = None rather than raising a TypeError explicitly now so that collections.Hashable correctly returns False - the slot machinery in typeobject.c will then take of turning that into PyObject_HashNotImplemented at the C level). However, looking at the relevant checkins, it appears I only updated the C API docs and didn't correct the library or language references. I reopened http://bugs.python.org/issue2235 - there are some other doc fixes I need to do this weekend for RC1, so I can tackle this at the same time. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
This may have been true for old style classes, but as new style classes inherit a default __hash__ from object - mutable objects *will* be usable as dictionary keys (hashed on identity) *unless* they implement a __hash__ method that raises a type error.
I always thought this was a bug in new-style classes (due to the fact that, as you say, they inherit __hash__ from object whether it's wanted or not). However, it seems to be fixed in Python 3.0. So this documentation is only "wrong" for Python 2.x branch. See: Python 2.6b3+ (trunk:66055, Aug 29 2008, 07:50:39) [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2 Type "help", "copyright", "credits" or "license" for more information.
class X(object): ... def __eq__(self, other): ... return True ... x = X() hash(x) -1211564180
versus Python 3.0b3+ (py3k:66055M, Aug 29 2008, 07:52:23) [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2 Type "help", "copyright", "credits" or "license" for more information.
class X(object): ... def __eq__(self, other): ... return True ... x = X() hash(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'X'
Matt
On 2008-08-28 21:31, Michael Foord wrote:
Hello all,
The documentation for __hash__ seems to be outdated. I'm happy to submit a patch, so long as I am not misunderstanding something.
http://docs.python.org/dev/reference/datamodel.html#object.__hash__
The documentation states:
If a class does not define a __cmp__() or __eq__() method it should not define a __hash__() operation either; if it defines __cmp__() or __eq__() but not __hash__(), its instances will not be usable as dictionary keys. If a class defines mutable objects and implements a __cmp__() or __eq__() method, it should not implement __hash__(), since the dictionary implementation requires that a key's hash value is immutable (if the object's hash value changes, it will be in the wrong hash bucket).
This may have been true for old style classes, but as new style classes inherit a default __hash__ from object - mutable objects *will* be usable as dictionary keys (hashed on identity) *unless* they implement a __hash__ method that raises a type error.
Being hashable is a different from being usable as dictionary key. Dictionaries perform the lookup based on the hash value, but will then have to check for hash collisions based on an equal comparison. If an object does not define an equal comparison, then it is not usable as dictionary key.
Shouldn't the advice be that classes that implement comparison methods should always implement __hash__ (wasn't this nearly enforced?),
It's probably a good idea to implement __hash__ for objects that implement comparisons, but it won't always work and it is certainly not needed, unless you intend to use them as dictionary keys.
and that mutable objects should raise a TypeError in __hash__.
That's a good idea, even though it's not needed either ;-) -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 29 2008)
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
Being hashable is a different from being usable as dictionary key.
Dictionaries perform the lookup based on the hash value, but will then have to check for hash collisions based on an equal comparison.
If an object does not define an equal comparison, then it is not usable as dictionary key.
But if an object defines *neither* __eq__ or __hash__, then by default it is usable as a dictionary key (using the id() of the object for both default equality and hashing, which is fine, and works for all user-defined types by default). An object defining __hash__ but not __eq__ is not problematic, since it still uses id() default for equality. (It just has potentially bad dictionary performance, if lots of things hash the same even though they aren't equal). This it not a problem by definition because *it is officially "okay" for two objects to hash the same, even if they aren't equal, though undesirable*. So all hashable objects are usable as dictionary keys, are they not? (As far as I know it isn't possible to have an object that does not have an equality comparison, unless you explicitly override __eq__ and have it raise a TypeError for some reason). It's probably a good idea to implement __hash__ for objects that
implement comparisons, but it won't always work and it is certainly not needed, unless you intend to use them as dictionary keys.
But from what I know, it is a *bad* idea to implement __hash__ for any mutable object with non-reference equality (where equality depends on the mutable state), as an unbreakable rule. This is because if they are inserted into a dictionary, then mutated, they may suddenly be in the wrong bucket. This is why all the mutable types in Python with non-reference equality (eg. list, set, dict) are explicitly not hashable, while the immutable types (eg. tuple, frozenset, str) are hashable, and so are the mutable types with reference equality (eg. functions, user-defined classes by default).
and that mutable objects should raise a TypeError in __hash__.
That's a good idea, even though it's not needed either ;-)
So I think my above "axioms" are a better (less restrictive, and still correct) rule than this one. It's OK for a mutable object to define __hash__, as long as its __eq__ doesn't depend upon its mutable state. For example, you can insert a function object into a dictionary, and mutate its closure, and it won't matter, because neither the hash nor the equality of the object is changing. It's only types like list and dict, with deep equality, where you run into this hash table problem.
On 2008-08-29 13:03, Matt Giuca wrote:
Being hashable is a different from being usable as dictionary key.
Dictionaries perform the lookup based on the hash value, but will then have to check for hash collisions based on an equal comparison.
If an object does not define an equal comparison, then it is not usable as dictionary key.
But if an object defines *neither* __eq__ or __hash__, then by default it is usable as a dictionary key (using the id() of the object for both default equality and hashing, which is fine, and works for all user-defined types by default).
An object defining __hash__ but not __eq__ is not problematic, since it still uses id() default for equality. (It just has potentially bad dictionary performance, if lots of things hash the same even though they aren't equal). This it not a problem by definition because *it is officially "okay" for two objects to hash the same, even if they aren't equal, though undesirable*.
Note that only instances have the default hash value id(obj). This is not true in general. Most types don't implement the tp_hash slot and thus are not hashable. Indeed, mutable types should not implement that slot unless they know what they're doing :-)
So all hashable objects are usable as dictionary keys, are they not? (As far as I know it isn't possible to have an object that does not have an equality comparison, unless you explicitly override __eq__ and have it raise a TypeError for some reason).
Sorry, I wasn't clear enough: with "not defining an equal comparison" I meant that an equal comparison does not succeed, ie. raises an exception or returns Py_NotImplemented (at the C level). Due to the default of using the id(obj) as fallback for the equal comparison, this has to be explicitly coded for. If this is not the case (and that's probably the most common situation), then you're right: hashable implies usable as dictionary key.
It's probably a good idea to implement __hash__ for objects that implement comparisons, but it won't always work and it is certainly not needed, unless you intend to use them as dictionary keys.
But from what I know, it is a *bad* idea to implement __hash__ for any mutable object with non-reference equality (where equality depends on the mutable state), as an unbreakable rule. This is because if they are inserted into a dictionary, then mutated, they may suddenly be in the wrong bucket. This is why all the mutable types in Python with non-reference equality (eg. list, set, dict) are explicitly not hashable, while the immutable types (eg. tuple, frozenset, str) are hashable, and so are the mutable types with reference equality (eg. functions, user-defined classes by default).
Right. By implementing __hash__ in classes you have the explicit choice of either raising an exception or returning a useful hash value. Again, the situation is better at the C level, since types don't have a default tp_hash implementation, so have to explicitly code such a slot in order for hash(obj) to work.
and that mutable objects should raise a TypeError in __hash__. That's a good idea, even though it's not needed either ;-)
So I think my above "axioms" are a better (less restrictive, and still correct) rule than this one. It's OK for a mutable object to define __hash__, as long as its __eq__ doesn't depend upon its mutable state. For example, you can insert a function object into a dictionary, and mutate its closure, and it won't matter, because neither the hash nor the equality of the object is changing. It's only types like list and dict, with deep equality, where you run into this hash table problem.
I think the documentation needs to be changed to make the defaults explicit. The documentation should probably say: "If you implement __cmp__ or __eq__ on a class, also implement a __hash__ method (and either have it raise an exception or return a valid non-changing hash value for the object)." "If you implement __hash__ on classes, you should consider implementing __eq__ and/or __cmp__ as well, in order to control how dictionaries use your objects." In general, it's probably best to always implement both methods on classes, even if the application will just use one of them. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Aug 29 2008)
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
Note that only instances have the default hash value id(obj). This is not true in general. Most types don't implement the tp_hash slot and thus are not hashable. Indeed, mutable types should not implement that slot unless they know what they're doing :-)
By "instances" you mean "instances of user-defined classes"? (I carefully avoid the term "instance" on its own, since I believe that was phased out when they merged types and classes; it probably still exists in the C API but shouldn't be mentioned in Python-facing documentation). But anyway, yes, we should make that distinction. Sorry, I wasn't clear enough: with "not defining an equal comparison"
I meant that an equal comparison does not succeed, ie. raises an exception or returns Py_NotImplemented (at the C level).
Oh OK. I didn't even realise it was "valid" or "usual" to explicitly block __eq__ like that.
Again, the situation is better at the C level, since types don't have a default tp_hash implementation, so have to explicitly code such a slot in order for hash(obj) to work.
Yes but I gather that this "data model" document we are talking about is not designed for C authors, but Python authors, so it should be written for the point of view of people coding only in Python. (Only the "Extending and Embedding" and the "C API" documents are for C authors). The documentation should probably say:
"If you implement __cmp__ or __eq__ on a class, also implement a __hash__ method (and either have it raise an exception or return a valid non-changing hash value for the object)."
I agree, except maybe not for the Python 3 docs. As long as the behaviour I am observing is well-defined and not just a side-effect which could go away -- that is, if you define __eq__/__cmp__ but not __hash__, in a user-defined class, it raises a TypeError -- then I think it isn't necessary to recommend implementing a __hash__ method and raising a TypeError. Better just to leave as-is ("if it defines __cmp__()http://docs.python.org/dev/3.0/reference/datamodel.html#object.__cmp__or __eq__()http://docs.python.org/dev/3.0/reference/datamodel.html#object.__eq__but not __hash__()http://docs.python.org/dev/3.0/reference/datamodel.html#object.__hash__, its instances will not be usable as dictionary keys") and clarify the later statement.
"If you implement __hash__ on classes, you should consider implementing __eq__ and/or __cmp__ as well, in order to control how dictionaries use your objects."
I don't think I agree with that. I'm not sure why you'd implement __hash__ without __eq__ and/or __cmp__, but it doesn't cause issues so we may as well not address it.
In general, it's probably best to always implement both methods on classes, even if the application will just use one of them.
Well it certainly is for new-style classes in the 2.x branch. I don't think you should implement __hash__ in Python 3 if you just want a non-hashable object (since this is the default behaviour anyway). A lot of my opinion here, though, which doesn't count very much -- so I'm just making suggestions. Matt
M.-A. Lemburg wrote:
On 2008-08-28 21:31, Michael Foord wrote:
Hello all,
The documentation for __hash__ seems to be outdated. I'm happy to submit a patch, so long as I am not misunderstanding something.
http://docs.python.org/dev/reference/datamodel.html#object.__hash__
The documentation states:
If a class does not define a __cmp__() or __eq__() method it should not define a __hash__() operation either; if it defines __cmp__() or __eq__() but not __hash__(), its instances will not be usable as dictionary keys. If a class defines mutable objects and implements a __cmp__() or __eq__() method, it should not implement __hash__(), since the dictionary implementation requires that a key's hash value is immutable (if the object's hash value changes, it will be in the wrong hash bucket).
This may have been true for old style classes, but as new style classes inherit a default __hash__ from object - mutable objects *will* be usable as dictionary keys (hashed on identity) *unless* they implement a __hash__ method that raises a type error.
Being hashable is a different from being usable as dictionary key.
Dictionaries perform the lookup based on the hash value, but will then have to check for hash collisions based on an equal comparison.
If an object does not define an equal comparison, then it is not usable as dictionary key.
Shouldn't the advice be that classes that implement comparison methods should always implement __hash__ (wasn't this nearly enforced?),
It's probably a good idea to implement __hash__ for objects that implement comparisons, but it won't always work and it is certainly not needed, unless you intend to use them as dictionary keys.
So you're suggesting that we document something like. Classes that represent mutable values and define equality methods are free to define __hash__ so long as you don't mind them being used incorrectly if treated as dictionary keys... Technically true, but not very helpful in my opinion... :-) Michael
and that mutable objects should raise a TypeError in __hash__.
That's a good idea, even though it's not needed either ;-)
-- http://www.ironpythoninaction.com/ http://www.voidspace.org.uk/ http://www.trypython.org/ http://www.ironpython.info/ http://www.resolverhacks.net/ http://www.theotherdelia.co.uk/
It's probably a good idea to implement __hash__ for objects that implement comparisons, but it won't always work and it is certainly not needed, unless you intend to use them as dictionary keys.
So you're suggesting that we document something like.
Classes that represent mutable values and define equality methods are free to define __hash__ so long as you don't mind them being used incorrectly if treated as dictionary keys...
Technically true, but not very helpful in my opinion... :-)
No, I think he was suggesting we document that if a class overrides __eq__, it's a good idea to also implement __hash__, so it can be used as a dictionary key. However I have issues with this. First, he said: "It's probably a good idea to implement __hash__ for objects that implement comparisons, but it won't always work and it is certainly not needed, unless you intend to use them as dictionary keys." You can't say "certainly not needed unless you intend to use them as dictionary keys", since if you are defining an object, you never know when someone else will want to use them as a dict key (or in a set, mind!) So *if possible*, it is a good idea to implement __hash__ if you are implementing __eq__. But also, it needs to be very clear that if you *should not* implement __hash__ on a mutable object -- and it already is. So basically the docs should suggest that it is a good idea to implement __hash__ if you are implementing __eq__ on an immutable object. HOWEVER, There are two contradictory pieces of information in the docs. a) "if it defines __cmp__()http://docs.python.org/dev/reference/datamodel.html#object.__cmp__or __eq__() http://docs.python.org/dev/reference/datamodel.html#object.__eq__but not __hash__()http://docs.python.org/dev/reference/datamodel.html#object.__hash__, its instances will not be usable as dictionary keys." versus b) "User-defined classes have __cmp__()http://docs.python.org/dev/3.0/reference/datamodel.html#object.__cmp__and __hash__()http://docs.python.org/dev/3.0/reference/datamodel.html#object.__hash__methods by default; with them, all objects compare unequal and x.__hash__() returns id(x)." Note that these statements are somewhat contradictory: if a class has a __hash__ method by default (as b suggests), then it isn't possible to "not have a __hash__" (as suggested by a). In Python 2, statement (a) is true for old-style classes only, while statement (b) is true for new style classes only. This distinction needs to be made. (For old-style classes, it isn't the case that it has a __hash__ method by default - rather that the hash() function knows how to deal with objects without a __hash__ method, by calling id()). In Python 3, statement (a) is true always, while statement (b) is not (in fact just the same as old-style classes are in Python 2). So the Python 3 docs can get away with being simpler (without having to handle that weird case). I just saw Marc-Andre's new email come in; I'll look at that now. Matt
Matt Giuca wrote:
It's probably a good idea to implement __hash__ for objects that implement comparisons, but it won't always work and it is certainly not needed, unless you intend to use them as dictionary keys.
So you're suggesting that we document something like.
Classes that represent mutable values and define equality methods are free to define __hash__ so long as you don't mind them being used incorrectly if treated as dictionary keys...
Technically true, but not very helpful in my opinion... :-)
No, I think he was suggesting we document that if a class overrides __eq__, it's a good idea to also implement __hash__, so it can be used as a dictionary key.
I strongly advise people interested in this topic to take a closer look at the functionality that was added to address issue 2235. The "don't inherit __hash__" behaviour has been backported from 3.0 and broke a bunch of code, but the naive fix of reverting to the 2.5 behaviour proceeded to make the 2.6 version of collections.Hashable completely useless (since pretty much *everything* then claimed to be hashable, including all of the container types in the standard library). After thrashing out those problems, the 2.6 behaviour ended up being: - __hash__ is still inherited by default - you can block inheritance explicitly by setting "__hash__ = None" in the class definition or on the class object - for a class defined in C, you can block __hash__ inheritance by setting the tp_hash slot to PyObject_HashNotImplemented - using one of the above approaches will cause hash(obj) to raise a TypeError, as will calling the tp_hash slot directly - unlike defining your own __hash__ method, using one of the above techniques will also mean that isinstance(obj, collections.Hashable) will also return False - defining __eq__ and/or __cmp__ without defining __hash__ will lead to a Py3k Warning being raised on the class definition when run with the -3 switch The Python 3.0 behaviour is similar to the above, except that the unconditional inheritance of __hash__ is gone. If you define __eq__ or __cmp__ without defining __hash__, __hash__ will NOT be inherited from the parent class - instead, it will be set to None. The documentation of all of this could definitely use a bit more work - that's why I reopened 2235 in response to Michael's post. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org
I strongly advise people interested in this topic to take a closer look at the functionality that was added to address issue 2235. The "don't inherit __hash__" behaviour has been backported from 3.0 and broke a bunch of code, but the naive fix of reverting to the 2.5 behaviour proceeded to make the 2.6 version of collections.Hashable completely useless (since pretty much *everything* then claimed to be hashable, including all of the container types in the standard library).
After thrashing out those problems, the 2.6 behaviour ended up being: - __hash__ is still inherited by default - you can block inheritance explicitly by setting "__hash__ = None" in the class definition or on the class object - for a class defined in C, you can block __hash__ inheritance by setting the tp_hash slot to PyObject_HashNotImplemented - using one of the above approaches will cause hash(obj) to raise a TypeError, as will calling the tp_hash slot directly - unlike defining your own __hash__ method, using one of the above techniques will also mean that isinstance(obj, collections.Hashable) will also return False - defining __eq__ and/or __cmp__ without defining __hash__ will lead to a Py3k Warning being raised on the class definition when run with the -3 switch
The Python 3.0 behaviour is similar to the above, except that the unconditional inheritance of __hash__ is gone. If you define __eq__ or __cmp__ without defining __hash__, __hash__ will NOT be inherited from the parent class - instead, it will be set to None.
The documentation of all of this could definitely use a bit more work - that's why I reopened 2235 in response to Michael's post.
Couple months ago I was trying to figure out how __eq__, __cmp__, __hash__ and similar methods are called in Python and in which order and wrote a docs here: http://docs.sympy.org/python-comparisons.html Feel free to reuse any of it. I wrote it to myself, as I didn't find the official docs very clear. Ondrej
On Aug 30, 2008, at 2:41 PM, "Ondrej Certik"
I strongly advise people interested in this topic to take a closer look at the functionality that was added to address issue 2235. The "don't inherit __hash__" behaviour has been backported from 3.0 and broke a bunch of code, but the naive fix of reverting to the 2.5 behaviour proceeded to make the 2.6 version of collections.Hashable completely useless (since pretty much *everything* then claimed to be hashable, including all of the container types in the standard library).
After thrashing out those problems, the 2.6 behaviour ended up being: - __hash__ is still inherited by default - you can block inheritance explicitly by setting "__hash__ = None" in the class definition or on the class object - for a class defined in C, you can block __hash__ inheritance by setting the tp_hash slot to PyObject_HashNotImplemented - using one of the above approaches will cause hash(obj) to raise a TypeError, as will calling the tp_hash slot directly - unlike defining your own __hash__ method, using one of the above techniques will also mean that isinstance(obj, collections.Hashable) will also return False - defining __eq__ and/or __cmp__ without defining __hash__ will lead to a Py3k Warning being raised on the class definition when run with the -3 switch
The Python 3.0 behaviour is similar to the above, except that the unconditional inheritance of __hash__ is gone. If you define __eq__ or __cmp__ without defining __hash__, __hash__ will NOT be inherited from the parent class - instead, it will be set to None.
The documentation of all of this could definitely use a bit more work - that's why I reopened 2235 in response to Michael's post.
Couple months ago I was trying to figure out how __eq__, __cmp__, __hash__ and similar methods are called in Python and in which order and wrote a docs here:
http://docs.sympy.org/python-comparisons.html
Feel free to reuse any of it. I wrote it to myself, as I didn't find the official docs very clear.
Ondrej
Ondrej, a patch that improves the official docs would be welcome and still potentially make 2.6/3.0
Ondrej
Ondrej, a patch that improves the official docs would be welcome and still potentially make 2.6/3.0
That'd be awesome. I need to finish my thesis in the next couple days, so I'd welcome if anyone could just take it and put usefult things in. I could get to do it the next week the earliest. Ondrej
Ondrej Certik schrieb:
Ondrej
Ondrej, a patch that improves the official docs would be welcome and still potentially make 2.6/3.0
That'd be awesome. I need to finish my thesis in the next couple days, so I'd welcome if anyone could just take it and put usefult things in. I could get to do it the next week the earliest.
Doc patches are always accepted, and I intend to update the online 2.6 and 3.0 docs continually even when the finals are released, so there is no particular deadline you have to make. 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.
Hi Georg!
On Sat, Aug 30, 2008 at 11:09 PM, Georg Brandl
Ondrej Certik schrieb:
Ondrej
Ondrej, a patch that improves the official docs would be welcome and still potentially make 2.6/3.0
That'd be awesome. I need to finish my thesis in the next couple days, so I'd welcome if anyone could just take it and put usefult things in. I could get to do it the next week the earliest.
Doc patches are always accepted, and I intend to update the online 2.6 and 3.0 docs continually even when the finals are released, so there is no particular deadline you have to make.
This is awesome, I didn't know you take care of the official docs too. I'll send the doc patches when I get to it, unless someone else does it before me. Ondrej
participants (9)
-
Georg Brandl
-
Jeff Hall
-
Jesse Noller
-
M.-A. Lemburg
-
Matt Giuca
-
Michael Foord
-
Nick Coghlan
-
Ondrej Certik
-
Terry Reedy