__new__ oder __init__ debuggen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Gesund
User
Beiträge: 14
Registriert: Freitag 6. Mai 2022, 14:45

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?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Aus dem Stacktrace.
Gesund
User
Beiträge: 14
Registriert: Freitag 6. Mai 2022, 14:45

__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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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*?
Gesund
User
Beiträge: 14
Registriert: Freitag 6. Mai 2022, 14:45

__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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Benutzeravatar
__blackjack__
User
Beiträge: 14076
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Gesund
User
Beiträge: 14
Registriert: Freitag 6. Mai 2022, 14:45

__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:
Gesund
User
Beiträge: 14
Registriert: Freitag 6. Mai 2022, 14:45

__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__
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Gesund
User
Beiträge: 14
Registriert: Freitag 6. Mai 2022, 14:45

__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?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit breakpoints in der Metaklasse zb, und einem bevor die Klasse deklariert wird, so das du den ersten überhaupt setzt/beachtest.
Gesund
User
Beiträge: 14
Registriert: Freitag 6. Mai 2022, 14:45

__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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Antworten