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: abstract class instantiable when subclassing built-in types
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.10, Python 3.9, Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: 2xB, Jim Fasarakis-Hilliard, Jon McMahon, Kevin Shweh, Nathaniel Manista, aleax, benjamin.peterson, cvrebert, daniel.urban, eltoder, eric.araujo, eric.snow, josh.r, jwilk, luiz.poleto, maciej.szulik, nadeem.vawda, pitrou, r.david.murray, remi.lapeyre, rhettinger, terry.reedy, thet, xiang.zhang
Priority: low Keywords: patch

Created on 2009-05-11 14:06 by thet, last changed 2022-04-11 14:56 by admin.

Files
File name Uploaded Description Edit
abc.patch eltoder, 2011-04-10 02:28 review
Messages (16)
msg87574 - (view) Author: Johannes Raggam (thet) Date: 2009-05-11 14:06
when declaring a abstract base class with an abstract property or method
and subclassing from dict, the class is instantiable (instanceable?).

>>> import abc
>>> class A(object):
...     __metaclass__ = abc.ABCMeta
...     @abc.abstractproperty
...     def abstract(self): return True
... 
>>> a = A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class A with abstract methods abstract
>>> 
>>> class A2(dict):
...     __metaclass__ = abc.ABCMeta
...     @abc.abstractproperty
...     def abstract(self): return True
... 
>>> a2 = A2()
>>> 


although, when using the dict definition from __builtin__.pi directly,
the abc behaves like expected. but this may be a bug in the
c-implementation from dict.

platform:
Python 2.6.2 (r262:71600, Apr 25 2009, 21:56:41) 
[GCC 4.3.2] on linux2
msg87576 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-05-11 14:56
Also happens with other builtin types such as tuple. It's probably
related to the way subclasses of those types are instantiated, bypassing
the normal metaclass mechanism.
msg87854 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2009-05-16 03:47
I presume you claim the dict example to be a bug in relation to "A class
that has a metaclass derived from ABCMeta cannot be instantiated unless
all of its abstract methods and properties are overridden."

There is the same difference with @abstractproperty
Windows, 3.0.1

class C(metaclass=abc.ABCMeta):
	@abc.abstractmethod
	def f(self): return True

class C2(dict,metaclass=abc.ABCMeta):
	@abc.abstractmethod
	def f(self): return True

c2=C2()
print(c2.f())

c=C()
# prints
True
...
TypeError: Can't instantiate abstract class C with abstract methods f
msg113698 - (view) Author: Daniel Urban (daniel.urban) * (Python triager) Date: 2010-08-12 18:52
I think, that the reason is that, object.__new__ checks, if the class is instantiable (object_new in Objects/typeobject.c ). dict.__new__ (and tuple.__new__, and I guess the __new__ method of other built-in types) doesn't call object.__new__, but user defined types typically either doesn't have a __new__, or call object.__new__ from it (directly or with super).
msg133440 - (view) Author: Eugene Toder (eltoder) * Date: 2011-04-10 02:28
This patch fixes the problem by moving the check from object_new to PyType_GenericAlloc. The check is very cheap, so this should not be an issue.
msg138411 - (view) Author: Eugene Toder (eltoder) * Date: 2011-06-16 02:59
Anyone has any thoughts on this?
msg140108 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2011-07-11 11:28
IIRC, classes weren't supposed to be able inherit from two classes that had different metaclasses (since differing metaclasses don't necessarily play well with one another).
msg140114 - (view) Author: Eugene Toder (eltoder) * Date: 2011-07-11 12:35
They are, when there's a most specific metaclass -- the one which is a subclass of all others (described here http://www.python.org/download/releases/2.2.3/descrintro/#metaclasses, implemented here http://hg.python.org/cpython/file/ab162f925761/Objects/typeobject.c#l1956). Since ABCMeta is a subclass of type this holds.

Also, in the original example there's no multiple inheritance at all.
msg266704 - (view) Author: Xiang Zhang (xiang.zhang) * (Python committer) Date: 2016-05-30 16:21
I think subclassing builtin types and making it abstract is rare. And when there is a need, we can mimic this in application level (this may also apply to types having custom __new__):

In [2]: class CustomDict(dict, metaclass=abc.ABCMeta):
   ...:     def __new__(cls, *args, **kwargs):
   ...:         if getattr(cls, '__abstractmethods__', None):
   ...:             raise TypeError
   ...:         return super().__new__(cls, *args, **kwargs)
   ...:     @abc.abstractmethod
   ...:     def f(self):
   ...:         pass

Adding the abstract class checking in tp_alloc or builtin types' tp_new maybe degrade performance.

Is it necessary to add this support?
msg279479 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-10-26 01:45
Honestly let's just forget about this.
msg279481 - (view) Author: Nathaniel Manista (Nathaniel Manista) Date: 2016-10-26 02:00
Wait, really? My report came out of a real bug that I had in my system and shipped to my users; it wasn't academic or contrived at all.
msg279483 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-10-26 02:14
Where did you report that? I don't see your name on this bug -- it has a patch that's been unapplied for 5 years, so I doubt it's very important.
msg279484 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-10-26 02:17
Oh sorry. I received the emails in a strange order. I guess it can stay open.
msg279499 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-10-26 13:44
My apologies, I added Nathaniel to nosy here when I closed the duplicate, but forgot to add a link to the closed issue: issue 28537.
msg299815 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-08-06 21:40
Closed issue 31127 as a duplicate of this one.
msg335337 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2019-02-12 17:26
Closed #35958 as a duplicate of this issue (and updated the title, since clearly the problem is not specific to dict).

Patch probably needs to be rebased/rewritten against latest trunk (given it dates from Mercurial days).
History
Date User Action Args
2022-04-11 14:56:48adminsetgithub: 50246
2020-10-30 23:49:27iritkatrielsetversions: + Python 3.9, Python 3.10, - Python 3.1, Python 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5, Python 3.6, Python 3.7
2020-05-01 18:27:37Jim Fasarakis-Hilliardsetnosy: + Jim Fasarakis-Hilliard
2020-02-23 13:08:03mark.dickinsonsetnosy: - mark.dickinson
2020-02-13 16:51:322xBsetnosy: + 2xB
2019-02-25 23:32:20cheryl.sabellalinkissue24235 superseder
2019-02-12 18:02:57gvanrossumsetnosy: - gvanrossum
2019-02-12 17:30:26remi.lapeyresetnosy: + remi.lapeyre
2019-02-12 17:26:58josh.rsetnosy: + josh.r, Jon McMahon
title: abstract class instantiable when subclassing dict -> abstract class instantiable when subclassing built-in types
messages: + msg335337

versions: + Python 3.5, Python 3.6, Python 3.7, Python 3.8
stage: patch review
2019-02-12 17:23:38josh.rlinkissue35958 superseder
2017-08-06 21:40:29r.david.murraysetnosy: + Kevin Shweh
messages: + msg299815
2017-08-06 21:39:14r.david.murraylinkissue31127 superseder
2017-02-26 08:06:38serhiy.storchakaunlinkissue29650 dependencies
2017-02-26 08:06:38serhiy.storchakalinkissue29650 superseder
2017-02-26 07:49:41xiang.zhanglinkissue29650 dependencies
2016-10-26 13:44:05r.david.murraysetnosy: + r.david.murray
messages: + msg279499
2016-10-26 02:17:05gvanrossumsetstatus: closed -> open
resolution: wont fix ->
messages: + msg279484
2016-10-26 02:14:51gvanrossumsetmessages: + msg279483
2016-10-26 02:00:19Nathaniel Manistasetmessages: + msg279481
2016-10-26 01:45:41gvanrossumsetstatus: open -> closed
resolution: wont fix
messages: + msg279479
2016-10-26 00:45:23r.david.murraysetnosy: + aleax, cvrebert, Nathaniel Manista
2016-10-26 00:44:33r.david.murraylinkissue28537 superseder
2016-06-01 02:40:48luiz.poletosetnosy: + luiz.poleto
2016-05-30 16:21:46xiang.zhangsetnosy: + gvanrossum
messages: + msg266704
2016-05-26 15:36:31rhettingersetassignee: rhettinger ->
2016-05-26 14:01:32xiang.zhangsetnosy: + xiang.zhang
2016-05-25 13:21:58maciej.szuliksetnosy: + maciej.szulik
2016-05-25 13:19:26r.david.murraylinkissue26306 superseder
2013-12-10 12:19:04jwilksetnosy: + jwilk
2013-12-07 15:03:45mark.dickinsonsetversions: + Python 3.4
2013-12-07 15:00:20mark.dickinsonsetnosy: + mark.dickinson
2011-07-11 13:04:39rhettingersetpriority: normal -> low
assignee: rhettinger
2011-07-11 12:35:43eltodersetmessages: + msg140114
2011-07-11 11:28:59rhettingersetnosy: + rhettinger
messages: + msg140108
2011-07-09 20:52:20eric.snowsetnosy: + eric.snow
2011-06-16 02:59:50eltodersetmessages: + msg138411
2011-04-10 02:28:38eltodersetfiles: + abc.patch

nosy: + eltoder
messages: + msg133440

keywords: + patch
2011-04-08 15:27:03eric.araujosetnosy: + eric.araujo

versions: + Python 3.3, - Python 2.6
2011-04-08 08:33:43nadeem.vawdasetnosy: + nadeem.vawda
2010-08-14 22:00:18pitrousetnosy: + benjamin.peterson
2010-08-12 18:52:21daniel.urbansetnosy: + daniel.urban
messages: + msg113698
2009-05-16 03:47:20terry.reedysetnosy: + terry.reedy
messages: + msg87854
2009-05-11 14:56:50pitrousetpriority: normal
versions: + Python 3.1, Python 2.7, Python 3.2
nosy: + pitrou

messages: + msg87576
2009-05-11 14:06:01thetcreate