Can assign directly to referenceset attribute without error but value is not persisted
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Storm |
Fix Released
|
Low
|
James Henstridge |
Bug Description
It's currently possible to do this:
>>> parent.children = [Child("foo"), Child("bar")]
where parent is an instance of a class with a one-to-many or many-to-many relationship to the the Child class.
With no error. But this actually overwrites the attribute with a list of unbound objects, rather than saving the relationship. It would be convenient if there was a __set__ method on the appropriate class which would at least thrust an exception under my nose, or better, do a sort of implicit:
>>> self.clear()
>>> for v in values:
... self.add(v)
(I tried monkeypatching from storm.references BoundReferenceSet and BoundIndirectRe
Related branches
- Thomas Herve (community): Approve
- Jamu Kakar (community): Approve
-
Diff: 42 lines (+14/-1)2 files modifiedstorm/references.py (+5/-1)
tests/store/base.py (+9/-0)
description: | updated |
Changed in storm: | |
status: | New → In Progress |
importance: | Undecided → Low |
assignee: | nobody → James Henstridge (jamesh) |
milestone: | none → 0.17 |
Changed in storm: | |
status: | Fix Committed → Fix Released |
__set__() is invoked on the ReferenceSet instance in the class for this case. The BoundReferenceSet and BoundIndirectRe ferenceSet classes are what is returned by ReferenceSet. __get__ ().
A possible implementation for this is:
def __set__(self, obj, value):
bound. clear()
bound. add(item)
bound = self.__get__(obj)
for item in value:
A more advanced implementation might try to clear only the objects that won't be in the new set, and only add those objects that aren't in the old set.