-
-
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
Allow passing lambda functions to Nested
#1382
Conversation
Will this cause any problems for apispec? @lafrech |
Oh this is neat. Do you think there's any value to supporting the SQLAlchemy-style syntax of |
It's not explicitly tested because I don't think we need to officially support that usage, but it should work anyway. |
I suppose it wouldn't since the nested field instance is resolved on first call to schema cached property. |
This generalizes slightly better to accommodate #1382
Maybe we hold off on deprecating the string name usage (as well as the It's worth noting that SQLAlchemy also supports string names to |
We could just document |
So finally we'd have
That's double API surface with still unsupported cases.
The last case could be covered with string + a |
The lambda/callable usage can actually handle the circular import, but in a clunky way. def get_artist_schema():
from .artists import ArtistSchema
return ArtistSchema()
class AlbumSchema(Schema):
artist = fields.Nested(get_artist_schema) In most cases, lambda is strictly better than string names because it doesn't break static analysis. The string usage is only provided for convenience in the circular import cases. We could decide to deprecate/remove it later. So it's a bit more like
|
Oh yeah, that was the reason behind my implementation of the string constructor and argument passing, to avoid circular imports, now I remember. Regarding to static analysis / linting, I guess you are also breaking the import guidelines by not having imports at the top of your modules, but by lazily importing the schemas in your factory function, it's clunky indeed. Unfortunately both ways have their lows and ups but I guess only one should be supported not both. |
If I haaad to choose one way, it'd be the @lafrech @Kamforka What do you think about
|
For the lambda case, can you not do: from . import artists
class AlbumSchema(Schema):
artist = fields.Nested(lambda: artists.ArtistSchema()) As long as the evaluation is delayed, I think this should be okay? You do get a circular import, but it should still work. |
@taion That will work sometimes but will break in cases like # core.py
from . import artists
class EntityMixin:
id = fields.UUID()
class AlbumSchema(EntityMixin, Schema):
artist = fields.Nested(lambda: artists.ArtistSchema()) # artists.py
from marshmallow import Schema, fields
from . import core
class ArtistSchema(core.EntityMixin, Schema):
name = fields.Str() |
Those cases seem avoidable, though. The string case carries an implicit requirement, too, that |
Indeed, you can fix the above cases with some code re-org. I still think we should iteratively move users toward the |
* Respect dotted `only` and `exclude` on nested schema instances * Refactor: use _init_fields to re-initialize fields based on `only` and `exclude` Also, be explicit about which helper methods are private * Update changelog * Refactor only/exclude propagation This generalizes slightly better to accommodate #1382 * Fix behavior when dumping multiple times Copy schema to avoid unwanted sharing of `only` and `exclude` across instances * Remove unnecessary falsy checks * Update changelog
Nested
Nested
38f1938
to
6699809
Compare
Do we know what the ETA of merging this is? |
Sorry for the delay. LGTM. |
I'm a bit late on this but my original solution was introduced to solve the circular import issue with nested schemas, when both schema nests the other. |
@Kamforka See #1382 (comment) . It's technically possible to avoid circular imports but it's klunky. The proposal here is to keep support for string names in the short term, but |
This allows passing a schema factory function to
Nested
. This enables passing constructor arguments to circularly-referenced schemas and also allows for self-nesting without the'self'
magic.Closes #1146
Replaces #1151