Opened 9 years ago
Closed 3 years ago
#26287 closed New feature (fixed)
SimpleLazyObject doesn't implement __radd__
Reported by: | Keryn Knight | Owned by: | Theofilos Alexiou |
---|---|---|---|
Component: | Utilities | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | django@…, debanshuk2007@… | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Technically, there's a whole bunch of magic methods it doesn't implement, compared to a complete proxy implementation, like that of wrapt.ObjectProxy
, but __radd__
being missing is the one that's biting me at the moment.
As far as I can tell, the implementation can't just be
__radd__ = new_method_proxy(operator.radd)
because that doesn't exist, which is rubbish.
__radd__ = new_method_proxy(operator.attrgetter("__radd__"))
also won't work because types may not have that attr, and attrgetter doesn't supress the exception (correctly)
The minimal implementation I've found that works for me is:
def __radd__(self, other): if self._wrapped is empty: self._setup() return other + self._wrapped
Change History (11)
comment:1 by , 9 years ago
follow-up: 4 comment:2 by , 9 years ago
In a boiled-down nutshell:
def lazy_consumer(): # something more complex, obviously. return [1, 3, 5] consumer = SimpleLazyObject(lazy_consumer) # inside third party code ... def some_func(param): third_party_code = [...] # then, through parameter passing, my value is provided to be used. # param is at this point, `consumer` third_party_code_plus_mine = third_party_code + param
which ultimately yields:
TypeError: unsupported operand type(s) for +: 'list' and 'SimpleLazyObject'
comment:3 by , 9 years ago
Triage Stage: | Unreviewed → Accepted |
---|
Seems okay, although I'm not an expert on the SimpleLazyObject
class.
comment:4 by , 9 years ago
Replying to kezabelle:
def lazy_consumer(): # something more complex, obviously. return [1, 3, 5] consumer = SimpleLazyObject(lazy_consumer)
If you know what is the resulting type or possible resulting types of your expression, I think you better use django.utils.functional.lazy
which will provide all the necessary methods.
comment:5 by , 8 years ago
Replying to kezabelle:
As far as I can tell, the implementation can't just be
__radd__ = new_method_proxy(operator.radd)because that doesn't exist, which is rubbish.
__radd__ = new_method_proxy(operator.attrgetter("__radd__"))also won't work because types may not have that attr, and attrgetter doesn't supress the exception (correctly)
Wouldn't the following code work?
__add__ = new_method_proxy(operator.add) __radd__ = new_method_proxy(lambda a, b: operator.add(b, a))
I have tested this and it seems to work as excepted.
comment:6 by , 8 years ago
Cc: | added |
---|
comment:7 by , 3 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:8 by , 3 years ago
Has patch: | set |
---|---|
Triage Stage: | Accepted → Ready for checkin |
PR here: https://github.com/django/django/pull/15400. Tried the suggestion by @Debanshu Kundu and it seems to work.
comment:9 by , 3 years ago
Triage Stage: | Ready for checkin → Accepted |
---|
RFC should be set by reviewer, see docs.
comment:10 by , 3 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Could you please give some sample code with your use case?