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

add UUID1, UUID3, UUID4 and UUID5 types #167

Merged
merged 1 commit into from May 2, 2018

Conversation

@Gr1N
Copy link
Contributor

@Gr1N Gr1N commented Apr 30, 2018

No description provided.

Gr1N added a commit to Gr1N/pydantic that referenced this issue Apr 30, 2018
@codecov
Copy link

@codecov codecov bot commented Apr 30, 2018

Codecov Report

Merging #167 into master will not change coverage.
The diff coverage is 100%.

@@          Coverage Diff          @@
##           master   #167   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files           9      9           
  Lines         938    950   +12     
  Branches      206    207    +1     
=====================================
+ Hits          938    950   +12

def conuuid(*, version=4) -> Type[UUID]:
# use kwargs then define conf in a dict to aid with IDE type hinting
namespace = dict(version_=version)
return type('ConstrainedUUIDValue', (ConstrainedUUID,), namespace)
Copy link
Owner

@samuelcolvin samuelcolvin May 1, 2018

Given that there are only 4 times, should it would be cleaner to just have 4 tyes: Uuid1, Uuid2, ...

Rather than having to implement conuuid

Copy link
Contributor Author

@Gr1N Gr1N May 1, 2018

You're right!

Gr1N added a commit to Gr1N/pydantic that referenced this issue May 1, 2018
add ``ConstrainedUUID``, ``UUID1``, ``UUID3``, ``UUID4`` and ``UUID5`` types (samuelcolvin#167)
@Gr1N Gr1N changed the title add Config.uuid_version; add ConstrainedUUID and conuuid types add Config.uuid_version; add ConstrainedUUID, UUID1, UUID3, UUID4 and UUID5 types May 1, 2018
@Gr1N
Copy link
Contributor Author

@Gr1N Gr1N commented May 1, 2018

@samuelcolvin, updated, please review

Copy link
Owner

@samuelcolvin samuelcolvin left a comment

Looking good, but I think we can make it simpler.

pydantic/main.py Outdated
@@ -20,6 +20,7 @@ class BaseConfig:
max_anystr_length = 2 ** 16
min_number_size = -2 ** 64
max_number_size = 2 ** 64
uuid_version = None
Copy link
Owner

@samuelcolvin samuelcolvin May 1, 2018

I think adding this is unnecessarily confusing. The 5 types UUID, UUID1, UUID3, UUID4 and UUID5 are sufficient.

Copy link
Owner

@samuelcolvin samuelcolvin May 1, 2018

Then you can remove the duplicated logic in ConstrainedUUID and uuid_version_validator

Copy link
Contributor Author

@Gr1N Gr1N May 1, 2018

Done

@@ -48,7 +52,11 @@ class Model(BaseModel):
neg_float=-2.3,
email_address='Samuel Colvin <s@muelcolvin.com >',
email_and_name='Samuel Colvin <s@muelcolvin.com >',
uuid='ebcdab58-6eb8-46fb-a190-d07a33e9eac8'
uuid='ebcdab58-6eb8-46fb-a190-d07a33e9eac8',
uuid_v1='c96e505c-4c62-11e8-a27c-dca90496b483',
Copy link
Owner

@samuelcolvin samuelcolvin May 1, 2018

It'll be much clearer to read if you show how these were generated, eg.

uuid=uuid.uuid4(),
uuid_v1=uuid.uuid1(),
....
uuid_v=uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')

Copy link
Owner

@samuelcolvin samuelcolvin May 1, 2018

same in tests.

Copy link
Contributor Author

@Gr1N Gr1N May 1, 2018

Done

@@ -237,4 +243,36 @@ class NegativeFloat(ConstrainedFloat):
lt = 0


class ConstrainedUUID(UUID):
Copy link
Owner

@samuelcolvin samuelcolvin May 1, 2018

ConstrainedUUID could lead to confusion, I think we can remove it altogether.

I think best to just have

class UUID1(UUID):
    _required_version = 1

...

Then change uuid_validator:

def uuid_validator(v) -> UUID:
    if isinstance(v, str):
        v = UUID(v)
    elif isinstance(v, (bytes, bytearray)):
        v = UUID(v.decode())
    elif not isinstance(v, UUID):
        raise ValueError(f'str, byte or native UUID type expected not {type(v)}')
    required_version = getattr(v, '_required_version', None)
    if required_version and required_version != v.version:
        ...
    return v

Copy link
Contributor Author

@Gr1N Gr1N May 1, 2018

This is a good idea, but I think this is impossible to implement (or I don't know how :). As I see in my tests in uuid_validator v is instance of UUID type, not UUID1 or UUID2...

Validator implementation:

def uuid_validator(v) -> UUID:
    if isinstance(v, str):
        v = UUID(v)
    elif isinstance(v, (bytes, bytearray)):
        v = UUID(v.decode())
    elif not isinstance(v, UUID):
        raise ValueError(f'str, byte or native UUID type expected not {type(v)}')

    required_version = getattr(v, '_required_version', None)
    if required_version and v.version != required_version:
        raise ValueError(f'uuid version {required_version} expected, not {v.version}')

    return v

And test:

class UUIDModel(BaseModel):
    a: UUID1
    b: UUID3
    c: UUID4
    d: UUID5


def test_uuid_validation():
    a = uuid.uuid1()
    b = uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
    c = uuid.uuid4()
    d = uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')

    m = UUIDModel(a=a, b=b, c=c, d=d)
    assert m.dict() == {
        'a': a,
        'b': b,
        'c': c,
        'd': d,
    }

    with pytest.raises(ValidationError) as exc_info:
        UUIDModel(a=d, b=c, c=b, d=a)
    assert exc_info.value.message == '4 errors validating input'

Copy link
Contributor Author

@Gr1N Gr1N May 2, 2018

Done! :)

Gr1N added a commit to Gr1N/pydantic that referenced this issue May 1, 2018
@Gr1N Gr1N changed the title add Config.uuid_version; add ConstrainedUUID, UUID1, UUID3, UUID4 and UUID5 types add ConstrainedUUID, UUID1, UUID3, UUID4 and UUID5 types May 1, 2018
@Gr1N Gr1N changed the title add ConstrainedUUID, UUID1, UUID3, UUID4 and UUID5 types add UUID1, UUID3, UUID4 and UUID5 types May 2, 2018
@Gr1N
Copy link
Contributor Author

@Gr1N Gr1N commented May 2, 2018

@samuelcolvin please review again!

@samuelcolvin samuelcolvin merged commit b4d3a2d into samuelcolvin:master May 2, 2018
3 checks passed
@samuelcolvin
Copy link
Owner

@samuelcolvin samuelcolvin commented May 2, 2018

Looks good, thank you very much. Sorry for the mistake in my comment code!

@Gr1N Gr1N deleted the uuid-type branch May 3, 2018
@Gr1N Gr1N mentioned this pull request May 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants