This repository was archived by the owner on Mar 6, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 68
This repository was archived by the owner on Mar 6, 2026. It is now read-only.
[python 2.7, google-cloud-ndb==0.2.0] StringProperty(repeated=True) deserializes list of empty strings into list of None #300
Copy link
Copy link
Closed
Labels
🚨This issue needs some love.This issue needs some love.priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.Important issue which blocks shipping the next release. Will be fixed prior to next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Description
Environment details
- mkvirtualenv py2-ndb-issue -p python2
- pip install google-cloud-ndb==0.2.0 pytest pytest-env
- Cloud SDK
Google Cloud SDK 274.0.0
app-engine-python 1.9.87
app-engine-python-extras 1.9.87
beta 2019.05.17
bq 2.0.51
cloud-datastore-emulator 2.1.0
core 2019.12.17
gsutil 4.46 - run with datastore emulator (same behavior in a GCP env)
Steps to reproduce
- Define a model with a repeated string property
- Set this property to list of empty string and put into the datastore
- Get entity from the datastore, verify a value should equals to the list of empty strings
- Actual behavior - you get list of None.
Code example
class NullableModel(ndb.Model):
list_prop = ndb.StringProperty(repeated=True)
ord_prop = ndb.StringProperty()
# child3 = NullableStringProperty(repeated=True)
@pytest.mark.parametrize("changeset", [
["abc", u"абв"],
["", ""],
[u"", u""],
])
def test_repeated_string_property_none(changeset):
entity = NullableModel()
entity.list_prop = changeset
entity.ord_prop = ""
entity.put()
entity = entity.key.get()
assert entity.ord_prop == ""
assert entity.list_prop == changeset
assert entity.put()Stack trace
============================= test session starts ==============================
platform darwin -- Python 2.7.16, pytest-4.6.9, py-1.8.1, pluggy-0.13.1 -- /Users/vladimir/Virtualenvs/py2-ndb-issue/bin/python2
cachedir: .pytest_cache
rootdir: /Users/vladimir/Projects/py2-ndb-issues, inifile: setup.cfg
plugins: env-0.6.2
collecting ... collected 4 items
test_get_multi.py::test_create_many_change_one_get_multi_all PASSED [ 25%]
test_get_multi.py::test_repeated_string_property_none[changeset0]
test_get_multi.py::test_repeated_string_property_none[changeset1] PASSED [ 50%]FAILED [ 75%]
test_get_multi.py:73 (test_repeated_string_property_none[changeset1])
[None, None] != ['', '']
Expected :['', '']
Actual :[None, None]
<Click to see difference>
changeset = ['', '']
@pytest.mark.parametrize("changeset", [
["abc", u"абв"],
["", ""],
[u"", u""],
])
def test_repeated_string_property_none(changeset):
entity = NullableModel()
entity.list_prop = changeset
entity.ord_prop = ""
entity.put()
entity = entity.key.get()
assert entity.ord_prop == ""
> assert entity.list_prop == changeset
E AssertionError: assert [None, None] == ['', '']
test_get_multi.py:87: AssertionError
FAILED [100%]
test_get_multi.py:73 (test_repeated_string_property_none[changeset2])
[None, None] != [u'', u'']
Expected :[u'', u'']
Actual :[None, None]
<Click to see difference>
changeset = ['', '']
@pytest.mark.parametrize("changeset", [
["abc", u"абв"],
["", ""],
[u"", u""],
])
def test_repeated_string_property_none(changeset):
entity = NullableModel()
entity.list_prop = changeset
entity.ord_prop = ""
entity.put()
entity = entity.key.get()
assert entity.ord_prop == ""
> assert entity.list_prop == changeset
E AssertionError: assert [None, None] == [u'', u'']
test_get_multi.py:87: AssertionError
Assertion failed
test_get_multi.py::test_repeated_string_property_none[changeset2]
The issue seems are in model.py#_entity_from_ds_entity and the following part of the method just in the end ** if sub_value else None **
if value is not None:
if prop._repeated:
value = [
(_BaseValue(sub_value) if sub_value else None)
for sub_value in value
]
else:
value = _BaseValue(value)Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
🚨This issue needs some love.This issue needs some love.priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.Important issue which blocks shipping the next release. Will be fixed prior to next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.