Seite 1 von 1

__new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 09:45
von Gesund
Moin Leute,

ich habe das Problem, das ein paar abgeleitete Klassen nicht instanziert werden können, weil die Parameteranzahl von __new__ oder __init__ nicht übereinstimmt.
pdb bricht einfach ab und sagt z.B. missing 1 required positional argument
Ich möchte mit dem Debugger in die __new__ Funktion treten, damit ich mir den Dateinamen+Zeilnummer anzeigen lassen kann, wo das Problem liegt, aber das geht nicht.
Wie finde ich jetzt raus, wo die abgeleite Klasse ist, mit der falschen Parameteranzahl?

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 10:05
von __deets__
Aus dem Stacktrace.

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 11:44
von Gesund
__deets__ hat geschrieben: Freitag 21. Oktober 2022, 10:05 Aus dem Stacktrace.
Nein der Stacktrace zeigt weder __new__ noch __init__ an, das ist ja mein Problem.

Re: __new__ oder __init__ debug

Verfasst: Freitag 21. Oktober 2022, 12:00
von __deets__
Der zeigt aber die Zeile , wo du die aufrufst. Und die wirst du dann mit deren tatsächlicher Definition vergleichen müssen. Was soll der debugger da tun? Einfach mal prophylaktisch eine Methode aufrufen, der der Interpreter nicht aufrufen *kann*?

Re: __new__ oder __init__ debug

Verfasst: Freitag 21. Oktober 2022, 12:35
von Gesund
__deets__ hat geschrieben: Freitag 21. Oktober 2022, 12:00 Der zeigt aber die Zeile , wo du die aufrufst. Und die wirst du dann mit deren tatsächlicher Definition vergleichen müssen. Was soll der debugger da tun? Einfach mal prophylaktisch eine Methode aufrufen, der der Interpreter nicht aufrufen *kann*?
Es wird der Klassenname angezeigt, mehr nicht. Ich habe nach der Klasse gesucht, und dort ist stimmen die Parameter, und bei den Unterklassen auch. Deswegen wrürde ich gerne die exakte Zeile sehen, wo der __new__ der __init__ Aufruf fehlgeschlagen ist.

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 12:41
von __deets__
Ohne den Code und die Fehlermeldung zu sehen, kann man dazu nicht viel mehr sagen. Und was der Stacktrace anzeigt, ist die exakte Zeile. Der Python-Debugger hat da keine besseren Zeilen parat. Wenn es sich bei der Klasse um eine aus einer Extension handelt, dann kommt es innerhalb des in C geschriebenen Interpreters zur Fehlermeldung. Und da bekommst du so einfach keine Informationen raus. Man *kann* das machen, aber das habe ich nur gebraucht, wenn ich selbst C/C++-Erweiterungen geschrieben habe.

Wobei der Debugger helfen kann, ist genaure Informationen ueber die Argumente, und die tatsaechlichen Typen zu liefern. Aber an der Stelle vorbei kommt er trotzdem nicht.

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 12:43
von __blackjack__
@Gesund: Das steht doch aber im Traceback wo der Aufruf her kommt‽

Beispiel: Dieser Code:

Code: Alles auswählen

#!/usr/bin/env python3


class Class:
    def __init__(self, value, another_value):
        self.value = value
        self.another_value = another_value


def main():
    instance = Class(42, 23)
    another_instance = Class(4711)


if __name__ == "__main__":
    main()
Führt zu diesem Traceback:

Code: Alles auswählen

Traceback (most recent call last):
  File "forum12.py", line 16, in <module>
    main()
  File "forum12.py", line 12, in main
    another_instance = Class(4711)
TypeError: __init__() missing 1 required positional argument: 'another_value'
Und da sieht man doch sehr deutlich welcher Aufruf den auslöst.

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 12:49
von Gesund
__deets__ hat geschrieben: Freitag 21. Oktober 2022, 12:41 Ohne den Code und die Fehlermeldung zu sehen, kann man dazu nicht viel mehr sagen. Und was der Stacktrace anzeigt, ist die exakte Zeile. Der Python-Debugger hat da keine besseren Zeilen parat. Wenn es sich bei der Klasse um eine aus einer Extension handelt, dann kommt es innerhalb des in C geschriebenen Interpreters zur Fehlermeldung. Und da bekommst du so einfach keine Informationen raus. Man *kann* das machen, aber das habe ich nur gebraucht, wenn ich selbst C/C++-Erweiterungen geschrieben habe.

Wobei der Debugger helfen kann, ist genaure Informationen ueber die Argumente, und die tatsaechlichen Typen zu liefern. Aber an der Stelle vorbei kommt er trotzdem nicht.
Ne es, handelt sich um reinen Python Quelltext. Die Fehlermeldung lautet:
TypeError: __init__() missing 1 required positional argument:

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 12:53
von Gesund
__blackjack__ hat geschrieben: Freitag 21. Oktober 2022, 12:43 @Gesund: Das steht doch aber im Traceback wo der Aufruf her kommt‽

Beispiel: Dieser Code:

Code: Alles auswählen

#!/usr/bin/env python3


class Class:
    def __init__(self, value, another_value):
        self.value = value
        self.another_value = another_value


def main():
    instance = Class(42, 23)
    another_instance = Class(4711)


if __name__ == "__main__":
    main()
Führt zu diesem Traceback:

Code: Alles auswählen

Traceback (most recent call last):
  File "forum12.py", line 16, in <module>
    main()
  File "forum12.py", line 12, in main
    another_instance = Class(4711)
TypeError: __init__() missing 1 required positional argument: 'another_value'
Und da sieht man doch sehr deutlich welcher Aufruf den auslöst.
Bei mir nicht, wie gesagt, es scheint an einer Unterklasse zu liegen.
Traceback (most recent call last):
File "/usr/lib/python3.9/pdb.py", line 1726, in main
pdb._runscript(mainpyfile)
File "/usr/lib/python3.9/pdb.py", line 1586, in _runscript
self.run(statement)
File "/usr/lib/python3.9/bdb.py", line 580, in run
exec(cmd, globals, locals)
File "<string>", line 1, in <module>
File "bt_bot.py", line 52, in <module>
import backtrader.plot
File "/usr/local/lib/python3.9/dist-packages/backtrader/__init__.py", line 69, in <module>
from . import indicators as indicators
File "/usr/local/lib/python3.9/dist-packages/backtrader/indicators/__init__.py", line 30, in <module>
from .basicops import *
File "/usr/local/lib/python3.9/dist-packages/backtrader/indicators/basicops.py", line 33, in <module>
class PeriodN(Indicator):
TypeError: __init__() missing 1 required positional argument: 'Parameter'
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /usr/local/lib/python3.9/dist-packages/backtrader/indicators/basicops.py(33)<module>()
-> class PeriodN(Indicator):
Wenn ich nach der Klasse suche finde ich folgenden Quelltext:

Code: Alles auswählen

class PeriodN(Indicator):
    '''
    Base class for indicators which take a period (__init__ has to be called
    either via super or explicitly)

    This class has no defined lines
    '''
    params = (('period', 1),)

    def __init__(self, Parameter=None):
        self.Parameter= Parameter
        super(PeriodN, self).__init__()
        self.addminperiod(self.p.period)
und alle Unterklassen haben weder __init__ noch __new__

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 13:02
von __deets__
Unterklassen muessen ja auch kein __init__ oder __new__ haben. Klassen darueber muessen das, und das Paket macht eine ganze Menge mit Meta-Magie. Siehe https://github.com/mementum/backtrader/ ... tor.py#L90

Ohne da tiefer reingeschaut zu haben, hat das wahrscheinlich mit diesem params-Ding zu tun. Du musst halt rausfinden, was passiert, wenn die Klasse erzeugt wird. Denn an der wird rumgefummelt.

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 14:11
von Gesund
__deets__ hat geschrieben: Freitag 21. Oktober 2022, 13:02 Unterklassen muessen ja auch kein __init__ oder __new__ haben. Klassen darueber muessen das, und das Paket macht eine ganze Menge mit Meta-Magie. Siehe https://github.com/mementum/backtrader/ ... tor.py#L90

Ohne da tiefer reingeschaut zu haben, hat das wahrscheinlich mit diesem params-Ding zu tun. Du musst halt rausfinden, was passiert, wenn die Klasse erzeugt wird. Denn an der wird rumgefummelt.
Ich habe mich schon seit Tagen durchgewurschtelt...... wie kann ich denn das Metagedönst debuggen?

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 14:25
von __deets__
Mit breakpoints in der Metaklasse zb, und einem bevor die Klasse deklariert wird, so das du den ersten überhaupt setzt/beachtest.

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 15:18
von Gesund
__deets__ hat geschrieben: Freitag 21. Oktober 2022, 14:25 Mit breakpoints in der Metaklasse zb, und einem bevor die Klasse deklariert wird, so das du den ersten überhaupt setzt/beachtest.
Ich weiß nicht nicht, wo die sind und außerdem sind es mehrere.
Sinnvoll wäre es, wen man da Schritt für Schritt reingehen könnte.

Re: __new__ oder __init__ debuggen

Verfasst: Freitag 21. Oktober 2022, 15:39
von __deets__
Die Metaklasse ist doch in der von mir verlinkten Codestelle angegeben - die musst du dir eben anschauen, und das nachvollziehen, was die macht, und darin breakpoints setzen.