New submission from Nick Coghlan <ncogh...@gmail.com>:

In a recent python-ideas discussion of the differences between concatenation 
and augmented assignment on lists, I pointed out the general guiding principle 
behind Python's binary operation semantics was that the type of a binary 
operation should not depend on the order of the operands. That is "X op Y" and 
"Y op X" should either consistently create results of the same type ("1 + 1.1", 
"1.1 + 1") or else throw an exception ("[] + ()", "() + []").

This principle is why list concatenation normally only works with other lists, 
but will accept arbitrary iterables for augmented assignment. collections.deque 
exhibits similar behaviour (i.e. strict on the binary operation, permissive on 
augmented assignment).

However, bytes and bytearray don't follow this principle - they accept anything 
that implements the buffer interface even in the binary operation, leading to 
the following asymmetries:

>>> b'' + bytearray()
b''
>>> b'' + memoryview(b'')
b''
>>> bytearray() + b''
bytearray(b'')
>>> bytearray() + memoryview(b'')
bytearray(b'')
>>> memoryview(b'') + b''
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'memoryview' and 'bytes'
>>> memoryview(b'') + bytearray(b'')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'memoryview' and 'bytearray'

Now, the latter two cases are due to a known problem where returning 
NotImplemented from sq_concat or sq_repeat doesn't work properly (so none of 
the relevant method implementations in the stdlib even try), but the bytes and 
bytearray interaction is exactly the kind of type asymmetry the operand order 
independence guideline is intended to prevent.

My question is - do we care enough to try to change this? If we do, then it's 
necessary to decide on more appropriate semantics:

1. The "list" solution, permitting only the same type in binary operations 
(high risk of breaking quite a lot of code)
2. Don't allow arbitrary buffers, but do allow bytes/bytearray interoperability
  2a. always return bytes from mixed operations
  2b. always return bytearray from mixed operations
  2c. return the type of the first operand (ala set.__or__)

Or just accept that this really is more of a guideline than a rule and adjust 
the documentation accordingly.

----------
components: Interpreter Core
messages: 146669
nosy: ncoghlan
priority: normal
severity: normal
status: open
title: Result type depends on order of operands for bytes and bytearray
type: behavior
versions: Python 3.3

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue13298>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to