[Zope-dev] recursion depth exceeded
Dieter Maurer
dieter@handshake.de
Wed, 6 Mar 2002 22:57:11 +0100
Terry Kerr writes:
> I am running a fairly high traffic Zope server where people occassionly ftp
> files in and out of the server.
>
> Approximately once per week, the zope process will go to using 99%CPU and stay
> like that untill it is restarted. The error shown in the stupid log file is:
>
> 2002-03-06T01:22:41 ERROR(200) ZServer uncaptured python exception, closing
> channel <zope_ftp_channel connected 202.129.84.50:64011 at 8ac4ecc>
> (exceptions.RuntimeError:maximum recursion depth exceeded
> [/usr/local/lib/python2.1/asyncore.py|poll|104]
> [/usr/local/lib/python2.1/asyncore.py|handle_write_event|393]
> [/usr/local/zope/Zope-2.4.3-src/ZServer/medusa/asynchat.py|handle_write|147]
> [/usr/local/zope/Zope-2.4.3-src/ZServer/medusa/asynchat.py|initiate_send|209]
> [/usr/local/zope/Zope-2.4.3-src/ZServer/medusa/asynchat.py|refill_buffer|190]
> [/usr/local/zope/Zope-2.4.3-src/ZServer/medusa/ftp_server.py|close|179]
> [/usr/local/zope/Zope-2.4.3-src/ZServer/medusa/ftp_server.py|close|903]
> [/usr/local/lib/python2.1/asyncore.py|close|355]
> [/usr/local/lib/python2.1/asyncore.py|del_channel|241]
> .....
> [/usr/local/lib/python2.1/asyncore.py|__getattr__|361] .... and so on...
>
>
> Line 361 in asyncore.py is:
>
> 358 # cheap inheritance, used to pass all other attribute
> 359 # references to the underlying socket object.
> 360 def __getattr__ (self, attr):
> 361 return getattr (self.socket, attr)
Python's "getattr" is dangerous (being able to easily give you infinite loops):
In your example, the problems happens when for some reason, the socket
could not be created during the construction.
Fortunately, there is a work around:
Add a class level definition for "socket" before "__getattr__"
socket= None
def __getattr__(self,attr):
return getattr(self.socket,attr)
In your problematic case, this will raise an AttributeError
instead of an "recursion depth exceeded". This is much better.
Dieter