On 3/12/2011 8:59 AM, Nick Coghlan wrote:
On Sat, Mar 12, 2011 at 8:33 AM, Laura Creighton<l...@openend.se>  wrote:
For those of you not at the Language Summit at PyCON the day before yesterday,
there was talk of identifying non-portable behaviour, such as relying on
CPython's reference counting garbage collector to close files for you as
soon as they become unreachable.  And then warning about them.

We have a real live user who has a large code base that relies on
the CPython behaviour that an object's __radd__ method will take precedence
over a list's inplace add behaviour.

The thread with the whole gory details begins here:
http://codespeak.net/pipermail/pypy-dev/2011q1/006958.html

My inclination is to declare code that relies on this as broken, rather
than patch every wretched container type in PyPy.  Can this become
blessed as a 'you shouldn't have done this'?

Given that the meat of the difference in semantics lies in the
CPython-specific distinction between nb_add and sq_concat, I'm
inclined to agree with you.

Me too. Consider filing a tracker issue with the += and * examples from the link above as new unit tests.

I'm actually tempted to call the current CPython semantics flatout
*wrong*. When a given operation has multiple C level slots, shouldn't
we be checking all the LHS slots before checking any of the RHS slots?

Yes.

There's nothing in the language spec that I'm aware of that justifies
us doing otherwise.

The current CPython behavior strikes me as a buggy optimization. If class 'list' were written in Python, it would have an '__iadd__' method that would implement +=. No question. I gather that this is what PyPy (correctly) does. The CPython implementation makes a (false) distinction between numeric + and * and sequence + and * that does not exist in Python the language. The reference manual only lists __add__, and not __nadd__ and __sadd__ as separate special methods. The fact that CPython has both (with different names) should *not* leak into Python semantics and behavior.

(obviously, history now means that changing our behaviour would
require a deprecation period)

I disagree. Behavior that contradicts intent and doc is a bug and should be fixed. Otherwise, the doc should be changed to say that for C-implmented objects, the precedence between forward and reverse methods depends on the category of object. This would mean that subclasses of builtins *should* act differently from their parent, as they can now. Example derived from the link:

# 3.2
class C(object):
    def __iter__(self):
        yield 'yes!'
    def __radd__(self, other):
        other.append('bug!')
        return other

class L(list):
    def __iadd__(self, other):
        list.__iadd__(self,other)
        return self

z1,z2 = [], L()
z1 += C()
z2 += C()
print(z1, z2)

>>>
['bug!'] ['yes!']

Such a change would make the definition of the language more C-dependent, which is what Laura is rightly complaining about, rather than less. It would also work against efforts to make Python and C versions of stdlib modules work the same and pass the same tests.

--
Terry Jan Reedy

_______________________________________________
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

Reply via email to