Merge lp:~stefanor/ibid/calc-525439 into lp:~ibid-core/ibid/old-trunk-1.6

Proposed by Stefano Rivera
Status: Merged
Approved by: Jonathan Hitchcock
Approved revision: not available
Merged at revision: 900
Proposed branch: lp:~stefanor/ibid/calc-525439
Merge into: lp:~ibid-core/ibid/old-trunk-1.6
Diff against target: 86 lines (+23/-15)
2 files modified
ibid/plugins/__init__.py (+13/-12)
ibid/plugins/calc.py (+10/-3)
To merge this branch: bzr merge lp:~stefanor/ibid/calc-525439
Reviewer Review Type Date Requested Status
Jonathan Hitchcock Approve
Keegan Carruthers-Smith Approve
Michael Gorven Approve
Review via email: mp+19957@code.launchpad.net

This proposal supersedes a proposal from 2010-02-23.

To post a comment you must log in.
Revision history for this message
Michael Gorven (mgorven) wrote : Posted in a previous version of this proposal

 review approve

review: Approve
Revision history for this message
Michael Gorven (mgorven) wrote : Posted in a previous version of this proposal

Hackity hack...
 review approve

review: Approve
Revision history for this message
Stefano Rivera (stefanor) wrote :

21:10 <@cocooncrash> tumbleweed: Er, I don't quite understand what you're doing in calc
21:11 < tumbleweed> ok, let me explain what I had to change

here goes:

Previously module authors could bypass the Processor inspection (to locate handler functions) by providing a class level list "_event_handlers" of handlers, otherwise it inspects and builds a list of the same name.

Problem with that is when you inherit from a Processor then the subclass assumes that the existing _event_handlers was manual, when it really comes from inspecting the base class.

Solution:
Store the inspected list in __event_handlers (which has to be manually mangled because setattr et al. don't mangle). And extend the list during subclass initialisation. Overriding with a manual list works as before.

Revision history for this message
Michael Gorven (mgorven) :
review: Approve
Revision history for this message
Keegan Carruthers-Smith (keegan-csmith) wrote :

Is _event_handlers or _periodic_handlers ever not None now?

Revision history for this message
Stefano Rivera (stefanor) wrote :

> Is _event_handlers or _periodic_handlers ever not None now?

Nope. And _get_*_handlers isn't overridden by anyone either.

Revision history for this message
Keegan Carruthers-Smith (keegan-csmith) wrote :

Ok, I didn't see the comment explaining the code change when I commented. So a plugin can choose to manually override that.

I haven't really ever played with __new__ before, so I am not 100% what goes on with the setattr(). Say a subclass, A, of processor has _Processor__event_handlers as [handler_a]. Then B, a subclass of A, adds handler_b. So B._Processor__event_handlers is [handler_a, handler_b]? If so I am led to believe A. and Processor. _Processor__event_handlers is also [handler_a, handler_b]. Just wondering if this is intended and if this is how it works?

Also, maybe _Processor__*_handlers should be sets instead of lists?

review: Needs Information
Revision history for this message
Stefano Rivera (stefanor) wrote :

> I haven't really ever played with __new__ before, so I am not 100% what goes
> on with the setattr().

setattr(a, 'b', 'c') is the same as a.b = c
however, setattr doesn't know to do name mangling if you say setattr(a, '__b')

> Say a subclass, A, of processor has _Processor__event_handlers as [handler_a].
> Then B, a subclass of A, adds handler_b. So B._Processor__event_handlers is
> [handler_a, handler_b]?

Correct

> If so I am led to believe A. and Processor. _Processor__event_handlers is also
> [handler_a, handler_b]. Just wondering if this is intended and if this is how
> it works?

Ok, that bit I don't understand. Explain to me on IRC

> Also, maybe _Processor__*_handlers should be sets instead of lists?

No. Definable order could be handy.

Revision history for this message
Keegan Carruthers-Smith (keegan-csmith) :
review: Approve
Revision history for this message
Jonathan Hitchcock (vhata) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ibid/plugins/__init__.py'
--- ibid/plugins/__init__.py 2010-02-03 15:04:43 +0000
+++ ibid/plugins/__init__.py 2010-02-23 11:48:19 +0000
@@ -62,16 +62,17 @@
62 new.default = getattr(cls, name)62 new.default = getattr(cls, name)
63 setattr(cls, name, new)63 setattr(cls, name, new)
6464
65 if getattr(cls, '_event_handlers', None) is None:65 for attr, listname in (
66 cls._event_handlers = []66 ('handler', 'event'),
67 for name, item in cls.__dict__.iteritems():67 ('periodic', 'periodic')):
68 if getattr(item, 'handler', False):68 listname = '_Processor__%s_handlers' % listname
69 cls._event_handlers.append(name)69 if not hasattr(cls, listname):
70 if getattr(cls, '_periodic_handlers', None) is None:70 setattr(cls, listname, [])
71 cls._periodic_handlers = []71 handlers = getattr(cls, listname)
72 for name, item in cls.__dict__.iteritems():72
73 if getattr(item, 'periodic', False):73 for name, item in cls.__dict__.iteritems():
74 cls._periodic_handlers.append(name)74 if getattr(item, attr, False) and name not in handlers:
75 handlers.append(name)
7576
76 return super(Processor, cls).__new__(cls)77 return super(Processor, cls).__new__(cls)
7778
@@ -127,12 +128,12 @@
127128
128 def _get_event_handlers(self):129 def _get_event_handlers(self):
129 "Find all the handlers (regex matching and blind)"130 "Find all the handlers (regex matching and blind)"
130 for handler in self._event_handlers:131 for handler in self._event_handlers or self.__event_handlers:
131 yield getattr(self, handler)132 yield getattr(self, handler)
132133
133 def _get_periodic_handlers(self):134 def _get_periodic_handlers(self):
134 "Find all the periodic handlers"135 "Find all the periodic handlers"
135 for handler in self._periodic_handlers:136 for handler in self._periodic_handlers or self.__periodic_handlers:
136 yield getattr(self, handler)137 yield getattr(self, handler)
137138
138 def _run_periodic_handler(self, method, event):139 def _run_periodic_handler(self, method, event):
139140
=== modified file 'ibid/plugins/calc.py'
--- ibid/plugins/calc.py 2010-01-18 23:20:33 +0000
+++ ibid/plugins/calc.py 2010-02-23 11:48:19 +0000
@@ -2,10 +2,9 @@
2# Released under terms of the MIT/X/Expat Licence. See COPYING for details.2# Released under terms of the MIT/X/Expat Licence. See COPYING for details.
33
4from __future__ import division4from __future__ import division
5from random import random, randint
6
7import logging5import logging
8from os import kill6from os import kill
7from random import random, randint
9from signal import SIGTERM8from signal import SIGTERM
10from subprocess import Popen, PIPE9from subprocess import Popen, PIPE
11from time import time, sleep10from time import time, sleep
@@ -151,7 +150,7 @@
151 safe['pow'] = limited_pow150 safe['pow'] = limited_pow
152 safe['factorial'] = limited_factorial151 safe['factorial'] = limited_factorial
153152
154 @match(r'^(?:calc\s+)?(.+?)$')153 @match(r'^(.+)$')
155 def calculate(self, event, expression):154 def calculate(self, event, expression):
156 for term in self.banned:155 for term in self.banned:
157 if term in expression:156 if term in expression:
@@ -193,6 +192,14 @@
193 if isinstance(result, (int, long, float, complex)):192 if isinstance(result, (int, long, float, complex)):
194 event.addresponse(unicode(result))193 event.addresponse(unicode(result))
195194
195
196class ExplicitCalc(Calc):
197 priority = 0
198
199 @match(r'^calc(?:ulate)?\s+(.+)$')
200 def calculate(self, event, expression):
201 super(ExplicitCalc, self).calculate(event, expression)
202
196help['random'] = u'Generates random numbers.'203help['random'] = u'Generates random numbers.'
197class Random(Processor):204class Random(Processor):
198 u"""random [ <max> | <min> <max> ]"""205 u"""random [ <max> | <min> <max> ]"""

Subscribers

People subscribed via source and target branches