[Python-Dev] About raising NotPortableWarning for CPython specific code
Terry Reedy
tjreedy at udel.edu
Sat Mar 12 20:52:41 CET 2011
On 3/12/2011 8:59 AM, Nick Coghlan wrote:
> On Sat, Mar 12, 2011 at 8:33 AM, Laura Creighton<lac at 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
More information about the Python-Dev
mailing list