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: __or__ et al instantiate subclass of set without calling __init__
Type: behavior Stage:
Components: Versions: Python 2.7
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: Robert.Burke, mark.dickinson, rhettinger, santoso.wijaya, stutzbach
Priority: normal Keywords:

Created on 2011-04-16 05:29 by Robert.Burke, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
demo Robert.Burke, 2011-04-16 05:29 Demonstration of the issue in Python REPL
Messages (7)
msg133880 - (view) Author: Robert Burke (Robert.Burke) Date: 2011-04-16 05:29
If you create a subclass of set but do not override __or__, __and__, __xor__, and __sub__, calling these functions will yield a new instance of your subclass.  The new instance will never have __init__ called on it.  Depending on what you expect __init__ to do, this can cause problems later on.

The simplest solution would be to make these functions work like list.__add__.  If you have two instances of some list subclass (foo and bar), type(foo.__add__(bar)) will just be list.
msg133903 - (view) Author: Santoso Wijaya (santoso.wijaya) * Date: 2011-04-16 19:21
Python 2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class SetSub(set):
...     def __init__(self, *args, **kwargs):
...             print 'foo'
...             set.__init__(self, *args, **kwargs)
...
>>> a = SetSub([2,7])
foo
>>> b = set([1,7])
>>> a ^ b
SetSub([1, 2])


Python 3.2 (r32:88445, Feb 20 2011, 21:30:00) [MSC v.1500 64 bit (AMD64)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> class SetSub(set):
...     def __init__(self, *args, **kwargs):
...             print('foo')
...             set.__init__(self, *args, **kwargs)
...
>>> a = SetSub([2,7])
foo
>>> b = set([1,7])
>>> a ^ b
{1, 2}
msg133911 - (view) Author: Robert Burke (Robert.Burke) Date: 2011-04-16 23:37
I've only observed this in 2.6.  Does 2.6 not belong in the bug's versions list if 2.7 is also affected?
msg133917 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2011-04-17 02:33
2.6 is closed for anything except security patches at this point.

2.7 is only open for flat-out bugs, not API changes.  So, we might be able to add code that could call the __init__ method (if it exists) whenever a new set is created, but we couldn't change whether __or__ returns a new set or frozenset instead of one of its subtypes.  Existing, working code may reasonably rely on the current behavior of returning the subtype (FWIW, this also matches what was done in the original sets.py).
msg133919 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2011-04-17 04:15
If some code were added to call __init__ for the new instance of a set/frozenset subclass, it would have to make an assumption that the method's signature allowed it to be called without any arguments.
msg203585 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2013-11-21 08:34
Can this issue be closed as 'wont fix'?
msg204790 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2013-11-30 09:07
Closing.  This isn't likely to change in Python 2.7.
History
Date User Action Args
2022-04-11 14:57:16adminsetgithub: 56063
2013-11-30 09:07:48mark.dickinsonsetstatus: open -> closed
resolution: wont fix
messages: + msg204790
2013-11-21 08:34:50mark.dickinsonsetnosy: + mark.dickinson
messages: + msg203585
2011-04-17 04:15:29rhettingersetmessages: + msg133919
2011-04-17 02:33:32rhettingersetmessages: + msg133917
2011-04-16 23:37:53Robert.Burkesetmessages: + msg133911
2011-04-16 19:22:48santoso.wijayasetversions: - Python 3.1, Python 3.2, Python 3.3
2011-04-16 19:21:39santoso.wijayasetnosy: + santoso.wijaya

messages: + msg133903
versions: + Python 3.1, Python 2.7, Python 3.2, Python 3.3, - Python 2.6
2011-04-16 17:18:16stutzbachsetnosy: + stutzbach
2011-04-16 06:18:47rhettingersetassignee: rhettinger

nosy: + rhettinger
2011-04-16 05:35:06Robert.Burkesettitle: __or__, __and__, __sub__, and __xor__ instantiate subclass of set without calling __init__ -> __or__ et al instantiate subclass of set without calling __init__
2011-04-16 05:29:53Robert.Burkecreate