Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UUID validation fails when provided with 16-byte string #1541

Closed
shawnwall opened this issue May 20, 2020 · 2 comments · Fixed by #1542
Closed

UUID validation fails when provided with 16-byte string #1541

shawnwall opened this issue May 20, 2020 · 2 comments · Fixed by #1542

Comments

@shawnwall
Copy link
Contributor

I'm trying to utilize fastapi + sqlalchemy which uses pydantic. My sqlalchemy column type is BINARY(16) mapping to that exact type in a MariaDB/MySQL database:

uuid = Column(BINARY(16), nullable=False, unique=True)

In pydantic I'm defining as:

uuid: UUID

I get an error thrown that the "value is not a valid uuid (type=type_error.uuid)".

I've cloned pydantic and included a new test for the following:

('uuid_check', b'\x12\x34\x56\x78' * 4, UUID('12345678-1234-5678-1234-567812345678')),

...which fails using your current code. You can find the test byte string above in the official python documentation. I've made a modification in validators to fallback to utilizing the bytes argument in UUID, and then the tests pass. I'm hoping you'd be interested in this fix, as its currently preventing us from using pydantic for a large project refactor. Thank you.

@StephenBrown2
Copy link
Contributor

I might create a subclass of UUID following the Custom Data Types doc to be able to move forward with your project refactor. Something like this should work:

In [1]: from uuid import UUID

In [2]: from pydantic import BaseModel

In [3]: class BinaryUUID(UUID):
   ...:     @classmethod
   ...:     def __get_validators__(cls):
   ...:         yield cls.validate
   ...:
   ...:     @classmethod
   ...:     def validate(cls, v):
   ...:         if not isinstance(v, bytes):
   ...:             raise TypeError('bytes required')
   ...:
   ...:         return cls(bytes=v)
   ...:

In [4]: class TestUuid(BaseModel):
   ...:     uuid: UUID
   ...:     buuid: BinaryUUID
   ...:

In [5]: TestUuid(uuid='12345678123456781234567812345678', buuid=b'\x12\x34\x56\x78'*4)
Out[5]: TestUuid(uuid=UUID('12345678-1234-5678-1234-567812345678'), buuid=BinaryUUID('12345678-1234-5678-1234-567812345678'))

And if you would like to submit a PR with the fix or post the modification you made here for discussion, that would be welcome.

@shawnwall
Copy link
Contributor Author

Thank you for the suggested workaround. I also created a PR in case it helps the project.

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 a pull request may close this issue.

2 participants