Doubly Nested Schemas instantiated via lambdas cannot be referenced with multiple dot notation with onlys/excludes
Related to https://github.com/marshmallow-code/marshmallow/pull/2164
The following works as intended
from marshmallow import Schema, fields
class ASchema(Schema):
a = fields.String()
a2 = fields.String()
class BSchema(Schema):
b = fields.Nested(lambda: ASchema)
class CSchema(Schema):
c = fields.Nested(lambda: BSchema)
class DSchema(Schema):
d = fields.Nested(lambda: CSchema, only=("c.b.a2",))
class A:
def __init__(self):
self.a = 'Hello from a'
self.a2 = 'Hello from a2'
class B:
def __init__(self, a):
self.b = a
class C:
def __init__(self, b):
self.c = b
class D:
def __init__(self, c):
self.d = c
print(DSchema().dump(D(C(B(A())))))
Outputting
{'d': {'c': {'b': {'a2': 'Hello from a2'}}}}
However when changing the CSchema nested field c lambda to return an instantiated BSchema(), the output is different and incorrect
class CSchema(Schema):
c = fields.Nested(lambda: BSchema())
Outputs
{'d': {'c': {}}}
I've narrowed this issue down to https://github.com/marshmallow-code/marshmallow/blob/dev/src/marshmallow/fields.py#L601 where the self.only values in the instantiated BSchema() will be "b.a2" whereas original = self._schema.fields.keys() will be the top-level parent "b". This results in an empty set intersection meaning the serialized value will have no fields.
Thanks for the research and the comprehensive bug report.
A fix proposal would be very welcome, anyone.