TypeError with PySide 6.5.0 for multiple inheritance of MainWindow
-
wrote on 9 Apr 2023, 14:36 last edited by StarterKit 4 Sept 2023, 14:58
Hi all,
It appears I got a problem after PySide upgrade from 6.4.3 to 6.5.0.
Here is a minimal example - it does nothing special, just displays a window and a label in it. The structure of the code is similar to the one I use in real project where UI is created with help of Qt Designer generated files.
This code works fine with PySide 6.4.3, but with PySide 6.5.0 it raises an error.
The error:window = MainWindow() ^^^^^^^^^^^^^^^^^ File "main.py", line 11, in __init__ QMainWindow.__init__(self, parent=None) TypeError: object.__init__() takes exactly one argument (the instance to initialize)
The code:
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel class Ui_X_MainWindow(object): def setupUi(self, MainWindow): MainWindow.resize(400, 300) self.lbl = QLabel(self) class MainWindow(QMainWindow, Ui_X_MainWindow): def __init__(self): QMainWindow.__init__(self, parent=None) self.setupUi(self) self.lbl.setText("XXX") app = QApplication([]) window = MainWindow() window.show() app.exec()
-
@SGaist said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
This is wrong, self shall not be part of the arguments passed to the function called when using super.
super().init(parent=parent)That's what he said. I'm not sure enough about my Python to answer, maybe no harm in trying :)
It would be interesting to know if there is a PyQt6.5.0 and how it handles your existing code. You say it was working at 6.4.3, I don't know whether the PySide 6.5 is correct or not.
For the architecture of this particular logger case. Since you have to derive from
logging.Handler
, why don't you encapsulate theQPlainTextEdit
in your class instead of multiple-inheriting from it? My initial thought is that would be preferable. Then you would not multiple-inherit and you wouldn't have the current problem, whatever it is.wrote on 14 Apr 2023, 18:27 last edited by@JonB said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
For the architecture of this particular logger case. Since you have to derive from logging.Handler, why don't you encapsulate the QPlainTextEdit in your class instead of multiple-inheriting from it? My initial thought is that would be preferable. Then you would not multiple-inherit and you wouldn't have the current problem, whatever it is.
Finally I decided to encaplusate
logging.Handler
in my class and now I like it more than before :)
The bug was confirmed in PySide and to be corrected in future versions but everything works good without multiple inheritance.Also initial code was not ideal and was different from Qt recommendations.
So, with both things changed I have my code up and running again.
-
Hi all,
It appears I got a problem after PySide upgrade from 6.4.3 to 6.5.0.
Here is a minimal example - it does nothing special, just displays a window and a label in it. The structure of the code is similar to the one I use in real project where UI is created with help of Qt Designer generated files.
This code works fine with PySide 6.4.3, but with PySide 6.5.0 it raises an error.
The error:window = MainWindow() ^^^^^^^^^^^^^^^^^ File "main.py", line 11, in __init__ QMainWindow.__init__(self, parent=None) TypeError: object.__init__() takes exactly one argument (the instance to initialize)
The code:
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel class Ui_X_MainWindow(object): def setupUi(self, MainWindow): MainWindow.resize(400, 300) self.lbl = QLabel(self) class MainWindow(QMainWindow, Ui_X_MainWindow): def __init__(self): QMainWindow.__init__(self, parent=None) self.setupUi(self) self.lbl.setText("XXX") app = QApplication([]) window = MainWindow() window.show() app.exec()
wrote on 9 Apr 2023, 14:55 last edited byI downgraded PySide6 to version 6.4.3 (with 2 dependencies - PySide6-Essentials and PySide6-Addons) and it works. So the problem is definitely appeared after an upgrade of PySide to 6.5.0.
-
I downgraded PySide6 to version 6.4.3 (with 2 dependencies - PySide6-Essentials and PySide6-Addons) and it works. So the problem is definitely appeared after an upgrade of PySide to 6.5.0.
wrote on 9 Apr 2023, 16:24 last edited by@StarterKit You would need to report this over at https://bugreports.qt.io/.
-
@StarterKit You would need to report this over at https://bugreports.qt.io/.
wrote on 9 Apr 2023, 17:00 last edited by@JonB unfortunately I don't clearly understand what is wrong here and as a result I feel my bug report will be inconsistent or incomplete...
Do you see something that is obviosly wrong here?... I see that here is some mess with different constructor calls that takes different set of arguments... but I can't make my complain more clear, unfortunately... :( -
@JonB unfortunately I don't clearly understand what is wrong here and as a result I feel my bug report will be inconsistent or incomplete...
Do you see something that is obviosly wrong here?... I see that here is some mess with different constructor calls that takes different set of arguments... but I can't make my complain more clear, unfortunately... :(Hi,
I currently don't have a direct answer for this new issue however, the use of
super
is more common in code designed with Qt for Python. Even more so in Python 3 code bases.You can see some good reasons here as to why.
-
Hi,
I currently don't have a direct answer for this new issue however, the use of
super
is more common in code designed with Qt for Python. Even more so in Python 3 code bases.You can see some good reasons here as to why.
wrote on 10 Apr 2023, 13:53 last edited by StarterKit 4 Oct 2023, 13:54@SGaist , while I fully support your point of using super() I can't figure out how to fix this exact error with help of it.
-
@SGaist , while I fully support your point of using super() I can't figure out how to fix this exact error with help of it.
wrote on 10 Apr 2023, 16:45 last edited by JonB 4 Oct 2023, 18:39@StarterKit
If you replace your
QMainWindow.__init__(self, parent=None)
by
super().__init__(self, parent=None)
[Should not haveself
as per @SGaist below.]
does it make the problem go away?If that does not solve, not that you should have to but try omitting the
, parent=None
in both theQMainWindow
and thesuper()
cases. -
@StarterKit
If you replace your
QMainWindow.__init__(self, parent=None)
by
super().__init__(self, parent=None)
[Should not haveself
as per @SGaist below.]
does it make the problem go away?If that does not solve, not that you should have to but try omitting the
, parent=None
in both theQMainWindow
and thesuper()
cases.Lifetime Qt Championwrote on 10 Apr 2023, 18:26 last edited by SGaist 4 Oct 2023, 18:27@JonB said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
@StarterKit
If you replace your
QMainWindow.__init__(self, parent=None)
by
super().__init__(self, parent=None)
does it make the problem go away?This is wrong,
self
shall not be part of the arguments passed to the function called when using super.super().__init__(parent=parent)
-
@JonB said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
@StarterKit
If you replace your
QMainWindow.__init__(self, parent=None)
by
super().__init__(self, parent=None)
does it make the problem go away?This is wrong,
self
shall not be part of the arguments passed to the function called when using super.super().__init__(parent=parent)
-
wrote on 11 Apr 2023, 16:05 last edited by StarterKit 4 Nov 2023, 16:14
@JonB , @SGaist , thanks for your proposal, but probably my message was not clear enough. I tried this code already and it fails with the same error unfortunately :(
File "main.py", line 10, in __init__ super().__init__(parent=None) TypeError: object.__init__() takes exactly one argument (the instance to initialize)
It only works if I put nothing:
super().__init__()
but... in this case I have a failure in another part of my code... (I'm still looking into it but it appears without
parent=None
some other widget behaves wrong...) -
@JonB , @SGaist , thanks for your proposal, but probably my message was not clear enough. I tried this code already and it fails with the same error unfortunately :(
File "main.py", line 10, in __init__ super().__init__(parent=None) TypeError: object.__init__() takes exactly one argument (the instance to initialize)
It only works if I put nothing:
super().__init__()
but... in this case I have a failure in another part of my code... (I'm still looking into it but it appears without
parent=None
some other widget behaves wrong...)wrote on 11 Apr 2023, 16:56 last edited byOk, I found why I my code fails if I use
super().__init__()
.
It happens because I have the same problem in another place... And I don't have a clear idea how to fix it in an easy way.So, I use python logging module in my app. Traditionally it prints messages to a console by default. You may redirect it to file or something else.
But you may do whatever you want if you create you own handler and pass it to
logging.addHandler()
method. But your handler should be a descendant oflogging.Handler
.So, I use Qt to have GUI and I deciced to put logging output into a Plain text editor.
As result I created a class that is descendant of both -QPlainTextEdit
andlogging.Handler
:class LogViewer(QPlainTextEdit, logging.Handler): def __init__(self, parent=None): QPlainTextEdit.__init__(self, parent) logging.Handler.__init__(self) # Other initialization def emit(self, record, **kwargs): # log record handling
and then I use it:
self.Logs = LogViewer(parent_widget) self.logger = logging.getLogger() self.logger.addHandler(self.Logs)
And as result I have exactly the same prolem
TypeError: Level not an integer or a valid string
because now it tries to passparent_widget
tologging.Handler
constructor. -
Ok, I found why I my code fails if I use
super().__init__()
.
It happens because I have the same problem in another place... And I don't have a clear idea how to fix it in an easy way.So, I use python logging module in my app. Traditionally it prints messages to a console by default. You may redirect it to file or something else.
But you may do whatever you want if you create you own handler and pass it to
logging.addHandler()
method. But your handler should be a descendant oflogging.Handler
.So, I use Qt to have GUI and I deciced to put logging output into a Plain text editor.
As result I created a class that is descendant of both -QPlainTextEdit
andlogging.Handler
:class LogViewer(QPlainTextEdit, logging.Handler): def __init__(self, parent=None): QPlainTextEdit.__init__(self, parent) logging.Handler.__init__(self) # Other initialization def emit(self, record, **kwargs): # log record handling
and then I use it:
self.Logs = LogViewer(parent_widget) self.logger = logging.getLogger() self.logger.addHandler(self.Logs)
And as result I have exactly the same prolem
TypeError: Level not an integer or a valid string
because now it tries to passparent_widget
tologging.Handler
constructor.wrote on 11 Apr 2023, 17:03 last edited by StarterKit 4 Nov 2023, 17:03Should I have
super(QPlainTextEdit, self).__init__(parent) super(logging.Handler, self).__init__()
instead of:
QPlainTextEdit.__init__(self, parent) logging.Handler.__init__(self)
?
-
Should I have
super(QPlainTextEdit, self).__init__(parent) super(logging.Handler, self).__init__()
instead of:
QPlainTextEdit.__init__(self, parent) logging.Handler.__init__(self)
?
wrote on 11 Apr 2023, 17:16 last edited by JonB 4 Nov 2023, 17:17@SGaist said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
This is wrong, self shall not be part of the arguments passed to the function called when using super.
super().init(parent=parent)That's what he said. I'm not sure enough about my Python to answer, maybe no harm in trying :)
It would be interesting to know if there is a PyQt6.5.0 and how it handles your existing code. You say it was working at 6.4.3, I don't know whether the PySide 6.5 is correct or not.
For the architecture of this particular logger case. Since you have to derive from
logging.Handler
, why don't you encapsulate theQPlainTextEdit
in your class instead of multiple-inheriting from it? My initial thought is that would be preferable. Then you would not multiple-inherit and you wouldn't have the current problem, whatever it is. -
@SGaist said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
This is wrong, self shall not be part of the arguments passed to the function called when using super.
super().init(parent=parent)That's what he said. I'm not sure enough about my Python to answer, maybe no harm in trying :)
It would be interesting to know if there is a PyQt6.5.0 and how it handles your existing code. You say it was working at 6.4.3, I don't know whether the PySide 6.5 is correct or not.
For the architecture of this particular logger case. Since you have to derive from
logging.Handler
, why don't you encapsulate theQPlainTextEdit
in your class instead of multiple-inheriting from it? My initial thought is that would be preferable. Then you would not multiple-inherit and you wouldn't have the current problem, whatever it is.wrote on 11 Apr 2023, 19:54 last edited by StarterKit 4 Nov 2023, 19:55@JonB, I've created PYSIDE-2294 where I try to figure out how my code should look like...
The main strange thing indeed is that everything is fine with 6.4.3 and goes to hell with 6.5.0. I'm not a python master but... it worked pretty well before 6.5.0 even if my code isn't ideal :)With regards to your question about inheritance. I use Qt Designer to create UI layout. So for me it is easier to have Qt-based class that I may use in Qt Designer and simply put an object on form with help of mouse. This is why I inherited from
QPlainTextEdit
.
I may do it other way around and make another class that would be derived fromlogging.Handler
and then use it as a member of my class. But these two classes will be tightly coupled and won't work one without another.
So... if one way I lose benefits of Qt, another way I have bad design... - and then, why would we have multiple inheritance at all? :) I created this class some time ago and it survived migration from Qt 5 to Qt 6... But now it fails with Qt 6.5.0 :( -
@JonB, I've created PYSIDE-2294 where I try to figure out how my code should look like...
The main strange thing indeed is that everything is fine with 6.4.3 and goes to hell with 6.5.0. I'm not a python master but... it worked pretty well before 6.5.0 even if my code isn't ideal :)With regards to your question about inheritance. I use Qt Designer to create UI layout. So for me it is easier to have Qt-based class that I may use in Qt Designer and simply put an object on form with help of mouse. This is why I inherited from
QPlainTextEdit
.
I may do it other way around and make another class that would be derived fromlogging.Handler
and then use it as a member of my class. But these two classes will be tightly coupled and won't work one without another.
So... if one way I lose benefits of Qt, another way I have bad design... - and then, why would we have multiple inheritance at all? :) I created this class some time ago and it survived migration from Qt 5 to Qt 6... But now it fails with Qt 6.5.0 :(wrote on 12 Apr 2023, 14:31 last edited by StarterKit 4 Dec 2023, 14:42Hi all,
So it appears to be a bug introduced in PySide 6.5.0 release that they corrected as result of PYSIDE-2294.But I try to understand how
super()
works based on information that I collected.
And I'm a bit puzzled now...
Here is my old code:import logging from PySide6.QtWidgets import QApplication, QPlainTextEdit class LogViewer(QPlainTextEdit, logging.Handler): def __init__(self, parent=None): QPlainTextEdit.__init__(self, parent) # this line will be changed logging.Handler.__init__(self) # this line will be changed app = QApplication([]) window = LogViewer() window.show() print(f"LEVEL: {window.level}") app.exec()
It works and prints
LEVEL: 0
as expected.
But based on all these discussions I decided to change it and usesuper()
and got this code:import logging from PySide6.QtWidgets import QApplication, QPlainTextEdit class LogViewer(QPlainTextEdit, logging.Handler): def __init__(self, parent=None): super().__init__(parent=parent) # this line was changed app = QApplication([]) window = LogViewer() window.show() print(f"LEVEL: {window.level}") app.exec()
And this code fails with
AttributeError: 'LogViewer' object has no attribute 'level'
- it appears thatlogging.Handler
ancestor didn't become a part ofwindow
object... I don't understand what is wrong in this case... Any hints?...I played a bit and changed 2nd example to use different class order:
class LogViewer(logging.Handler, QPlainTextEdit)
and it gave meTypeError: Handler.__init__() got an unexpected keyword argument 'parent'
that raises a feeling that something is not right... -
@SGaist said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
This is wrong, self shall not be part of the arguments passed to the function called when using super.
super().init(parent=parent)That's what he said. I'm not sure enough about my Python to answer, maybe no harm in trying :)
It would be interesting to know if there is a PyQt6.5.0 and how it handles your existing code. You say it was working at 6.4.3, I don't know whether the PySide 6.5 is correct or not.
For the architecture of this particular logger case. Since you have to derive from
logging.Handler
, why don't you encapsulate theQPlainTextEdit
in your class instead of multiple-inheriting from it? My initial thought is that would be preferable. Then you would not multiple-inherit and you wouldn't have the current problem, whatever it is.wrote on 14 Apr 2023, 18:27 last edited by@JonB said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
For the architecture of this particular logger case. Since you have to derive from logging.Handler, why don't you encapsulate the QPlainTextEdit in your class instead of multiple-inheriting from it? My initial thought is that would be preferable. Then you would not multiple-inherit and you wouldn't have the current problem, whatever it is.
Finally I decided to encaplusate
logging.Handler
in my class and now I like it more than before :)
The bug was confirmed in PySide and to be corrected in future versions but everything works good without multiple inheritance.Also initial code was not ideal and was different from Qt recommendations.
So, with both things changed I have my code up and running again.
-
-
@JonB said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
For the architecture of this particular logger case. Since you have to derive from logging.Handler, why don't you encapsulate the QPlainTextEdit in your class instead of multiple-inheriting from it? My initial thought is that would be preferable. Then you would not multiple-inherit and you wouldn't have the current problem, whatever it is.
Finally I decided to encaplusate
logging.Handler
in my class and now I like it more than before :)
The bug was confirmed in PySide and to be corrected in future versions but everything works good without multiple inheritance.Also initial code was not ideal and was different from Qt recommendations.
So, with both things changed I have my code up and running again.
wrote on 14 Apr 2023, 18:32 last edited by JonB@StarterKit said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
Finally I decided to encaplusate
logging.Handler
in my class and now I like it more than before :)That is indeed the best, but earlier you said
But your handler should be a descendant of
logging.Handler
.Anyway, sounds good :)
-
@StarterKit said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
Finally I decided to encaplusate
logging.Handler
in my class and now I like it more than before :)That is indeed the best, but earlier you said
But your handler should be a descendant of
logging.Handler
.Anyway, sounds good :)
wrote on 16 Apr 2023, 10:19 last edited by@JonB said in TypeError with PySide 6.5.0 for multiple inheritance of MainWindow:
That is indeed the best, but earlier you said
I thought one more time about it and decided that there is a better desing option possible :) Not a big change but I moved 2 more methods inside my class and it looks good after all :)
-
wrote on 18 Apr 2023, 17:14 last edited by
We have hit this issue too. PySide 6.5.0 appears to use the signature of the last super-class that is initialised for both of them. The example we have is:
def __init__(self, rootDataModel, parent): super(QtCore.QObject, self).__init__(self) StateSource.__init__(self, parent, "model")
This results in a runtime error of:
QtCore.QObject.__init__(self) TypeError:__init__() missing 2 required positional arguments: 'parent' and 'name'
If I reverse the order of initialisation to:
def __init__(self, rootDataModel, parent): StateSource.__init__(self, parent, "model") super(QtCore.QObject, self).__init__(self)
Then the error reports that the
StateSource
initialiser only should have a single parameter. -
We have hit this issue too. PySide 6.5.0 appears to use the signature of the last super-class that is initialised for both of them. The example we have is:
def __init__(self, rootDataModel, parent): super(QtCore.QObject, self).__init__(self) StateSource.__init__(self, parent, "model")
This results in a runtime error of:
QtCore.QObject.__init__(self) TypeError:__init__() missing 2 required positional arguments: 'parent' and 'name'
If I reverse the order of initialisation to:
def __init__(self, rootDataModel, parent): StateSource.__init__(self, parent, "model") super(QtCore.QObject, self).__init__(self)
Then the error reports that the
StateSource
initialiser only should have a single parameter.wrote on 18 Apr 2023, 19:00 last edited byThis makes me think it's a new bug that has been introduced into the handling of multiple inheritance in PySide.
I don't know enough about the inner workings of PySide, perhaps someone on this forum can shed some light on it?
1/28