MongoEngine / MongoEngine/mongoengine

LazyReferenceField sometimes failing equality test

Open
#2,465 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
4.3k
Forks
1.2k
Avg merge
4h 41m
Merged PRs (30d)
11

Description

Context: I have an EmbeddedDocument with LazyReferences to another Document called Topic. Throughout my code, I've gotten used to set the values of these references with just the id string (in my case primary ID is a string, not ObjectId). However, this got me failing test cases in certain situations, that points to an undeterministic behaviour of LazyReferenceField.

Test case:

class TestEmb(EmbeddedDocument):
    tests = ListField(LazyReferenceField("Topic"))
    test = LazyReferenceField("Topic")

class Topic(Document):
    id = StringField(primary_key=True)

def test_assert():

    emb2 = TestEmb(test="b")
    emb2.test = "b"
    # print(emb2.test)
    assert emb2 == TestEmb(test="b")

    emb = TestEmb(tests=["b"])
    emb.tests = ["b"]
    # print(emb.tests)
    assert emb == TestEmb(tests=["b"])

So both of these asserts will fail, because __eq__() on DBRef returns (not throws) NotImplemented, which in turn happens because at the time of running __eq__ the test/tests property only contain strings, not DBRefs, and it doesn't do equality between strings and DBRefs. However if I uncomment the print lines, the test will succeed. It seems the reason is that accessing the test/tests property will automatically convert the strings to LazyReferences, which can be compared.

It was really tricky to debug this behaviour, as any prints or watches I set during the debug will mean accessing the property and generating the LazyReferences which make the test case succeed. I would expect that the LazyReference is created when the property is set, not when it's accessed.

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

Start with the TestEmb and Topic reproduction in the issue, focusing on LazyReferenceField assignment and equality before either property is accessed. Add a regression test showing that scalar IDs are converted consistently when assigned, so both equality assertions pass without print or property access.

Written by the indexing model from the issue text.

Assessment

Tech stack
mongodb, python
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.