Re: [Python-Dev] Documentation Error for __hash__

2008-08-29 Thread M.-A. Lemburg
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
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Documentation Error for __hash__

2008-08-29 Thread Matt Giuca
> 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.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Documentation Error for __hash__

2008-08-29 Thread Michael Foord

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/

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Documentation Error for __hash__

2008-08-29 Thread M.-A. Lemburg
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
___

Re: [Python-Dev] Documentation Error for __hash__

2008-08-29 Thread Matt Giuca
>
>> 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__()or
__eq__() but
not
__hash__(),
its instances will not be usable as dictionary keys."
versus
b) "User-defined classes have
__cmp__()and
__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
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Documentation Error for __hash__

2008-08-29 Thread Matt Giuca
> 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__()or
__eq__()but
not
__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
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-3000] what version of bsddb to use/accept for 2.6/3.0

2008-08-29 Thread Trent Nelson
On Sun, Aug 24, 2008 at 06:15:06PM -0700, Neal Norwitz wrote:
> It looks like the WIndows buildbots use 4.4.20.  Unfortunately, the
> Windows bots aren't in great shape either.

It won't be that hard to bump 3.0 on Windows to use 4.7 (assuming
that the 3.0 bsddb codebase has Jesus's new code).  I'll be able
to take a look at this early next week.

Trent.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Documentation Error for __hash__

2008-08-29 Thread Nick Coghlan
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   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---
http://www.boredomandlaziness.org
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Summary of Python tracker Issues

2008-08-29 Thread Python tracker

ACTIVITY SUMMARY (08/22/08 - 08/29/08)
Python tracker at http://bugs.python.org/

To view or respond to any of the issues listed below, click on the issue 
number.  Do NOT respond to this message.


 2029 open (+66) / 13524 closed (+16) / 15553 total (+82)

Open issues with patches:   655

Average duration of open issues: 704 days.
Median duration of open issues: 1760 days.

Open Issues Breakdown
   open  2015 (+65)
pending14 ( +1)

Issues Created Or Reopened (84)
___

__eq__ / __hash__ check doesn't take inheritance into account08/28/08
   http://bugs.python.org/issue2235reopened ncoghlan  
   patch   

Objects/obmalloc.c:529: warning: comparison is always false due  08/24/08
   http://bugs.python.org/issue3642reopened christian.heimes  
   64bit   

IA5 Encoding should be in the default encodings  08/22/08
CLOSED http://bugs.python.org/issue3649created  pascal.bach   
   

Memory leak in bytes.split() 08/22/08
CLOSED http://bugs.python.org/issue3650created  amaury.forgeotdarc
   patch, needs review 

eval() leaks 1 reference every time  08/22/08
CLOSED http://bugs.python.org/issue3651created  amaury.forgeotdarc
   patch, needs review 

Remove DeprecationWarning in _warnings about 'line'  08/23/08
   http://bugs.python.org/issue3652created  brett.cannon  
   

segfault calling sys.excepthook with non-Exception argument  08/23/08
CLOSED http://bugs.python.org/issue3653created  ajaksu2   
   patch, needs review 

Duplicated test name in regex test script08/23/08
CLOSED http://bugs.python.org/issue3654created  mrabarnett
   

latexwriter: \footnotemark can only take numbers as arguments08/23/08
   http://bugs.python.org/issue3655created  pv
   

unicode encoding has lots of leaks of bytes  08/24/08
CLOSED http://bugs.python.org/issue3656created  nnorwitz  
   

pickle can pickle the wrong function 08/24/08
   http://bugs.python.org/issue3657created  nnorwitz  
   

fix for pychecker property complaints08/24/08
   http://bugs.python.org/issue3658created  skip.montanaro
   patch, easy, needs review   

sqlite: enumeration value 'TYPE_STRING' not handled in switch08/24/08
   http://bugs.python.org/issue3659created  christian.heimes  
   

reference leaks in 3.0   08/24/08
   http://bugs.python.org/issue3660created  nnorwitz  
   patch   

sys.call_tracing segfaults   08/24/08
   http://bugs.python.org/issue3661created  ajaksu2   
   

_fileio._FileIO segfaults08/24/08
CLOSED http://bugs.python.org/issue3662created  ajaksu2   
   needs review

Extra DECREF on syntax errors08/24/08
CLOSED http://bugs.python.org/issue3663created  amaury.forgeotdarc
   patch, needs review 

Pickler.dump from a badly initialized Pickler segfaults  08/24/08
   http://bugs.python.org/issue3664created  ajaksu2   
   

Support \u and \U escapes in regexes 08/24/08
   http://bugs.python.org/issue3665created  georg.brandl  
   patch   

atexit.register with bad input segfaults on ex

Re: [Python-Dev] Things to Know About Super

2008-08-29 Thread Nick Coghlan
Michele Simionato wrote:
> OTOH, for what concerns multiple inheritance, I am still not
> convinced it is really worth it. I mean, the MRO is beautiful,
> elegant and all that on paper, but on real-life code things as different,
> especially from the side of the users of frameworks heavily
> based on inheritance.

The mixin methods in the ABC machinery would be a lot less useful
without multiple inheritance (and the collections ABCs would be a whole
lot harder to define and to write).

So if you're looking for use cases for multiple inheritance, I'd suggest
starting with the Python 2.6 collections module and seeing how you would
go about rewriting it using only single inheritance. I believe the new
io module is also fairly dependent on multiple inheritance.

Cheers,
Nick.

-- 
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---
http://www.boredomandlaziness.org
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Things to Know About Super

2008-08-29 Thread Michele Simionato
On Fri, Aug 29, 2008 at 6:15 PM, Nick Coghlan <[EMAIL PROTECTED]> wrote:
> The mixin methods in the ABC machinery would be a lot less useful
> without multiple inheritance (and the collections ABCs would be a whole
> lot harder to define and to write).
>
> So if you're looking for use cases for multiple inheritance, I'd suggest
> starting with the Python 2.6 collections module and seeing how you would
> go about rewriting it using only single inheritance. I believe the new
> io module is also fairly dependent on multiple inheritance.

I am very well aware of the collection module and the ABC mechanism.
However, you are missing that mixins can be implemented in a single-inheritance
world without the complications of the MRO. See my answer to Alex
Martelli in this same thread.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Things to Know About Super

2008-08-29 Thread Casey Duncan

On Aug 29, 2008, at 11:46 AM, Michele Simionato wrote:

On Fri, Aug 29, 2008 at 6:15 PM, Nick Coghlan <[EMAIL PROTECTED]>  
wrote:

The mixin methods in the ABC machinery would be a lot less useful
without multiple inheritance (and the collections ABCs would be a  
whole

lot harder to define and to write).

So if you're looking for use cases for multiple inheritance, I'd  
suggest
starting with the Python 2.6 collections module and seeing how you  
would
go about rewriting it using only single inheritance. I believe the  
new

io module is also fairly dependent on multiple inheritance.


I am very well aware of the collection module and the ABC mechanism.
However, you are missing that mixins can be implemented in a single- 
inheritance

world without the complications of the MRO. See my answer to Alex
Martelli in this same thread.


As interesting as this conversation is at a meta-level, I'm not sure  
how much more can be accomplished here by debating the merits of  
multiple vs. single inheritance. Unfortunately I think this is a case  
where there is not just one good way to do it in all cases, especially  
given the subjective nature of "good" in this context.


This is what I take away from this:

- super() is tricky to use at best, and its documentation is  
inaccurate and incomplete. I think it should also be made more clear  
that super() is really mostly useful for framework developers,  
including users extending frameworks. Unfortunately many frameworks  
require you to extend them in order to write useful applications in my  
experience, so it trickles down to the app developer at times. In  
short, more correct documentation == good.


- The difficulties of super() are really symptomatic of the  
difficulties of multiple inheritance. I think it's clear that multiple  
inheritance is here to stay in Python, and it solves certain classes  
of problems quite well. But, it requires careful consideration, and  
it's easy to get carried away and create a huge mess (ala Zope2, which  
I am all too familiar), and it can hinder code clarity as much as it  
facilitates reuse.


- There are good alternatives to multiple inheritance for many cases,  
but there are cases where multiple inheritance is arguably best.  
Traits are a possible alternative that deserve further study. I think  
that study would be greatly aided by a 3rd-party library implementing  
traits for Python. If traits are to gain any traction or ever be  
considered for inclusion into the language such a library would need  
to exist first and demonstrate its utility.


I know I'm probably just stating the obvious here, but I found it  
therapeutic ;^)


-Casey
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Things to Know About Super

2008-08-29 Thread glyph

On 06:33 pm, [EMAIL PROTECTED] wrote:

On Aug 29, 2008, at 11:46 AM, Michele Simionato wrote:
On Fri, Aug 29, 2008 at 6:15 PM, Nick Coghlan <[EMAIL PROTECTED]> 
wrote:



I am very well aware of the collection module and the ABC mechanism.
However, you are missing that mixins can be implemented in a single- 
inheritance

world without the complications of the MRO. See my answer to Alex
Martelli in this same thread.


- super() is tricky to use at best, and its documentation is 
inaccurate and incomplete. I think it should also be made more clear 
that super() is really mostly useful for framework developers, 
including users extending frameworks. Unfortunately many frameworks 
require you to extend them in order to write useful applications in my 
experience, so it trickles down to the app developer at times. In 
short, more correct documentation == good.


I know I'm probably just stating the obvious here, but I found it 
therapeutic ;^)


I think this is a problem with this topic.  Everyone writing about 
super() seems to be not just clearing up the documentation issues that 
surround it, but venting from personal frustrations with using it as 
well.  I confess that I have done the same - if not in widely-publicized 
articles, at least on IRC and mailing list posts.


I think it would benefit everyone if this discussion would end up with 
some patches to the library documentation that documented the semantics 
of super() more completely in the reference documentation and the 
"multiple inheritance" area of the tutorial, so that when people *do* 
run in to difficulties there is a very clear, central explanation of 
what it's supposed to do.


Personally I think the thing that really should be pointed out is that 
it may behave in a confusing manner if the signature of the method being 
invoked is not the same on all classes in the same inheritance 
hierarchy.  Theoretical problems aside, 99% of the trouble I've had with 
super() has to do with __init__ methods.


I'll try my hand at such a patch over the weekend, but I'd be grateful 
for some pointers on a "quick start" for that.  I am a complete newb at 
modifying the official documentation, and I seem to recall from a prior 
(failed) attempt that the tools are a bit difficult to work with.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Things to Know About Super

2008-08-29 Thread Raymond Hettinger

From: <[EMAIL PROTECTED]>
I think it would benefit everyone if this discussion would end up with 
some patches to the library documentation that documented the semantics 
of super() more completely in the reference documentation and the 
"multiple inheritance" area of the tutorial, so that when people *do* 
run in to difficulties there is a very clear, central explanation of 
what it's supposed to do.


Am working on a doc patch, will post this weekend.


Raymond
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Things to Know About Super

2008-08-29 Thread Michele Simionato
On Fri, Aug 29, 2008 at 8:33 PM, Casey Duncan <[EMAIL PROTECTED]> wrote:
> - There are good alternatives to multiple inheritance for many cases, but
> there are cases where multiple inheritance is arguably best.

Maybe, but I am still biased in the opposite direction ;)

>Traits are a
> possible alternative that deserve further study. I think that study would be
> greatly aided by a 3rd-party library implementing traits for Python. If
> traits are to gain any traction or ever be considered for inclusion into the
> language such a library would need to exist first and demonstrate its
> utility.

I wrote a trait library which I plan to release soon or later. However
it is intended as a proof of concept, not as a candidate for inclusion
in the standard library. As of now, I don't think we should have
a different way of doing mixins in the standard library. There should
be only one obvious way and the obvious way in current Python
is multiple inheritance as it is now. The proof of concept is
important for educational purposes, to open the mind to
alternatives, to give inspiration to the creators of new languages:
it is not intended to add complication (whenever small) to
current Python. Having said that, maybe once I release the
library people will start using it in production and will ask
for inclusion for the standard library, but this is not my goal
now. This happened for my decorator module years ago:
when I wrote it I did not expect people to use it,  I saw it
as a temporary hack until we got a better support for
fiddling with function signatures in the standard library.
Nevertheless now a lot of people are using it and I am
not even sure it is a good thing (I have seen many decorator
abuses out there). This the strange thing that happens when
you release a library: you will never now what people will
end up using it for ;)

  Michele Simionato
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com