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

WIP Added support for tuples, namedtuples (both from collections and typing), sets, frozensets and OrderedDict's in MSONable, MontyEncoder and MontyDecoder #100

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

davidwaroquiers
Copy link
Contributor

@davidwaroquiers davidwaroquiers commented Jan 14, 2020

Summary

Solves #89

  • tuple's, collections.namedtuple's, typing.NamedTuple's, set's, frozenset's and collections.OrderedDict's are automatically serialized as special dictionaries, that allow to reconstruct the proper object upon deserialization.

TODO

Might want to add support for other objects, e.g. Data classes and possibly others.
Not sure whether the last try-except in the default method of MontyEncoder is still necessary as the as_dict is now directly performed (recursively) at the beginning of the encode method of MontyEncoder.

a_nt = namedtuple('a', ['x', 'y', 'z'])
a1 = a_nt(1, 2, 3)
assert a1 == (1, 2, 3)
assert is_namedtuple(a1) is True
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need "is True". The assert tests whether it is True.
Similarly, 3 lines later you just need "assert not is_named_tuple..."

Copy link
Contributor Author

@davidwaroquiers davidwaroquiers Jan 16, 2020

Choose a reason for hiding this comment

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

It is actually not exactly equivalent. The "is True" also checks that the returned value is a bool and not for example an empty list vs a non empty list. If is_namedtuple(a1) were to return, e.g. ["hello"] (or to return [] in the "False" case), "assert is_namedtuple(a1)" would also pass while the API would have changed. I would keep the "is True" if that's ok for you. Same for 3 lines after (and also in quite a lot of other places).

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I know it is not exactly equivalent, but we need to think of typical use cases. When people use that method, they are not going to check that it is a boolean type. They will merely check that it is a "True-like" value. E.g., if is_namedtuple(a1). That's the Pythonic way of doing this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course, users will use it this way. My point is that this method is supposed (from its docstring/name) to return a bool indicating whether it is a namedtuple or not. Why should we allow any new development/change to return something else (e.g. the string "Yes it is a namedtuple" for the True case and "" for the False case) ? This unit test is just preventing that. Anyway if you prefer to remove the "is True", I can do it. For me the pythonic way applies for the code itself, but the test code can deviate from that for the reason above.

def test_tuple_serialization(self):
a = GoodMSONClass(a=1, b=tuple(), c=1)
afromdict = GoodMSONClass.from_dict(a.as_dict())
assert type(a.b) is tuple
Copy link
Contributor

Choose a reason for hiding this comment

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

I think isinstance is a better approach. This applies to all instances where you use type(X) is or == something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

isinstance checks that the instance is a tuple or a subclass of tuple. I think it is more safe to use type(a.b) is tuple as it would prevent someone (a weirdo btw ;-) to change the MSONable as_dict and/or from_dict to return a subclass of tuple when deserializing. What do you think ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. But this is a test, not the actual code. So here, it suffices to make sure it is an instance of tuple.

Copy link
Contributor Author

@davidwaroquiers davidwaroquiers Jan 17, 2020

Choose a reason for hiding this comment

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

If the user serializes a tuple, he expects to get back exactly a tuple when deserializing. Using isinstance in the test allows to change that. I could modify the MSONable from_dict to return a subclass of a tuple instead of a real tuple.

…have the correct type.

Unit tests for validate_NamedTuple.
…edtuples, etc ... in order to avoid potential clashes with the builtins package.
@davidwaroquiers davidwaroquiers changed the title Added support for tuples, namedtuples and OrderedDict's in MSONable, MontyEncoder and MontyDecoder WIP Added support for tuples, namedtuples and OrderedDict's in MSONable, MontyEncoder and MontyDecoder Jan 16, 2020
@davidwaroquiers davidwaroquiers changed the title WIP Added support for tuples, namedtuples and OrderedDict's in MSONable, MontyEncoder and MontyDecoder WIP Added support for tuples, namedtuples (both from collections and typing), sets, frozensets and OrderedDict's in MSONable, MontyEncoder and MontyDecoder Jan 17, 2020
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.

2 participants