[Zope] - can't __call__ objects?

skip@calendar.com (Skip Montanaro) skip@calendar.com (Skip Montanaro)
Fri, 18 Dec 1998 14:17:06 -0500


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