Discussion:
Inheriting from ChoiceField
Jeffrey Eliasen
2018-06-13 01:31:07 UTC
Permalink
I am writing a serializer field type that inherits from `ChoiceField`. In
looking at the code, I see the following:


def __init__(self, choices, **kwargs):
self.choices = choices
# ...
super(ChoiceField, self).__init__(**kwargs)

... and later in the same class I see:

choices = property(_get_choices, _set_choices)

I need to override the behavior of _get_choices(), but I don't believe it
ever gets called as setting self.choices in __init__() *should* replace the
property. Am I misunderstanding something in how Python works, or does this
class contain a bug?

Thanks in advance!
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeffrey Eliasen
2018-06-13 02:09:17 UTC
Permalink
In reading closer, I believe the line in __init__() is supposed to be
`self._choices = choices`.
Post by Jeffrey Eliasen
I am writing a serializer field type that inherits from `ChoiceField`. In
self.choices = choices
# ...
super(ChoiceField, self).__init__(**kwargs)
choices = property(_get_choices, _set_choices)
I need to override the behavior of _get_choices(), but I don't believe it
ever gets called as setting self.choices in __init__() *should* replace the
property. Am I misunderstanding something in how Python works, or does this
class contain a bug?
Thanks in advance!
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeffrey Eliasen
2018-06-13 03:02:17 UTC
Permalink
I've created PR 6023 to show the suspected fix and a test
case. https://github.com/encode/django-rest-framework/pull/6023
Post by Jeffrey Eliasen
In reading closer, I believe the line in __init__() is supposed to be
`self._choices = choices`.
Post by Jeffrey Eliasen
I am writing a serializer field type that inherits from `ChoiceField`. In
self.choices = choices
# ...
super(ChoiceField, self).__init__(**kwargs)
choices = property(_get_choices, _set_choices)
I need to override the behavior of _get_choices(), but I don't believe it
ever gets called as setting self.choices in __init__() *should* replace the
property. Am I misunderstanding something in how Python works, or does this
class contain a bug?
Thanks in advance!
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Xavier Ordoquy
2018-06-13 06:02:49 UTC
Permalink
property doesn’t work the way you think it should.
... def set_a(self, value):
... self._a = value
... def get_a(self):
... return self._a
... a = property(get_a, set_a)
...
Post by Jeffrey Eliasen
d = Demo()
d.a = 1
d.a
1
... def get_a(self):
... print('GET_A')
... return self._a
...
Post by Jeffrey Eliasen
dd = SubDemo()
dd.a = 1
dd.a
1
... def get_a(self):
... print('GET_A')
... return self._a
... def set_a(self, value):
... print('SET_A')
... self._a = value
... a = property(get_a, set_a)
...
Post by Jeffrey Eliasen
dd2 = SubDemo2()
dd2.a = 5
SET_A
Post by Jeffrey Eliasen
dd2.a
GET_A
5
Regards,
Xavier,
Linovia.
Post by Jeffrey Eliasen
self.choices = choices
# ...
super(ChoiceField, self).__init__(**kwargs)
choices = property(_get_choices, _set_choices)
I need to override the behavior of _get_choices(), but I don't believe it ever gets called as setting self.choices in __init__() *should* replace the property. Am I misunderstanding something in how Python works, or does this class contain a bug?
Thanks in advance!
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
For more options, visit https://groups.google.com/d/optout <https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeffrey Eliasen
2018-06-13 07:07:31 UTC
Permalink
Yeah, this was a complete brain fart on my part. I was thinking of the behavior of overwriting a function, not the behavior of a property under the same circimstance. My bad.
Post by Xavier Ordoquy
property doesn’t work the way you think it should.
class Demo: 
...     self._a = value
...     return self._a
...   a = property(get_a, set_a)
... 
d = Demo()
d.a = 1
d.a
1
...     print('GET_A')
...     return self._a
... 
dd = SubDemo()
dd.a = 1
dd.a
1
...     print('GET_A')
...     return self._a
...     print('SET_A')
...     self._a = value
...   a = property(get_a, set_a)
... 
 
dd2 = SubDemo2()
dd2.a = 5
SET_A
dd2.a
GET_A
5
 
Regards,
Xavier,
Linovia.
self.choices = choices
# ...
super(ChoiceField, self).__init__(**kwargs)
choices = property(_get_choices, _set_choices)
I need to override the behavior of _get_choices(), but I don't believe it ever gets called as setting self.choices in __init__() *should* replace the property. Am I misunderstanding something in how Python works, or does this class contain a bug?
Thanks in advance!
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...