Seite 1 von 1
Rekursion: maximum recursion depth exceeded
Verfasst: Freitag 25. Juni 2010, 16:21
von rads
Hallo zusammen,
ich habe ein Rekursionsproblem da angeblich die maximal Rekursionstiefe erreicht wurde.
Fehlermeldung: "maximum recursion depth exceeded"
Dachte, ah ok hast halt einen Denkfehler eingebaut.
Aber nach etwas suchen ist mir in meinem Code nichts aufgefallen und so habe ich mit einer "statischen " Variablen (ja die gibts nicht) einfach mal Methodenaufrufe mitgezählt.
Angeblich ist bei 10 Aufrufen Schluss, ok dacht ich mir. Das kann nicht sein, Standard ist ja meistens 2000.
googel googel.
sys.getrecursionlimit(), setrecursionlimit(limit)
Mit diesen Funktionen kann die maximale Rekursionstiefe ausgelesen oder verändert werden. Die maximale Rekursionstiefe ist mit 1000 vorbelegt und bricht endlos rekursive Funktionsaufrufe ab, bevor diese zu einem Speicherüberlauf führen können.
Default Rekursionstiefe bei 1000. Also gehe ich davon aus, er erkennt frühzeitig das es "endlos" ist.
Da wollt ich fragen wie er das erkennt?
Grüße
anbei der code, falls interessant
Code: Alles auswählen
def build(self):
try:
self.htmlDoc = HTML("<html><head></head><body></body></html>")
self.__recursiveListHandling([], self.orderFields, self.whereFields)
print self.htmlDoc
except Exception, e:
print e
pass
#===========================================================================
def __recursiveListHandling(self,usedList,toUseList, whereFields):
try:
if len(toUseList) > 0:
....
for result in fieldList:
....
self.__recursiveListHandling(copy.deepcopy(usedList),
copy.deepcopy(copyToUseList),
copy.deepcopy(copyWhereFields))
else:
....
self.__writeTicketBlock(ticket[0])
pass
except Exception, e:
...
def __writeTicketBlock(self,ticketId):
for i in range(0,6)):
try:
...
self.htmlDoc = self.htmlDoc | Transformer('.//body').append("   %s \n"%sqlResult[0][i])
...
except Exception, e:
print e
break
pass
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Freitag 25. Juni 2010, 16:26
von Darii
rads hat geschrieben:Aber nach etwas suchen ist mir in meinem Code nichts aufgefallen und so habe ich mit einer "statischen " Variablen (ja die gibts nicht) einfach mal Methodenaufrufe mitgezählt.
Angeblich ist bei 10 Aufrufen Schluss, ok dacht ich mir.
Sicher dass du richtig gezählt hast?
Da wollt ich fragen wie er das erkennt?
Unendlich bedeutet > sys.getrecursionlimit()
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Freitag 25. Juni 2010, 16:33
von BlackJack
@rads: Wie sieht denn der Traceback aus? Da müsstest Du doch sehen was die Aufrufe sind, und auch das es wohl mehr als 10 sind.
Der Code sieht ein wenig komisch aus. Was sollen die ganzen Fehlerbehandlungen die eigentlich keine sind? Ausgabe jeder beliebigen Ausnahme ist keine adäquate Fehlerbehandlung.
`deepcopy()` ist IMHO auch ein "code smell". Das braucht man nur ganz selten. Kann es vielleicht sogar sein, dass Du da irgendwie eine rekursive Datenstruktur gebaut hast, und die eventuell Probleme beim Kopieren verursacht?
Die doppelten führenden Unterstriche solltest Du durch einzelne ersetzen. Das ist in dem Sinne kein "private" und sollte auch nicht als solches missbraucht werden.
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Freitag 25. Juni 2010, 16:38
von rads
Schonmal danek für die schnelle Antwort.
Sicher natürlich nicht, da es ja keine statische Variable ist
ich habe in build eine variable mit self.counter = 0 angelegt
und in den Methoden recursiveListHandling und writeTicketBlock
mache ich als ersten Befehl self.counter = self.counter + 1
Also an sich sogar mehr als die eigentliche Rekurssionstiefe.
sys.getrecursionlimit() liefert mir 1000 zurück.
Ok, dann MUSS ich einen Fehler gemacht habe, doch
etwas schleierhaft ist mir das schon
@Blackjack
- Traceback gibts nicht da ich die Exception fange, Meldung ist wie oben geschrieben max recursion..
- Fehlerbehandlungen sind rein als ich den aktuellen Fehler gesucht habe. Ich bekomme sonst kein Traceback da
Trac das verschluckt (schreibe ein Plugin für Trac)
- Dachte auch erst an deepcopy, aber bei kleinern Mengen macht er die Rekursion fehlerfrei, also ist hier nichts "endloses" drinnen. Aber ich sehe mir das nochmal genauer an
- Ok ändere das mit private ab, dann bedeute für mich private etwas anderes

Re: Rekursion: maximum recursion depth exceeded
Verfasst: Freitag 25. Juni 2010, 20:22
von Leonidas
rads hat geschrieben: - Traceback gibts nicht da ich die Exception fange, Meldung ist wie oben geschrieben max recursion..
Ja, BlackJack meinte dass man das eben nicht machen sollte.
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Dienstag 29. Juni 2010, 13:06
von rads
Leonidas hat geschrieben:rads hat geschrieben: - Traceback gibts nicht da ich die Exception fange, Meldung ist wie oben geschrieben max recursion..
Ja, BlackJack meinte dass man das eben nicht machen sollte.
rads hat geschrieben:- Fehlerbehandlungen sind rein als ich den aktuellen Fehler gesucht habe. Ich bekomme sonst kein Traceback da
Trac das verschluckt (schreibe ein Plugin für Trac)
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Dienstag 29. Juni 2010, 13:09
von BlackJack
@rads: Wird das wirklich verschluckt? Wie soll man denn da Plugins entwickeln? Wenn das nicht schon im Log landet, gibt es sicher eine Möglichkeit Trac so zu konfigurieren, *dass* es im Log landet.
Ansonsten musst Du den Stacktrace halt selbst ausgeben.
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Dienstag 29. Juni 2010, 16:17
von rads
@Blackjack
Grundsätzlich schon, leider frisst sich bei einer Recursion-Exception der Thread.
Trac bekommt nichts von einem Fehler mit, Oberfläche ist weiterhin möglich, allerdings
hat sich mein Modull komplett verabschiedet und ist nicht mehr ansprechbar, was aber
Trac auch nicht mitbekommt.
Deswegen mache ich es leider so. Danke Blackjack, das mit den print stacktrace hilft
mir hoffentlich, bis jetzt habe ich noch nicht rausgefunden wo das problem ist, tippe aber
das es mit den verarbeiten der Listen und der kopieren irgendwie zusammen hängt.
Grüße
Stefan
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Mittwoch 30. Juni 2010, 08:49
von rads
Fehler jetzt eingeschränkt,
Exception: maximum recursion depth exceeded
Befehl: print self.htmlDoc
Definition: self.htmlDoc = HTML("<html><head></head><body></body></html>")
Operationen: self.htmlDoc = self.htmlDoc | Transformer('.//body') \
.append(Element('h%s'%(len(usedList)+1))(tag.p()("[%s] %s: "%(ticket,ticketSummary))))
An sich reiche ich das self object immer durch und führe darauf ausschließlich Transformationen mit Genshi aus.
Gibt es möglichkeiten die Struktur einer Variablen zu analysieren? debuggen ist leider auch nicht.
Falls ich was finde geb ich euch bescheid

Ein Kaffee und ein Bier das es ein idiotischer Fehler ist.
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Mittwoch 30. Juni 2010, 09:12
von rads
Ok,
offenbar wird jedesmal, wenn ich self.html = self.html | Transform (...) eine Rekursion aufgerufen.
Wenn ich die Anzahl deutlich reduziere, läuft der Code bekanntlich fehlerfrei.
mal schaun wo hier der denkfehler ist
Anbei ein Minimalbeispiel:
Code: Alles auswählen
def build(self):
self.htmlDoc = HTML("<html><head></head><body></body></html>")
self.addNumber()
print self.htmlDoc
def addNumber(self):
for number in range(0,5000):
self.htmlDoc = self.htmlDoc |Transformer('.//body').append(tag.p()("number %s"%number))
Habe meinen traceback gefunden (ist nur ein ausschnitt, aber immer das gleiche)
Code: Alles auswählen
# File "C:\Entwicklungsecke\Software\Python26\lib\site-packages\genshi\core.py", line 267, in _ensure
Code fragment:
262. COMMENT = Stream.COMMENT
263.
264. def _ensure(stream):
265. """Ensure that every item on the stream is actually a markup event."""
266. stream = iter(stream)
267. event = stream.next()
268.
269. # Check whether the iterable is a real markup event stream by examining the
270. # first item it yields; if it's not we'll need to do some conversion
271. if type(event) is not tuple or len(event) != 3:
272. for event in chain([event], stream):
Local variables:
Name Value
stream <generator object _unmark at 0x0329BDF0>
# File "C:\Entwicklungsecke\Software\Python26\lib\site-packages\genshi\filters\transform.py", line 686, in _unmark
Code fragment:
681. def _mark(self, stream):
682. for event in stream:
683. yield OUTSIDE, event
684.
685. def _unmark(self, stream):
686. for mark, event in stream:
687. kind = event[0]
688. if not (kind is None or kind is ATTR or kind is BREAK):
689. yield event
690.
691.
Local variables:
Name Value
self <genshi.filters.transform.Transformer object at 0x032457F0>
stream <generator object __call__ at 0x0329BDC8>
# File "C:\Entwicklungsecke\Software\Python26\lib\site-packages\genshi\filters\transform.py", line 1144, in __call__
Code fragment:
1139. def __call__(self, stream):
1140. """Apply the transform filter to the marked stream.
1141.
1142. :param stream: The marked event stream to filter
1143. """
1144. for mark, event in stream:
1145. yield mark, event
1146. if mark is ENTER:
1147. for mark, event in stream:
1148. if mark is EXIT:
1149. break
Local variables:
Name Value
self <genshi.filters.transform.AppendTransformation object at 0x03245870>
stream <generator object __call__ at 0x0329BDA0>
# File "C:\Entwicklungsecke\Software\Python26\lib\site-packages\genshi\filters\transform.py", line 713, in __call__
Code fragment:
708. """
709. namespaces = {}
710. variables = {}
711. test = self.path.test()
712. stream = iter(stream)
713. for mark, event in stream:
714. if mark is None:
715. yield mark, event
716. continue
717. result = test(event, {}, {})
718. # XXX This is effectively genshi.core._ensure() for transform
Local variables:
Name Value
namespaces {}
self <genshi.filters.transform.SelectTransformation object at 0x032457B0>
stream <generator object _mark at 0x0329BD78>
test <function _test at 0x033455B0>
variables {}
# File "C:\Entwicklungsecke\Software\Python26\lib\site-packages\genshi\filters\transform.py", line 682, in _mark
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Mittwoch 30. Juni 2010, 09:45
von rads
Lösung:
Ok, gefällt mir nicht, ist aber wahrscheinlich schneller
Ich cache den Text in einer String Variablen
und mache nur eine Transformation mit Genshi.
Merke: Streamtransformationen mit Genshi über 2000x aufrufen ist nix gut.
Beispielslösung:
Code: Alles auswählen
test = ""
for number in range(0,5000):
test = "%s %s"%(test,tag.strong()(number))
self.htmlDoc = self.htmlDoc | Transformer(".//body").append(HTML(test))
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Mittwoch 30. Juni 2010, 10:14
von BlackJack
@rads: Das ist IMHO eine sehr eigenartige Methode um so eine Zeichenkette zusammenzusetzen. Die idiomatische und auch effizientere Variante sieht so aus:
Code: Alles auswählen
test = ' '.join(str(tag.strong()(n)) for n in xrange(5000))
Re: Rekursion: maximum recursion depth exceeded
Verfasst: Mittwoch 30. Juni 2010, 10:42
von rads
@BlackJack Danke, war nur ein Beispiel um die Methode mal schenll 5000x aufzurufen. Ansonsten läuft das ja über meine rekursive methode wie zu Begin gepostet. Aber danke BlackJack, ich freue mich immer über Anregungen deinerseits
