MongoEngine / MongoEngine/mongoengine
Slicing a ListField(EmbeddedField) can lead to strange value in _changed_fields
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 4.3k
- Fork
- 1.2k
- Merge medio
- 4h 41m
- PR unite (30g)
- 11
Descrizione
While fixing something else in BaseList, I noticed that slicing a BaseList could lead to bad values of the parent document._changed_fields. Additionally, it is behaving differently under python2 and python3.
In fact, see below (under PY3):
class Age(me.EmbeddedDocument):
age = me.IntField()
class Person(me.Document):
ages = me.EmbeddedDocumentListField(Age)
p = Person()
p.ages = [Age(age=1), Age(age=2), Age(age=3)]
p.save()
sliced = p.ages[1:3]
print(sliced) # [<Age: Age object>, <Age: Age object>]
print(type(sliced)) # <class 'mongoengine.base.datastructures.BaseList'>
print(sliced._instance) # Person object
print(sliced._name) # "ages.slice(1, 3, None)" <---- BOOM!
print(p._changed_fields) # []
sliced[1] = Age(age=1000)
print(p._changed_fields) # ['ages.slice(1, 3, None).1'] >
p.save() # Fails with OperationError: Could not save document (cannot use the part (ages of ages.slice(1, 3, None).1)...
Under PY2, here is the output:
class Age(me.EmbeddedDocument):
age = me.IntField()
class Person(me.Document):
ages = me.EmbeddedDocumentListField(Age)
p = Person()
p.ages = [Age(age=1), Age(age=2), Age(age=3)]
p.save()
sliced = p.ages[1:3]
print(sliced) # [<Age: Age object>, <Age: Age object>]
print(type(sliced)) # list (and not a BaseList like in PY3)
print(sliced._instance) # Fails with AttributeError: 'list' object has no attribute '_instance'
The difference between PY2 & PY3 comes from the fact that PY2 calls BaseList.getslice and PY3 calls getitem (with key being a slice, which causes the weird ._name attribute). This is something I'm harmonizing in another PR (#1853) so that at least it will behave the same (but faulty).
Being able to track changes properly after slicing is not trivial, especially if we try to identify specifically the index/key of the things being changed. I'll think of it in the next days, if I manage to find a clean fix, I'll push a PR
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia in BaseList, confrontando la gestione degli slice da parte di getslice e getitem, e verifica il comportamento descritto per Python 2 e Python 3. Controlla PR #1853 per la relativa armonizzazione, quindi definisci test che coprano lo slicing, _changed_fields e il salvataggio del documento padre senza l’OperationError segnalato.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- mongodb, python
- Ambito
- database
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Da chiarire
- Idoneità per principianti
- 30/100