googleapis/python-ndb

NDB: equality checking when using StructuredProperty and multiple contexts is broken

aetherknight opened this issue · 1 comments

Environment details

python-ndb 1.11.1
Python 2.7.18
Tested on MacOS 12.6.1

Steps to reproduce

  1. Create an entity in one NDB context
  2. Fetch/get the same entity in another context, or in the same context after having flushed/cleared the caches.
  3. Compare those objects

Code example

from google.cloud import ndb

client = ndb.Client("test")

class SP(ndb.Model):
    some_field = ndb.StringProperty()

class SomeModel(ndb.Model):
    sp = ndb.StructuredProperty(SP)

with client.context():
    obj = SomeModel(sp=SP(some_field="foo"))
    key = obj.put()

with client.context():
    other_obj = key.get()

    print(obj)
    # SomeModel(key=Key(u'SomeModel', 2L), sp=SP(some_field=u'foo'))
    print(other_obj)
    # SomeModel(key=Key(u'SomeModel', 2L), sp=SP(key=Key('SP', None), some_field=u'foo'))

    assert obj == other_obj
    # AssertionErrror...

Stack trace

N/A, it raises on my assertion statement, not deep in the NDB library.

When an entity with a structured property is fetched later/in a different context, NDB auto-adds a key to the structured property's model instance. However, it does not do so when initially creating the instance.

This issue is mainly a nuisance/annoyance when trying to write tests -- We often do test setup in one context, but then our API code creates a new context as a part of its WSGI middleware. We have mocks/spies that make assertions and want to ensure that a particular entity is passed in to some callable, but the objects differ due to the presence of the empty key n the structured properties.

(we have already updated our tests to work around this)