Skip to content

RFE: uuid.UUID(bytes=...): support bytes-like types, not only bytes #73915

Description

@jnwatson
mannequin
BPO 29729
Nosy @warsaw, @vstinner, @serhiy-storchaka, @jnwatson
PRs
  • bpo-29729: uuid.UUID now accepts bytes-like object #3801
  • 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 = None
    created_at = <Date 2017-03-05.19:59:58.391>
    labels = ['3.7', 'type-feature', 'library']
    title = 'RFE: uuid.UUID(bytes=...): support bytes-like types, not only bytes'
    updated_at = <Date 2017-09-28.20:43:09.315>
    user = 'https://github.com/jnwatson'

    bugs.python.org fields:

    activity = <Date 2017-09-28.20:43:09.315>
    actor = 'vstinner'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2017-03-05.19:59:58.391>
    creator = 'jnwatson'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 29729
    keywords = ['patch']
    message_count = 8.0
    messages = ['289045', '303242', '303246', '303248', '303250', '303277', '303278', '303279']
    nosy_count = 4.0
    nosy_names = ['barry', 'vstinner', 'serhiy.storchaka', 'jnwatson']
    pr_nums = ['3801']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue29729'
    versions = ['Python 3.7']

    Activity

    1. jnwatson commented on Mar 5, 2017

      jnwatsonmannequin
      MannequinAuthor

      The assertion:

      File "/usr/lib/python3.6/uuid.py", line 150, in __init__
      assert isinstance(bytes, bytes_), repr(bytes)

      is too specific (and IMHO, unpythonic). One may want to pass a bytearray or a memoryview. See int.from_bytes for an example that takes "bytes" but accepts anything that acts like a bytes.

      A simple solution may be to delete the assertion (it worked for me).

      Example code:

      import uuid
      
      b = uuid.uuid1().bytes
      ba = bytearray(b)
      print(uuid.UUID(bytes=b))
      
      # another API that works similarly, accepts a bytearray
      print(int.from_bytes(ba, byteorder='big'))
      
      # fails on assertion
      print(uuid.UUID(bytes=ba))
    2. changed the title [-]UUID bytes constructor has too-tight an assertion[/-] [+]RFE: uuid.UUID(bytes=...): support bytes-like types, not only bytes[/+] on Sep 28, 2017
    3. added
      type-featureA feature request or enhancement
      and removed
      type-bugAn unexpected behavior, bug, or error
      on Sep 28, 2017
    4. serhiy-storchaka commented on Sep 28, 2017

      @serhiy-storchaka
      Member

      I agree. In any case assert is a bad way of checking argument types. It was
      added in 65b6a80 as a part of migration to
      Python 3. I guess for debugging purposes. Now it isn't needed,
      int.from_bytes() checks whether the type is appropriate.

      Do you want to create a pull request Nic?

    5. serhiy-storchaka commented on Sep 28, 2017

      @serhiy-storchaka
      Member

      Ah, Victor already have created a PR!

    6. added
      stdlibStandard Library Python modules in the Lib/ directory
      and removed on Sep 28, 2017
    7. vstinner commented on Sep 28, 2017

      @vstinner
      Member

      Serhiy: is it safe to accept any memoryview? Or should we call explicitly .cast('B') on memory views to prevent bad surprises?

      The asyncio module doesn't do anything special in sock_sendall(). "data" is passed directly to socket.send(), unchanged.

      So maybe it's just fine to not do anything special.

    8. serhiy-storchaka commented on Sep 28, 2017

      @serhiy-storchaka
      Member

      The code doesn't work nice with general objects supporting the buffer protocol. The length check suppose that the value has a length, and it is the size in bytes. The code for bytes_le suppose that the value supports slicing and concatenating results of the slicing. And all this code is made as fast as possible. Additional checks and conversions will slowdown it.

    9. vstinner commented on Sep 28, 2017

      @vstinner
      Member

      The code doesn't work nice with general objects supporting the buffer protocol. The length check suppose that the value has a length, and it is the size in bytes. The code for bytes_le suppose that the value supports slicing and concatenating results of the slicing. And all this code is made as fast as possible. Additional checks and conversions will slowdown it.

      I enhanced my PR to also accept memoryview and bytearray in bytes_le. I don't think that performance matters so much here. First we need correctness, accept any bytes-like objects, no?

    10. serhiy-storchaka commented on Sep 28, 2017

      @serhiy-storchaka
      Member

      I have tested, this doesn't affect performance.

    11. vstinner commented on Sep 28, 2017

      @vstinner
      Member

      Serhiy: "I have tested, this doesn't affect performance."

      Oh, thank you for testing that :-)

    12. transferred this issue fromon Apr 10, 2022
    13. picnixz commented on Sep 17, 2025

      @picnixz
      Member

      Considering the history of the PR and how hard it was to ensure that we accept a bytes-like object, I would prefer rejecting this feature altogether. It's common to create a UUID from a bytes (e.g., if the latter comes from a process output or a database query), but I don't think it's common enough to construct a UUID from a memoryview, or a bytearray. If this is a concern, I would advise wrapping it in bytes(...) call.

      AFAICT, most of the issue stems from bytes_le where we need slicing. We could have a generic way to transform bytes_le without slicing and only assuming memoryview support, but I don't think it's worth the change. Accepting bytes_le is only internally used to get the node value of a UUIDv1 created on Windows for subsequent calls and it's only used once.

      Unless we want to change the AssertionError into a TypeError (which would make sense here) or explicitly document that values passed via bytes_le and bytes MUST be bytes instances (and not anything else), I will close this issue.

    14. vstinner commented on Sep 18, 2025

      @vstinner
      Member

      I agree to close the PR and leave the code as it is.

    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

      stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions