Skip to content

Make str and bytes error messages on concatenation conform with other sequences #73302

Closed

Description

@DimitrisJim
BPO 29116
Nosy @rhettinger, @terryjreedy, @ned-deily, @serhiy-storchaka, @ilevkivskyi, @zhangyangyu, @DimitrisJim
PRs
  • bpo-29116: Fix error messages for concatenating bytes and bytearray w… #709
  • bpo-29116: Improve error message for concatenating str with non-str. #710
  • bpo-29116: Fix error messages for concatenating bytes and bytearray w… #723
  • bpo-29116: Fix error messages for concatenating bytes and bytearray w… #724
  • 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 = None
    closed_at = <Date 2018-02-19.12:11:02.111>
    created_at = <Date 2016-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 = <Date 2018-02-19.12:11:02.110>
    user = 'https://github.com/DimitrisJim'

    bugs.python.org fields:

    activity = <Date 2018-02-19.12:11:02.110>
    actor = 'serhiy.storchaka'
    assignee = 'none'
    closed = True
    closed_date = <Date 2018-02-19.12:11:02.111>
    closer = 'serhiy.storchaka'
    components = ['Interpreter Core']
    creation = <Date 2016-12-30.18:56:51.731>
    creator = 'Jim Fasarakis-Hilliard'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 29116
    keywords = ['patch']
    message_count = 18.0
    messages = ['284340', '284341', '284348', '284370', '284372', '284545', '284855', '284861', '285213', '288922', '289803', '289866', '289877', '290151', '290152', '290158', '290159', '304958']
    nosy_count = 7.0
    nosy_names = ['rhettinger', 'terry.reedy', 'ned.deily', 'serhiy.storchaka', 'levkivskyi', 'xiang.zhang', 'Jim Fasarakis-Hilliard']
    pr_nums = ['709', '710', '723', '724']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue29116'
    versions = ['Python 3.7']

    Activity

    1. DimitrisJim commented on Dec 30, 2016

      DimitrisJimmannequin
      MannequinAuthor

      Specifically, bytes (always, from what I could find) had this error message:

          >>> b'' + ''
          TypeError: can't concat bytes to str
      while str, after a change in issue26057, was made to:
          >>> '' + 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.

    2. added
      type-bugAn unexpected behavior, bug, or error
      interpreter-core(Objects, Python, Grammar, and Parser dirs)
      on Dec 30, 2016
    3. serhiy-storchaka commented on Dec 30, 2016

      @serhiy-storchaka
      Member

      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.

    4. DimitrisJim commented on Dec 30, 2016

      DimitrisJimmannequin
      MannequinAuthor

      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?

    5. serhiy-storchaka commented on Dec 31, 2016

      @serhiy-storchaka
      Member

      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.

    6. serhiy-storchaka commented on Dec 31, 2016

      @serhiy-storchaka
      Member
    7. zhangyangyu commented on Jan 3, 2017

      @zhangyangyu
      Member

      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).

    8. terryjreedy commented on Jan 6, 2017

      @terryjreedy
      Member

      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.

      >>> b'a' + bytearray(b'b')
      b'ab'
      >>> b'a' + memoryview(b'b')
      b'ab'

      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.

    9. added
      type-featureA feature request or enhancement
      and removed
      type-bugAn unexpected behavior, bug, or error
      on Jan 6, 2017
    10. serhiy-storchaka commented on Jan 6, 2017

      @serhiy-storchaka
      Member

      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".

    11. DimitrisJim commented on Jan 11, 2017

      DimitrisJimmannequin
      MannequinAuthor

      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.

    12. ned-deily commented on Mar 3, 2017

      @ned-deily
      Member

      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.

    13. removed their assignment
      on Mar 3, 2017
    14. serhiy-storchaka commented on Mar 18, 2017

      @serhiy-storchaka
      Member

      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".

    15. ilevkivskyi commented on Mar 19, 2017

      @ilevkivskyi
      Member

      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?

    16. serhiy-storchaka commented on Mar 20, 2017

      @serhiy-storchaka
      Member

      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"?

    17. serhiy-storchaka commented on Mar 24, 2017

      @serhiy-storchaka
      Member

      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

    18. serhiy-storchaka commented on Mar 24, 2017

      @serhiy-storchaka
      Member

      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

    19. serhiy-storchaka commented on Mar 24, 2017

      @serhiy-storchaka
      Member

      New changeset 6b5a9ec by Serhiy Storchaka in branch 'master':
      bpo-29116: Fix error messages for concatenating bytes and bytearray with unsupported type. (#709)
      6b5a9ec

    20. serhiy-storchaka commented on Mar 24, 2017

      @serhiy-storchaka
      Member

      New changeset 004e03f by Serhiy Storchaka in branch 'master':
      bpo-29116: Improve error message for concatenating str with non-str. (#710)
      004e03f

    21. rhettinger commented on Oct 25, 2017

      @rhettinger
      Contributor

      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".

    22. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.7 (EOL)end of lifeinterpreter-core(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancement

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions