classification
Title: RFE: uuid.UUID(bytes=...): support bytes-like types, not only bytes
Type: enhancement Stage: patch review
Components: Library (Lib) Versions: Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: barry, jnwatson, serhiy.storchaka, vstinner
Priority: normal Keywords: patch

Created on 2017-03-05 19:59 by jnwatson, last changed 2017-09-28 20:43 by vstinner.

Pull Requests
URL Status Linked Edit
PR 3801 closed vstinner, 2017-09-28 14:21
Messages (8)
msg289045 - (view) Author: Nic Watson (jnwatson) Date: 2017-03-05 19:59
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))
msg303242 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-09-28 14:29
I agree. In any case assert is a bad way of checking argument types. It was 
added in 65b6a80f19736d6313d5eb896d6b2fb6bbf65a03 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?
msg303246 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-09-28 14:37
Ah, Victor already have created a PR!
msg303248 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-09-28 14:41
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.
msg303250 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-09-28 14:51
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.
msg303277 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-09-28 20:21
> 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?
msg303278 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-09-28 20:32
I have tested, this doesn't affect performance.
msg303279 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-09-28 20:43
Serhiy: "I have tested, this doesn't affect performance."

Oh, thank you for testing that :-)
History
Date User Action Args
2017-09-28 20:43:09vstinnersetmessages: + msg303279
2017-09-28 20:32:49serhiy.storchakasetmessages: + msg303278
2017-09-28 20:21:18vstinnersetmessages: + msg303277
2017-09-28 14:51:47serhiy.storchakasetmessages: + msg303250
2017-09-28 14:41:30vstinnersetnosy: + vstinner
messages: + msg303248
2017-09-28 14:37:59serhiy.storchakasetmessages: + msg303246
components: + Library (Lib), - Extension Modules
versions: + Python 3.7, - Python 3.6
2017-09-28 14:29:11serhiy.storchakasetmessages: + msg303242
2017-09-28 14:21:57vstinnersetkeywords: + patch
stage: patch review
pull_requests: + pull_request3787
2017-09-28 13:43:07vstinnersetnosy: + serhiy.storchaka

type: behavior -> enhancement
title: UUID bytes constructor has too-tight an assertion -> RFE: uuid.UUID(bytes=...): support bytes-like types, not only bytes
2017-03-05 22:15:13barrysetnosy: + barry
2017-03-05 19:59:58jnwatsoncreate