Skip to content

Add simple UUID module with uuid4()#1137

Open
dpgeorge wants to merge 5 commits into
micropython:masterfrom
dpgeorge:add-uuid
Open

Add simple UUID module with uuid4()#1137
dpgeorge wants to merge 5 commits into
micropython:masterfrom
dpgeorge:add-uuid

Conversation

@dpgeorge

Copy link
Copy Markdown
Member

Summary

This PR pulls in @andrewleech 's minimal UUID implementation from https://github.com/pfalcon/pycopy-lib (originally submitted here as #312, #313 long ago).

Then I made a few updates to it:

  • add manifest.py
  • convert test to use unittest and run it under CI
  • use bytes.hex() instead of binascii.hexlify().decode()
  • run ruff format

Testing

Test added that runs under CI.

Trade-offs and Alternatives

This adds a minimal implementation of uuid.uuid4() which is arguably the more important of the uuidX functions.

Alternatives:

Generative AI

Not used.

andrewleech and others added 3 commits July 11, 2026 15:17
Includes unit test.

Signed-off-by: Damien George <damien@micropython.org>
And run it as part of CI.

Signed-off-by: Damien George <damien@micropython.org>
Using `bytes.hex()` eliminates an import, and eliminates the call to
`.decode()` to convert it to a str.

Also run ruff format.

Signed-off-by: Damien George <damien@micropython.org>

@andrewleech andrewleech left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great thanks.

class UUID:
def __init__(self, bytes):
if len(bytes) != 16:
raise ValueError("bytes arg must be 16 bytes long")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to test if cpython gave the save error here but it gave a much messier exception. Possibly not worth worrying about, this should be user friendly enough.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, indeed CPython does give a confusing error.

@dpgeorge

Copy link
Copy Markdown
Member Author

Thanks for the review!

@dpgeorge dpgeorge mentioned this pull request Jul 14, 2026
3 tasks
Comment thread python-stdlib/uuid/test_uuid.py Outdated
Comment on lines +6 to +10
def test_unique(self):
u1 = uuid.uuid4()
u2 = uuid.uuid4()
self.assertNotEqual(u1.hex, u2.hex)
self.assertNotEqual(str(u1), str(u2))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there tests to ensure that, for a given port, os.urandom provides unique results? I could only find tests/extmod/os_urandom.py.

Perhaps we should then either test urandom more thoroughly or test uuid uniqueness here more thoroughly? For comparison, CPython generates 1000 UUIDs and ensures they're all unique (see here).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing urandom() is out of scope of this PR. A port needs to make sure that works as expected, and then this module should just be able to rely on that.

We could add a loop here to test a few more uniqueness, but IMO 1000 is excessive.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a test that 10 UUIDs are unique.

Comment thread python-stdlib/uuid/uuid.py Outdated
return "-".join((h[0:8], h[8:12], h[12:16], h[16:20], h[20:32]))

def __repr__(self):
return "<UUID: %s>" % str(self)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repr output is different to CPython; would it be better to make it compatible?

Python 3.12.3 (main, Jun 19 2026, 12:46:00) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from uuid import uuid4
>>> uuid4()
UUID('84da63f4-127b-4c34-a7d9-b4321bf6f794')

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, could make it the same as CPython, that would be easy.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to match CPython.

import os


class UUID:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if other methods/properties would make porting CPython code easier, it's hard to know which are in common use. version and variant seem like they would be high on the list - particularly if we decide to add support for UUIDv7 in the future - but it's probably best to hold off for now and keep it as minimal as possible.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't really know what users are going to need...

@dpgeorge

Copy link
Copy Markdown
Member Author

@mattytrentini if you think this is not enough functionality then we can consider instead your #504 implementation. That's fundamentally different in that it stores the UUID as an int and hence allows easy access of fields -- although I'm not sure how useful that will be?

@mattytrentini

Copy link
Copy Markdown
Contributor

@mattytrentini if you think this is not enough functionality then we can consider instead your #504 implementation. That's fundamentally different in that it stores the UUID as an int and hence allows easy access of fields -- although I'm not sure how useful that will be?

No, I think this minimal approach is best, at least for now. I've tried to scour some popular applications that used uuid but of the few I looked at, they just used it without calling any other methods.

@dpgeorge

Copy link
Copy Markdown
Member Author

It's probably a good idea to eventually support more functions, like the namespace UUIDs. And adding a version property would make sense because this uuid4() function creates RFC 4122 UUIDs.

dpgeorge added 2 commits July 14, 2026 14:03
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
@dpgeorge

Copy link
Copy Markdown
Member Author

I exposed the .bytes property to easily access the underlying bytes of the UUID.

@mattytrentini

Copy link
Copy Markdown
Contributor

I think this now strikes an excellent balance between functional and minimal. Looks good to me!

@dpgeorge

Copy link
Copy Markdown
Member Author

Thanks @mattytrentini !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants