I'm experimenting with ZPublisher directly, since I think it will fit my needs better than full-blown Zope. If I have a class with a __call__ method, ZPublisher won't let me call the instance. I realize __call__ violates the "no underscore" publishing rule, but if an object is an instance and is otherwise publishable, shouldn't __call__ be called (no pun)? Revisiting my simple ASCII calendar, if I define class Calendar: """simple calendar class""" def show(self, year=time.localtime(time.time())[0], month=0): """return plain ASCII calendar month == 0 ==> display calendar for entire year year defaults to the current year, month to 0 """ if year < 1902 or year > 2037: raise ValueError, ("year out of range: %d" % year) if month < 0 or month > 12: raise ValueError, ("month out of range: %d" % month) save_stdout = sys.stdout sys.stdout = cStringIO.StringIO() if month: calendar.prmonth(year, month) else: calendar.prcal(year) sys.stdout.seek(0,0) _c = sys.stdout.read() sys.stdout = save_stdout return _c cal = Calendar() then publish it with ZopeHTTPServer, I can easily access it with URLs like http://localhost:8043/cal/show?year:int=1999&month:int=4 If, however, I change the definition of the Calendar class to have a __call__ method instead: class Calendar: """simple calendar class""" def __call__(self, year=time.localtime(time.time())[0], month=0): """return plain ASCII calendar month == 0 ==> display calendar for entire year year defaults to the current year, month to 0 """ if year < 1902 or year > 2037: raise ValueError, ("year out of range: %d" % year) if month < 0 or month > 12: raise ValueError, ("month out of range: %d" % month) save_stdout = sys.stdout sys.stdout = cStringIO.StringIO() if month: calendar.prmonth(year, month) else: calendar.prcal(year) sys.stdout.seek(0,0) _c = sys.stdout.read() sys.stdout = save_stdout return _c then try to access URLs like http://localhost:8043/cal?year:int=1999&month:int=4 I get Sorry, the requested document does not exist. showcal.Calendar instance at 814c158 Traceback (innermost last): File /home/dolphin/skip/src/Zope-1.9.0b3-src/lib/python/ZPublisher/Publish.py, line 879, in publish_module File /home/dolphin/skip/src/Zope-1.9.0b3-src/lib/python/ZPublisher/Publish.py, line 576, in publish (Info: /cal) File /home/dolphin/skip/src/Zope-1.9.0b3-src/lib/python/ZPublisher/Response.py, line 300, in setBody NotFound: (see above) I realize it's not a big deal in this simple example, but it seems to me that if an instance is otherwise publisher-ready, that it should be __call__able. Skip Montanaro | Mojam: "Uniting the World of Music" http://www.mojam.com/ skip@calendar.com | Musi-Cal: http://concerts.calendar.com/ 518-372-5583
On Fri, 18 Dec 1998 skip@calendar.com wrote:
From DT_String.py: class func_code_class: pass func_code=func_code_class() func_code.co_varnames='self','REQUEST' func_code.co_argcount=2 func_defaults=()
Or from one of my projects: class HTMLFile: """A HTML File to go trough HTML Templates""" classDescriptor="DocumentTemplate" def __init__(self,fs,path,suffix=""): self.fs=fs self.path=path class func_code_class: pass func_code=func_code_class() func_code.co_varnames='self','REQUEST' func_code.co_argcount=2 func_defaults=() def __call__(self,client=None,mapping={},**kw): return apply(HTML(self.fs.readFile(self.path)),(client,mapping,),kw) Andreas
At 02:17 PM 12/18/98 -0500, Skip Montanaro wrote:
I'm experimenting with ZPublisher directly, since I think it will fit my needs better than full-blown Zope.
If I have a class with a __call__ method, ZPublisher won't let me call the instance. I realize __call__ violates the "no underscore" publishing rule, but if an object is an instance and is otherwise publishable, shouldn't __call__ be called (no pun)?
Bobo^H^H^H^HZPublisher call's an object's 'index_html' method, if no method is specified. So if you want your __call__ method to be considered the default published method here's how to do it: class CallMe: "defines __call__ as the default publishing method" def __call__(self): "call the object" ... index_html=__call__ Pretty simple. -Amos
On Fri, 18 Dec 1998, Amos Latteier wrote:
Bobo^H^H^H^HZPublisher call's an object's 'index_html' method, if no method is specified.
So if you want your __call__ method to be considered the default published method here's how to do it:
class CallMe: "defines __call__ as the default publishing method"
def __call__(self): "call the object" ...
index_html=__call__ That's not really desirable many times, as one'd like the DocumentTemplate behaviour of calling an object with self==containing folder. Additionally index_html is called with the wrong idea of location: ..../test.gif is interpreted as the URL ..../test.gif/index_html
For this to work, one has to add the parameter/default values to the object to emulate a real callable object. It seems probable that you can even have any parameter combination, including RESPONSE, which would allow images to be pseudo methods too :) (Not that it matters for images, but anything that is returning in fact text as SQL methods, HTML file methods, LaTeX methods, etc. should be able to be an method. If one needs an property context around the method, one can still use a directory with the object in it as index.* stuck in.) Andreas -- Win95: n., A huge annoying boot virus that causes random spontaneous system crashes, usually just before saving a massive project. Easily cured by UNIX. See also MS-DOS, IBM-DOS, DR-DOS, Win 3.x, Win98.
Andreas Kostyrka wrote:
On Fri, 18 Dec 1998, Amos Latteier wrote:
Bobo^H^H^H^HZPublisher call's an object's 'index_html' method, if no method is specified.
So if you want your __call__ method to be considered the default published method here's how to do it:
class CallMe: "defines __call__ as the default publishing method"
def __call__(self): "call the object" ...
index_html=__call__ That's not really desirable many times, as one'd like the DocumentTemplate behaviour of calling an object with self==containing folder. Additionally index_html is called with the wrong idea of location: .../test.gif is interpreted as the URL .../test.gif/index_html
Right. In particular the base href gets set to .../test.gif, not .../
For this to work, one has to add the parameter/default values to the object to emulate a real callable object. It seems probable that you can even have any parameter combination, including RESPONSE, which would allow images to be pseudo methods too :)
Exactly. ZPublisher won't call something unless it smells like a function (or method). In particular, it can't marshal parameters unless it hase some function meta-data telling it how. Now, I suppose that if an object has a __call__ method, it could get the meta-data from that. Hm. I wonder why it doesn't do that. I must have had a good reason. ;) Maybe this should change. Jim -- Jim Fulton mailto:jim@digicool.com Technical Director (888) 344-4332 Python Powered! Digital Creations http://www.digicool.com http://www.python.org Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats.
participants (4)
-
Amos Latteier -
Andreas Kostyrka -
Jim Fulton -
skip@calendar.com