Repository navigation
RFE: uuid.UUID(bytes=...): support bytes-like types, not only bytes #73915
Description
Activity
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))
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or errorextension-modulesC modules in the Modules dirC modules in the Modules dir
on Mar 5, 2017 - 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 - addedtype-featureA feature request or enhancementA feature request or enhancementand removedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Sep 28, 2017 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?
Ah, Victor already have created a PR!
- addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory3.7 (EOL)end of lifeend of lifeand removedextension-modulesC modules in the Modules dirC modules in the Modules dir
on Sep 28, 2017 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.
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.
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?
I have tested, this doesn't affect performance.
Serhiy: "I have tested, this doesn't affect performance."
Oh, thank you for testing that :-)
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_lewhere we need slicing. We could have a generic way to transformbytes_lewithout slicing and only assumingmemoryviewsupport, but I don't think it's worth the change. Acceptingbytes_leis 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_leandbytesMUST bebytesinstances (and not anything else), I will close this issue.I agree to close the PR and leave the code as it is.
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:
bugs.python.org fields: