-
-
Notifications
You must be signed in to change notification settings - Fork 629
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
RFC: Remove Nested(many=True) to keep only the List(Nested()) form #779
Comments
Is there any documentation outlining the differences between these two? I find the distinction confusing as well. |
I don't think there is supposed to be a difference. |
I think deprecating |
@lafrech I was thinking of deprecating in 3. As you pointed out, |
How would a self-referencing schema work with this? In other words, how would we express friends = Nested('self', many=True, exclude=('friends',)) |
I would expect |
I've got production code that relies on the fact that a nested field with The benefit is making sure expensive code that is needed to be executed before nested fields can be dumped is not repeated for each element in the I don't really see this as an edge case though, pretty sure doing something to the whole set of related objects before dumping/loading them is a common pattern. |
Yep, I just updated the list above. |
I saw the ref on the issue, but I couldn't figure out where it came from. Thanks. |
@anka-sirota yes it seems like a common use case, but it very well could be done on parent schema or by subclassing Looking at bigger picture, that this issue already have been here for couple months now, and there still few bugs before
|
@rooterkyberian, I was just searching for this thread to reference your issue. |
All differences listed above are either fixed or on their way to be fixed. Once this is done, we should be able to deprecate |
There is also a difference between from marshmallow import Schema
from marshmallow.fields import List, Nested, Str
class Employee(Schema):
name = Str(required=True)
title = Str(required=True)
def test_nested_partial_load_with_list():
class Company(Schema):
employees = List(Nested(Employee))
payload = {
'employees': [{
'name': 'Arthur',
}],
}
# Partial loading with list type shouldn't generate any errors.
result = Company().load(payload, partial=True)
assert result['employees'][0]['name'] == 'Arthur'
def test_nested_partial_load_with_nested_many():
class Company(Schema):
employees = Nested(Employee, many=True)
payload = {
'employees': [{
'name': 'Arthur',
}],
}
# Partial loading with Nested(many=True) type shouldn't generate any errors.
result = Company().load(payload, partial=True)
assert result['employees'][0]['name'] == 'Arthur' Partial loading in nested schemas was introduced in version 3.0.0rc1 in this PR: #849. Problem is that when a field is of type |
Thans @0xpsilocybe, I think this is the object of @sloria's comment in #1066. I shall update the PR to propagate all needed |
What about the |
Removing |
@lafrech Is there anything else to be addressed before we can deprecate In any case, I don't think we should block on this for releasing 3.0. We can always deprecate within the 3.x line. |
@sloria 👍 on depreciating stuff rather than stacking the deck with more BC breaks. I'd much rather have 8 releases with 8 breaking changes than 8 breaking changes in one release... I don't know about anyone else, but we've got hundreds - maybe even a thousand schemas to migrate. I'd rather take that in strides! |
@fuhrysteve, about this, please see the conversation in #928. |
Great. Is there the same kind of gap between |
Ya, Edit: I added the fix for |
Does it make sense to remove |
@jtrakk |
I see. FWIW, I've seen people (including myself) pass |
Yeah, it's a known issue. The reasons we use **kwargs instead of e.g. Not the best reasons, but I think it's not terrible. We've discussed adding a whitelist of metadata keys in the past, but we decided it wasn't worth the added API surface. |
I suppose so. That being said, 3.0.0 would be a good time to do it, and it wouldn't be hard to write an automatic converter using libCST or similar that'd move all the current |
With this change and the # before
albums = fields.Nested(AlbumSchema, many=True, only=('id', 'title', ))
# after (possible now)
albums = field.List(fields.Nested(AlbumSchema(only=('id', 'title'))))
# before
artist = fields.Nested('ArtistSchema', only=('id', ))
# after (proposed)
artist = fields.Nested(lambda: ArtistSchema(only=('id',))) |
#1801 may be related to this topic. But after looking at the code of |
Maybe the best solution is to document the differences and otherwise leave it be. It's easy to imagine there are many codebases around the world that depend on one of the two behaviours, given they aren't identical. |
See discussion in #493 (comment).
We have two ways to do the same thing. They sometimes behave differently, which generally means one of them is buggy.
IMHO, and from what I have seen from users around me, it is more natural for a new user to write
List(Nested)
thanNested(many)
. Besides, it is consistent withDict(values=Nested)
.I realize this is quite a breaking change, both from user perspective, because
Nested(many=True)
is probably the most commonly used form, and from developer perspective, because it involves a lot of code changes (but also a lot of code removal, which is nice).There could be things that can be done with
Nested(many=True)
but not withList(Nested)
, because in the latter case, the nested Schema has access to the whole data, while in the former, it is called on each element. Perhaps somepre_load
edge cases might suffer from the change. Any real-life example, anyone?Anyway, since the question was raised in a comment in another issue, I figured I'd give it more visibility.
The text was updated successfully, but these errors were encountered: