This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: super().__new__() of list expands arguments
Type: behavior Stage: resolved
Components: ctypes Versions: Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: conqp, serhiy.storchaka
Priority: normal Keywords:

Created on 2020-12-28 16:23 by conqp, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg383902 - (view) Author: Richard Neumann (conqp) * Date: 2020-12-28 16:23
When sublassing the built-in list, the invocation of super().__new__ will unexpectedly expand the passed arguments:

class MyTuple(tuple):

    def __new__(cls, *items):
        print(cls, items)
        return super().__new__(cls, items)


class MyList(list):

    def __new__(cls, *items):
        print(cls, items)
        return super().__new__(cls, items)


def main():

    my_tuple = MyTuple(1, 2, 3, 'foo', 'bar')
    print('My tuple:', my_tuple)
    my_list = MyList(1, 2, 3, 'foo', 'bar')
    print('My list:', my_list)


if __name__ == '__main__':
    main()


Actual result:

<class '__main__.MyTuple'> (1, 2, 3, 'foo', 'bar')
My tuple: (1, 2, 3, 'foo', 'bar')
<class '__main__.MyList'> (1, 2, 3, 'foo', 'bar')
Traceback (most recent call last):
  File "/home/neumann/listbug.py", line 24, in <module>
    main()
  File "/home/neumann/listbug.py", line 19, in main
    my_list = MyList(1, 2, 3, 'foo', 'bar')
TypeError: list expected at most 1 argument, got 5


Expected:

<class '__main__.MyTuple'> (1, 2, 3, 'foo', 'bar')
My tuple: (1, 2, 3, 'foo', 'bar')
<class '__main__.MyList'> (1, 2, 3, 'foo', 'bar')
My list: [1, 2, 3, 'foo', 'bar']
msg383905 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-12-28 16:46
Your problem is with list.__init__ method. It expects at most one argument.

tuple does not have specialized __init__ method, it inherits it from object. All work is done in tuple.__new__. list does not have specialized __new__ method, it inherits it from object. All work is done in list.__init__.

If your override __new__ with incompatible signature, make also __init__ supporting it.
msg383907 - (view) Author: Richard Neumann (conqp) * Date: 2020-12-28 17:27
I could have sworn, that this worked before, but it was obviously me being tired at the end of the work day.
Thanks for pointing this out and sorry for the noise.
History
Date User Action Args
2022-04-11 14:59:39adminsetgithub: 86934
2020-12-28 17:27:55conqpsetmessages: + msg383907
2020-12-28 16:46:33serhiy.storchakasetstatus: open -> closed

nosy: + serhiy.storchaka
messages: + msg383905

resolution: not a bug
stage: resolved
2020-12-28 16:23:51conqpcreate