Skip to content
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

Created object equality with retrieved object varies if breakpoint is set #1967

Open
lunalucadou opened this issue Feb 3, 2025 · 1 comment

Comments

@lunalucadou
Copy link

lunalucadou commented Feb 3, 2025

I have the following model:

class AppData(Document):
    id: str # UUID
    permissions: list[str] = Keyword(multi=True)
    webhooks: list[Webhook]

    class Index:
        name = "app_data"

These documents are created in this method:

class EsDao:
    def __init__(self, es_connection: Elasticsearch):
        self.es_connection: Elasticsearch = es_connection.options(ignore_status=404)

    def create_app_data(self, app_id: str, permissions: list[str]) -> AppData:
        app_data = AppData(
            meta={"id": app_id},
            id=app_id,
            permissions=permissions,
            webhooks=[],
        )
        app_data.save(using=self.es_connection)
        return app_data

And the code works fine, but integration tests fail when I check equality between created objects and retrieved objects:

    def test_create_app_data_creates_new_data(self):
        created_app = self.dao.create_app_data(
            "test", ["permission1", "permission2"]
        )
        self.assertEqual(created_app.id, "test")
        self.assertEqual(created_app.permissions, ["permission1", "permission2"])
        retrieved_app = AppData.get(id=created_app.id)
        self.assertEqual(created_app, retrieved_app)

It fails because retrieved_app.meta contains found=True, which is not present on created_app. So, I decided to force them to be equal:

    def test_create_app_data_creates_new_data(self):
        created_app = self.dao.create_app_data(
            "test", ["permission1", "permission2"]
        )
        self.assertEqual(created_app.id, "test")
        self.assertEqual(created_app.permissions, ["permission1", "permission2"])
        retrieved_app = AppData.get(id=created_app.id)

        # First attempt:
        created_app.meta["found"] = retrieved_app.meta["found"]
        # Second attempt:
        created_app.meta = retrieved_app.meta
        # Third attempt:
        del retrieved_app.meta["found"]
        # Fourth attempt:
        del retrieved_app.meta._d_["found"]

        self.assertEqual(created_app, retrieved_app)

All four methods work when I have a breakpoint set in the test and run it in the IntelliJ debugger (the final self.assertEqual passes), but none of them work when run normally or in the debugger without any breakpoints set (the final self.assertEqual fails). Why is this, and how can I make this test work reliably?

I could change the return statement of create_app_data to call .get but I would prefer to avoid a (seemingly) redundant call, if possible.

I am using elasticsearch-dsl 8.17.1.

@miguelgrinberg
Copy link
Collaborator

Unfortunately I cannot reproduce this problem. Here is the example that I built based on your description of the problem:

import os
from elasticsearch_dsl import connections, Document

connections.create_connection(hosts=[os.environ["ELASTICSEARCH_URL"]])

class MyDoc(Document):
    id: str
    name: str

    class Index:
        name = "my-index"

MyDoc._index.delete(ignore_unavailable=True)
MyDoc.init()

doc = MyDoc(id='test', name='elastic', meta={'id': 'test'})
doc.save(refresh=True)

doc1 = MyDoc.get('test')
assert doc == doc1
assert not hasattr(doc.meta, 'found')
assert doc1.meta.found

The three asserts at the end pass, so as far as I can see the found attribute does not matter for the equality check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants