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

[improvement] add support for hashing / settype + more tests #39

Merged
merged 10 commits into from
Feb 1, 2019

Conversation

derenrich
Copy link
Contributor

Before this PR

  • Comparison of Union types was broken
  • No tests for enum or union types
  • No way to represent Sets separate from Lists

After this PR

This PR does a few things:

@derenrich derenrich requested a review from a team as a code owner January 8, 2019 03:50
Copy link
Contributor

@ferozco ferozco left a comment

Choose a reason for hiding this comment

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

Although this change is not a break, adopting this change in conjure-python would be since we're changing the request/response types for sets. I think long term this is the right thing to do, but i'm unsure if it is the right time to have cause a major rev. @ahggns for thoughts

decoded_A2 = ConjureDecoder().read_from_string("\"A\"", TestEnum)
assert decoded_A != decoded_B
assert decoded_A == decoded_A2

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: white space

B = 2
C = 3

def test_enum_decode():
Copy link
Contributor

Choose a reason for hiding this comment

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

could we also add some negative test cases?

from conjure_python_client import ConjureDecoder, ConjureEnumType


class TestEnum(ConjureEnumType):
Copy link
Contributor

Choose a reason for hiding this comment

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

could we use a generated enum instead of a hand rolled one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -36,6 +37,14 @@ def __init__(self, item_type):
self.item_type = item_type


class SetType(ConjureType):
item_type = None # type: Type[DecodableType]
Copy link
Contributor

Choose a reason for hiding this comment

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

could we also define __slots__ for the class to reduce memory overhead?

Copy link
Contributor

Choose a reason for hiding this comment

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

Could be done in a follow up along with the other type classes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

seems like premature optimization to me

@@ -62,6 +63,8 @@ def check_null_field(
cls, obj, deserialized, python_arg_name, field_definition):
if isinstance(field_definition.field_type, ListType):
deserialized[python_arg_name] = []
elif isinstance(field_definition.field_type, SetType):
deserialized[python_arg_name] = []
Copy link
Contributor

Choose a reason for hiding this comment

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

should this not be a frozenset?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i dont think so?

Copy link
Contributor

Choose a reason for hiding this comment

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

it should. otherwise the actual type of a set member in an object will vary depending on the wire format of the response.

  • The type will be frozenset if the collection is present ex: { "foo":[1,2] }
  • The type will be array if the collection is absent. ex: {}, { "foo": null }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh misunderstood which thing you were suggesting swapping to frozen set. you are correct

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed and added a test


def test_set_does_not_decode_from_json_null():
with pytest.raises(Exception):
ConjureDecoder().read_from_string("null", SetType(int))
Copy link
Contributor

Choose a reason for hiding this comment

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

is this a json null or the string null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

json null

import pytest
from conjure_python_client import ConjureDecoder, ListType, ConjureUnionType, ConjureFieldDefinition

class TestUnion(ConjureUnionType):
Copy link
Contributor

Choose a reason for hiding this comment

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

same here, use a generated union instead of a hand rolled one

Copy link
Contributor

@ahggns ahggns left a comment

Choose a reason for hiding this comment

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

In agreement that this is directionally correct, and the use of proper set types is unlikely to break existing code which was mostly treating lists as sets anyway.

As far as breaks go I think we have a handful of other breaks we'd been considering and it'd probably be better to do a bunch at once so we can be more watchful of the rollout.

assert not decoded_C.c

def test_invalid_decode():
with pytest.raises(Exception):
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a more specific error we can expect?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nope. the code just throws Exception at the moment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this code is copied from existing tests

@@ -36,6 +37,14 @@ def __init__(self, item_type):
self.item_type = item_type


class SetType(ConjureType):
item_type = None # type: Type[DecodableType]
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like we're pretty inconsistent elsewhere, but fields should probably be underscored with a @property method for access.

@derenrich
Copy link
Contributor Author

in response to

i'm unsure if it is the right time to have cause a major

I think we should merge this now and then discuss when to cause a break in the conjure-python repo

@derenrich
Copy link
Contributor Author

good to go?

@ferozco
Copy link
Contributor

ferozco commented Jan 31, 2019

Sorry, this totally slipped through the cracks. I think getting this in would be great!

@derenrich
Copy link
Contributor Author

cool. did i miss any changes you requested? the PR is still disapproved by you @ferozco

@bulldozer-bot bulldozer-bot bot merged commit 2871176 into palantir:develop Feb 1, 2019
iamdanfox added a commit that referenced this pull request Mar 6, 2019
bulldozer-bot bot pushed a commit that referenced this pull request Mar 6, 2019
…39)" (#52)

Reverts #39

reported by @geremih - seems like the conjure bean type's hashing is not stable!

Just doing a quick revert to make sure latest is known good, then we can revisit with a proper fix here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Generate a real Python 'set' for the Conjure set<T> type
4 participants