Skip to content

bytes() and bytearray() should have the default values for errors for string sources #137100

Description

@hyperkai

bytes() and bytearray() don't show the default values for source, encoding and errors as shown below:

class bytearray(source=b'')
class bytearray(source, encoding)
class bytearray(source, encoding, errors)

class bytes(source=b'')
class bytes(source, encoding)
class bytes(source, encoding, errors)

So, they should have the default values as shown below:

class bytearray(source=b'')
class bytearray(source, encoding='utf-8')
class bytearray(source, encoding='utf-8', errors='strict')

class bytes(source=b'')
class bytes(source, encoding='utf-8')
class bytes(source, encoding='utf-8', errors='strict')

Activity

  1. ZeroIntensity commented on Jul 25, 2025

    @ZeroIntensity
    Member

    I don't think we need the three separate lines anymore. It should suffice to just have one with all the defaults. PR welcome!

  2. skirpichev commented on Jul 25, 2025

    @skirpichev
    Member

    class bytes(source=b'') # (1)
    class bytes(source=b'', encoding='utf-8') # (2)
    class bytes(source=b'', encoding='utf-8', errors='strict')

    No. That will be just wrong. Same for bytearray.

    You can omit encoding for integer, iterable of integers or bytes. For strings - you must provide encoding, there is no default.

  3. ZeroIntensity commented on Jul 25, 2025

    @ZeroIntensity
    Member

    I meant by just documenting encoding=None or something like that.

  4. skirpichev commented on Jul 25, 2025

    @skirpichev
    Member

    I meant by just documenting encoding=None or something like that.

    But there is no such default.

    This is an example of a callable with multiple signatures. This function accept up to 3 arguments:

    1. 1-arg form, in source: bytes, integer or iterable of integers.
    2. 2-arg form: str in source + encoding
    3. 3-arg form: str in source + encoding + errors

    You can't specify string + errors - you must also set encoding in this case.

    Unless I miss something, we can't simplify this.

  5. terryjreedy commented on Jul 25, 2025

    @terryjreedy
    Member

    Kai, I fixed the duplication of bytearray that omitted bytes.

    One must omit both encoding and errors when source is not a string, or one gets "TypeError: encoding(errors) without a string argument".

    There are 2, but I would say, only 2 signatures, one for non-string sources (defaulting to b'') and one for string sources, which requires encoding and allows errors Since errors has a de facto default of strict for string sources, whence str.encode is called, I think we can simplify and make the situation clearer by combining the 2 and 3 arg lines into bytes(source, encoding, errors=strict). It is irrelevant to the user whether bytes calls str.encode with 'strict' or not and I don't think this implementation detail should be part of the definition of bytes/bytearray. (Having separate 2 and 3 arg lines implies that bytes makes separate 2 or 3 arg calls to encode.)

    Bytes has no inspect.signature, which is to say, inspect.signature(bytes) raises ValueError. Its signature in the docstring, as formatted by 'help', is:

    Help on class bytes in module builtins:
    
    class bytes(object)
     |  bytes(iterable_of_ints) -> bytes
     |  bytes(string, encoding[, errors]) -> bytes
     |  bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
     |  bytes(int) -> bytes object of size given by the parameter initialized with null bytes
     |  bytes() -> empty bytes object
    

    The entry for bytes(string, ...) should be either first, which matched the doc entry order, or put last and bytes() put first. In either case, separate it from the others.

    I think this separation should be increased in the entry text. Something like

    If source is a string (the second signature above),
    ... .
    If source is not a string,
    *
    *
    *

    • If omitted, it defaults to b'' and an empty bytes of length 0 is created.

    Currently, the call details are in the bytearray entry and the bytes entry refers to the former. I personally would put the details in the bytes entry and reference that in the bytearray entry. But that might be a separate issue.

  6. changed the title [-]`bytes()` and `bytearray()` should have the default values for `source`, `encoding` and `errors`[/-] [+]`bytes()` and `bytearray()` should have the default values for `errors` for string sources[/+] on Jul 25, 2025
  7. terryjreedy commented on Jul 25, 2025

    @terryjreedy
    Member

    I might add to the entry something like "The two signatures above correspond to non-string and string sources respectively". And then discuss them separately in whichever order.

  8. changed the title [-]`bytes()` and `bytearray()` should have the default values for `errors` for string sources[/-] [+]`bytes()` and `bytearray()` should have the default values for `source`, `encoding` and `errors`[/+] on Jul 26, 2025
  9. changed the title [-]`bytes()` and `bytearray()` should have the default values for `source`, `encoding` and `errors`[/-] [+]`bytes()` and `bytearray()` should have the default values for `errors` for string sources[/+] on Jul 26, 2025
  10. skirpichev commented on Jul 26, 2025

    @skirpichev
    Member

    @hyperkai, could you, please explain change in the issue title?

  11. serhiy-storchaka commented on Aug 25, 2025

    @serhiy-storchaka
    Member

    It was addressed in #137610. Now it is documented as

    .. class:: bytes(source=b'')
               bytes(source, encoding, errors='strict')

    It was discussed to use three signature (separate one for the case of no arguments), but for now two signature is enough.

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

    docsDocumentation in the Doc dir

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions