marshmallow-code / marshmallow-code/marshmallow

Doubly Nested Schemas instantiated via lambdas cannot be referenced with multiple dot notation with onlys/excludes

Open
#2,165 3 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
7.2k
Forks
738
Avg merge
1d 23h
Merged PRs (30d)
7

Description

Related to https://github.com/marshmallow-code/marshmallow/pull/2164

The following works as intended

```py
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
```py
{'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
```py
class CSchema(Schema):
c = fields.Nested(lambda: BSchema())
```
Outputs
```py
{'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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the nested schema example, then inspect src/marshmallow/fields.py around line 601, especially how self.only is intersected with self._schema.fields.keys(). Compare the instantiated BSchema() case with the lambda: BSchema case; done means both serialize {'d': {'c': {'b': {'a2': 'Hello from a2'}}}}.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.