-
Notifications
You must be signed in to change notification settings - Fork 10
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
first attempt at an adjacently tagged union for consideration #94
base: main
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## main #94 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 6 9 +3
Lines 468 820 +352
Branches 69 106 +37
==========================================
+ Hits 468 820 +352
Continue to review full report at Codecov.
|
this gives much more interesting test results where you can see the deserialization is fine due to the unique tags but the serialization is not.
src/desert/_fields.py
Outdated
|
||
@attr.s(auto_attribs=True) | ||
class TypeDictFieldRegistry: | ||
the_dict: typing.Dict[typing.Union[type, str], marshmallow.fields.Field] = attr.ib( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big the_foo
user, perhaps .mapping
or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, yeah, that was a garbage name so as to not think about it and worry about other things. Could also just be .dict
Oh hey... look. We can't add the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need a clearer presentation of the relational properties of the Registry idea. There are several entity categories: tag, field, class, hint. For each category C, I want a list of which of the others are required to retrieve a unique instance of C. For example, "a w is uniquely identifiable from a (x,z) tuple or a (y,z) tuple" where w,x,y,z are standing in for some of {tag,field,class,hint}.
registry.register( | ||
hint=Cat, | ||
tag="cat", | ||
field=marshmallow.fields.Nested(desert.schema(Cat, meta={"ordered": True})), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems weird for a standalone class to be registered as a Nested
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought this was how you made a field from a class. But yes, a person having to write this is at least questionable UX. Added to the Draft for:
list in the OP.
P.S. A direct answer is at the end. This was a good refresher for myself and I leave it here in case it is useful. Copied here.
It may be that this mechanism should have a higher level of formality, but I will start by trying to explain what is already here. I think the registry protocol describes the needed functionality and then we can move on to the provided implementation. class FieldRegistryProtocol(typing_extensions.Protocol):
"""This protocol encourages registries to provide a common interface. The actual
implementation of the mapping from objects to be serialized to their Marshmallow
fields, and likewise from the serialized data, can take any form.
"""
def register(
self,
hint: t.Any,
tag: str,
field: marshmallow.fields.Field,
) -> None:
"""Inform the registry of the relationship between the passed hint, tag, and
field.
"""
...
@property
def from_object(self) -> "FromObjectProtocol":
"""This is a funny way of writing that the registry's `.from_object()` method
should satisfy :class:`FromObjectProtocol`.
"""
...
@property
def from_tag(self) -> "FromTagProtocol":
"""This is a funny way of writing that the registry's `.from_tag()` method
should satisfy :class:`FromTagProtocol`.
"""
... (I wonder if I should (could?) make a function to create those protocol-conforming methods...) class FromObjectProtocol(typing_extensions.Protocol):
def __call__(self, value: object) -> HintTagField:
...
class FromTagProtocol(typing_extensions.Protocol):
def __call__(self, tag: str) -> HintTagField:
... Once configured, the registry needs to be able to process either an object to be serialized (
So... the interface does not mandate a whole lot. You could satisfy it with random return values. That's certainly a bit extreme, but I had avoided thus far thinking through what weird corners people might find for oddball relationships between hints, tags, and fields. So, now for the provided implementation,
So I guess for now it is using just the hint to resolve a given object to a field and tag.
So I guess the summary of my self-reacquaintance with this code is that the present implementation in |
Thanks, I'm starting to get the picture. |
#36
Draft for:
.__origin__
feature (or rather it only giveslist
fortyping.List
in 3.7+)Nested
etc at https://github.com/python-desert/desert/pull/94/files#r704735427