Skip to content

Conversation

miguelgrinberg
Copy link
Contributor

@miguelgrinberg miguelgrinberg commented Sep 18, 2025

Fixes #3075.

It appears that some users pass AttrDict instances as values for fields of type Object or Nested. If the document is validated (the default when save() is called) then these are handled well, but some users also call save(validate=False) or just to_dict(), in which case the AttrDicts cause the error described in #3075. This change adds logic that tolerates AttrDict values, and treats them like regular dicts (which are already tolerated).

return data

return data.to_dict(skip_empty=skip_empty)
try:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just isinstance(data, AttrDict)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this would also include support for other types that are not AttrDict. And because it avoids evaluating the conditional for every field that is saved, so it should perform a bit better.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this would also include support for other types that are not AttrDict.

Which would probably lead to more crash anyway?

And because it avoids evaluating the conditional for every field that is saved, so it should perform a bit better.

Handling an exception will cost many time what an isinstance cost. But does a few nano seconds performance of this even matter here 🤔 Just seems an unneeded "complex" structure flow to hide a very simple intent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception would be handled only for the fields that have a wrong type. The conditional would have to be evaluated for every single field.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And to my point, does it even matter in this case? Elasticsearch-dsl serialization/deserialization code is clearly not designed with performance in mind, so I don't really see why this one isinstance is seen as a potential issue at the cost of readability. But that's just my 2 cents. (and my last comment on this :) )

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, fwiw, I suppose your method is consistent with Field._safe_serialize

@miguelgrinberg miguelgrinberg force-pushed the support-attrdict-values-in-objects branch from d09d681 to d6e025d Compare September 18, 2025 15:53
@miguelgrinberg
Copy link
Contributor Author

miguelgrinberg commented Sep 19, 2025

@isra17 Thanks for the discussion and the insights you provided.

I'm going to do some additional testing, and if you don't mind, I'm also going to bring the unit test that you created in your PR, which is different than mine.

As far as the exception vs. no exception method for preventing this error it's really not a big deal, but I have seen other methods that do an instance check like you suggested, so maybe that wins in terms of consistency. But I'm not sure if that is enough. I don't know yet if we need a similar fix for AttrList instances in Nested fields, which inherit from Object and use the same serialize/deserialize logic.

@isra17
Copy link

isra17 commented Sep 19, 2025

@isra17 Thanks for the discussion and the insights you provided.

Thanks for looking at the issue! I understand this is a bit of a niche error, so it's nice to see it fixed :)

I'm going to do some additional testing, and if you don't mind, I'm also going to bring the unit test that you created in your PR, which is different than mine.

Of course!

I don't know yet if we need a similar fix for AttrList instances in Nested fields, which inherit from Object and use the same serialize/deserialize logic.

For what it's worth, I think if AttrList would have been an issue we would have seen it in the past since the [de]serialize method never dealt with list? Isn't any fields can be a list anyway? My guess is that to_dict on the document take care of unrolling list? Seems like AttrDict.to_dict does, but I can't find how DocumentBase does it 🤔

@isra17
Copy link

isra17 commented Sep 19, 2025

Ha, Field.serialize deals with the lists.

Copy link
Member

@pquentin pquentin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM.

@miguelgrinberg miguelgrinberg force-pushed the support-attrdict-values-in-objects branch from 5cae556 to 34dc8b7 Compare September 30, 2025 15:50
@miguelgrinberg miguelgrinberg merged commit f68539e into elastic:main Oct 1, 2025
15 checks passed
@miguelgrinberg miguelgrinberg deleted the support-attrdict-values-in-objects branch October 1, 2025 09:34
github-actions bot pushed a commit that referenced this pull request Oct 1, 2025
* Support values of inner docs given as AttrDict instances

* one more unit test

(cherry picked from commit f68539e)
github-actions bot pushed a commit that referenced this pull request Oct 1, 2025
* Support values of inner docs given as AttrDict instances

* one more unit test

(cherry picked from commit f68539e)
github-actions bot pushed a commit that referenced this pull request Oct 1, 2025
* Support values of inner docs given as AttrDict instances

* one more unit test

(cherry picked from commit f68539e)
miguelgrinberg added a commit that referenced this pull request Oct 1, 2025
* Support values of inner docs given as AttrDict instances

* one more unit test

(cherry picked from commit f68539e)

Co-authored-by: Miguel Grinberg <[email protected]>
miguelgrinberg added a commit that referenced this pull request Oct 1, 2025
* Support values of inner docs given as AttrDict instances

* one more unit test

(cherry picked from commit f68539e)

Co-authored-by: Miguel Grinberg <[email protected]>
miguelgrinberg added a commit that referenced this pull request Oct 2, 2025
* Support values of inner docs given as AttrDict instances

* one more unit test

(cherry picked from commit f68539e)

Co-authored-by: Miguel Grinberg <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Object._serialize() missing 1 required positional argument: 'skip_empty'

3 participants