You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Make str and bytes error messages on concatenation conform with other sequences #73302
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2018-02-19.12:11:02.111>created_at=<Date2016-12-30.18:56:51.731>labels= ['interpreter-core', 'type-feature', '3.7']
title='Make str and bytes error messages on concatenation conform with other sequences'updated_at=<Date2018-02-19.12:11:02.110>user='https://github.com/DimitrisJim'
Specifically, bytes (always, from what I could find) had this error message:
>>> b'' + ''
TypeError: can't concat bytes to str
whilestr, afterachangeinissue26057, wasmadeto:
>>> '' + b''
TypeError: must be str, not bytes
from the previous form of "TypeError: Can't convert 'bytes' object to str implicitly".
I think these could be changed to conform with what the other sequences generate and fall in line with the error messages produced for other operations.
Specifically changing them to:
>>> b'' + ''
TypeError: can only concatenate bytes (not 'str') to bytes
and similarly for str.
If this idea makes sense, I can attach a patch that addresses it.
Old error message is misleading. It implied that there are objects that can be converted to str implicitly. This was true in Python 2, but is false in Python 3.
New error message conforms with TypeError messages produced by PyArg_Parse*(). It is the same in a number of str methods. It doesn't conform with the error messages for other produced by concatenating other types. But different messages are generated for different types:
>>> b''+1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat bytes to int
>>> a =bytearray(); a +=1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat int to bytearray
>>> [] +1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "int") to list
>>> a = []; a +=1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> import array; array.array('b') + []
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only append array (not "list") to array
>>> import array; a = array.array('b'); a += []
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only extend array with array (not "list")
>>> import operator; operator.concat(1, '')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object can't be concatenated
I think it would be better to unify them all.
I'm not sure that this change can be considered as a bug fix rather than an enhancement. Leave this on 3.6 release manager.
Should that message be the one predominantly used for sequences, i.e:
TypeError: can only concatenate class1 (not "class2") to class1
or should another one be used like "Unsupported operand type(s) for op: 'class1' and 'class2'?
The first is problematic with cases like += where an iterable is accepted, the second seems better to me at least.
As for operator.concat, any reason why the check is made beforehand to see if the first argument has a __getitem__ method? Couldn't that just be removed allowing the exception from concat(1, '') to just propagate to the caller?
Different cases accept different types. Not always we can say that only one specific type is accepted.
"list +" accepts only lists, "list +=" is a syntax sugar for list.extend and accepts any iterables. "bytes +" and "bytearray +=" accept any objects that support the buffer protocol. "array +" and "array +=" accept only arrays.
Changing semantic is out of the scope of this issue. I think there are reasons for current behavior.
As for operator.concat, any reason why the check is made beforehand to see if the first argument has a __getitem__ method?
Concatenation is an operation of sequence (+ could be used both for concatenation and addition), so you have to check __getitem__ to make sure it's a sequence.
Couldn't that just be removed allowing the exception from concat(1, '') to just propagate to the caller?
If removed, concat(1, '') could propagate exceptions but not concat(1, 1).
By default, error message wording changes are 'enhancements' that wait for the next x.y.0 release unless the current wording is positively wrong'. This is different from doc changes because there are tests depending on error messages. 'Inconsistent' or 'awkward' is not the same as 'wrong'.
I do agree that the clipped "must be str, not bytes' is awkward. What (which) is it that must be str? A fleshed out and positive "can only concatenate str (not bytes) to str." would be clearer and educate users better.
As Serhiy said, the exact equivalent cannot be said for bytes.
However "Can only concatenate bytes, bytearray, or memoryview (not x) to bytes." would be good if this is in fact complete. I need to be educated on this ;-) I was not sure about memoryview until I tried it.
You can concatenate any object supporting the buffer protocol to bytes and bytearray.
Current error message for bytes looks awkward too, because it says "bytes to othertype" instead of "othertype to bytes".
DimitrisJim commented on Jan 11, 2017
DimitrisJimmannequin
MannequinAuthor
More actions
As I currently see this:
The error message for str can be changed to the one used for other sequences 'can only concatenate str (not "type") to str'
The error message for arrays can be changed to use concatenate instead of append, too.
For bytes I see a conundrum, on one hand it can be changed to mention the buffer protocol which might confuse new users more than it helps them or, it can try and mention the objects that currently conform to it which might be exhaustive and long.
I'm removing myself as assignee as this doesn't seem to need a 3.6 RM decision at this point. If necessary, we can discuss a 3.6 backport after the issue has been resolved for 3.7.
PR 709 fixes the order of types for concatenating bytes and and bytearray. b''+0 will raise "can't concat str to bytes" rather than "can't concat bytes to str".
PR 710 makes error message for str concatenation more informative and similar to error messages for list, tuple, deque, array. '' + b'' will raise "can only concatenate str (not "bytes") to str" rather than "must be str, not bytes".
I don't know why statuses was not updated automatically. Updated them manually.
Ivan in the comment on GitHub suggested to use "concatenate" instead of "concat" in "can't concat <type> to bytes". Maybe make it more similar to messages for list, tuple, deque, array? "can only concatenate objects supporting the buffer protocol (not "<type>") to bytes"?
New changeset 2c5b2c3 by Serhiy Storchaka in branch '3.5': bpo-29116: Fix error messages for concatenating bytes and bytearray with unsupported type. (#709) (#724) 2c5b2c3
New changeset 3d258b1 by Serhiy Storchaka in branch '3.6': bpo-29116: Fix error messages for concatenating bytes and bytearray with unsupported type. (#709) (#723) 3d258b1
New changeset 6b5a9ec by Serhiy Storchaka in branch 'master': bpo-29116: Fix error messages for concatenating bytes and bytearray with unsupported type. (#709) 6b5a9ec
Activity
DimitrisJim commentedon Dec 30, 2016
Specifically, bytes (always, from what I could find) had this error message:
>>> b'' + '' TypeError: can't concat bytes to str>>> '' + b'' TypeError: must be str, not bytesfrom the previous form of "TypeError: Can't convert 'bytes' object to str implicitly".
I think these could be changed to conform with what the other sequences generate and fall in line with the error messages produced for other operations.
Specifically changing them to:
>>> b'' + '' TypeError: can only concatenate bytes (not 'str') to bytesand similarly for str.
If this idea makes sense, I can attach a patch that addresses it.
serhiy-storchaka commentedon Dec 30, 2016
Old error message is misleading. It implied that there are objects that can be converted to str implicitly. This was true in Python 2, but is false in Python 3.
New error message conforms with TypeError messages produced by PyArg_Parse*(). It is the same in a number of str methods. It doesn't conform with the error messages for other produced by concatenating other types. But different messages are generated for different types:
I think it would be better to unify them all.
I'm not sure that this change can be considered as a bug fix rather than an enhancement. Leave this on 3.6 release manager.
DimitrisJim commentedon Dec 30, 2016
Should that message be the one predominantly used for sequences, i.e:
TypeError: can only concatenate class1 (not "class2") to class1
or should another one be used like "Unsupported operand type(s) for op: 'class1' and 'class2'?
The first is problematic with cases like
+=where an iterable is accepted, the second seems better to me at least.As for
operator.concat, any reason why the check is made beforehand to see if the first argument has a__getitem__method? Couldn't that just be removed allowing the exception fromconcat(1, '')to just propagate to the caller?serhiy-storchaka commentedon Dec 31, 2016
Different cases accept different types. Not always we can say that only one specific type is accepted.
"list +" accepts only lists, "list +=" is a syntax sugar for list.extend and accepts any iterables. "bytes +" and "bytearray +=" accept any objects that support the buffer protocol. "array +" and "array +=" accept only arrays.
Changing semantic is out of the scope of this issue. I think there are reasons for current behavior.
serhiy-storchaka commentedon Dec 31, 2016
Originally this issue was raised on StackOverflow:
http://stackoverflow.com/questions/41388606/python-3-6-vs-3-5-typeerror-message-on-string-concatenation
zhangyangyu commentedon Jan 3, 2017
Concatenation is an operation of sequence (+ could be used both for concatenation and addition), so you have to check __getitem__ to make sure it's a sequence.
If removed,
concat(1, '')could propagate exceptions but notconcat(1, 1).terryjreedy commentedon Jan 6, 2017
By default, error message wording changes are 'enhancements' that wait for the next x.y.0 release unless the current wording is positively wrong'. This is different from doc changes because there are tests depending on error messages. 'Inconsistent' or 'awkward' is not the same as 'wrong'.
I do agree that the clipped "must be str, not bytes' is awkward. What (which) is it that must be str? A fleshed out and positive "can only concatenate str (not bytes) to str." would be clearer and educate users better.
As Serhiy said, the exact equivalent cannot be said for bytes.
However "Can only concatenate bytes, bytearray, or memoryview (not x) to bytes." would be good if this is in fact complete. I need to be educated on this ;-) I was not sure about memoryview until I tried it.
serhiy-storchaka commentedon Jan 6, 2017
You can concatenate any object supporting the buffer protocol to bytes and bytearray.
Current error message for bytes looks awkward too, because it says "bytes to othertype" instead of "othertype to bytes".
DimitrisJim commentedon Jan 11, 2017
As I currently see this:
The error message for str can be changed to the one used for other sequences 'can only concatenate str (not "type") to str'
The error message for arrays can be changed to use concatenate instead of append, too.
For bytes I see a conundrum, on one hand it can be changed to mention the buffer protocol which might confuse new users more than it helps them or, it can try and mention the objects that currently conform to it which might be exhaustive and long.
ned-deily commentedon Mar 3, 2017
I'm removing myself as assignee as this doesn't seem to need a 3.6 RM decision at this point. If necessary, we can discuss a 3.6 backport after the issue has been resolved for 3.7.
serhiy-storchaka commentedon Mar 18, 2017
PR 709 fixes the order of types for concatenating bytes and and bytearray. b''+0 will raise "can't concat str to bytes" rather than "can't concat bytes to str".
PR 710 makes error message for str concatenation more informative and similar to error messages for list, tuple, deque, array. '' + b'' will raise "can only concatenate str (not "bytes") to str" rather than "must be str, not bytes".
ilevkivskyi commentedon Mar 19, 2017
Something is strange: PRs 709, 723, 724 are shown as open in the "Pull Requests" section on this page. However, all four PRs are already merged.
Are other see the same? Shouldn't status be automatically updated?
serhiy-storchaka commentedon Mar 20, 2017
I don't know why statuses was not updated automatically. Updated them manually.
Ivan in the comment on GitHub suggested to use "concatenate" instead of "concat" in "can't concat <type> to bytes". Maybe make it more similar to messages for list, tuple, deque, array? "can only concatenate objects supporting the buffer protocol (not "<type>") to bytes"?
serhiy-storchaka commentedon Mar 24, 2017
New changeset 2c5b2c3 by Serhiy Storchaka in branch '3.5':
bpo-29116: Fix error messages for concatenating bytes and bytearray with unsupported type. (#709) (#724)
2c5b2c3
serhiy-storchaka commentedon Mar 24, 2017
New changeset 3d258b1 by Serhiy Storchaka in branch '3.6':
bpo-29116: Fix error messages for concatenating bytes and bytearray with unsupported type. (#709) (#723)
3d258b1
serhiy-storchaka commentedon Mar 24, 2017
New changeset 6b5a9ec by Serhiy Storchaka in branch 'master':
bpo-29116: Fix error messages for concatenating bytes and bytearray with unsupported type. (#709)
6b5a9ec
serhiy-storchaka commentedon Mar 24, 2017
New changeset 004e03f by Serhiy Storchaka in branch 'master':
bpo-29116: Improve error message for concatenating str with non-str. (#710)
004e03f
rhettinger commentedon Oct 25, 2017
In the future, I don't think this sort of thing should be backported. It isn't a bug, rather, it is a "thing x doesn't exactly look like thing y".