Commit fa775e2c authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix optimization that is wrong for abstract classes

We fast-pathed "type has __init__ but not __new__" by saying
that the default __new__ would always succeed, but this isn't true for abstract classes.
parent 8e739ffc
......@@ -1097,7 +1097,8 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
}
if (rewrite_args) {
if (cls->tp_new == object_cls->tp_new && cls->tp_init != object_cls->tp_init) {
if (cls->tp_new == object_cls->tp_new && cls->tp_init != object_cls->tp_init
&& !(cls->tp_flags & Py_TPFLAGS_IS_ABSTRACT)) {
// Fast case: if we are calling object_new, we normally doesn't look at the arguments at all.
// (Except in the case when init_attr != object_init, in which case object_new looks at the number
// of arguments and throws an exception.)
......@@ -1143,7 +1144,8 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
}
}
} else {
if (cls->tp_new == object_cls->tp_new && cls->tp_init != object_cls->tp_init) {
if (cls->tp_new == object_cls->tp_new && cls->tp_init != object_cls->tp_init
&& !(cls->tp_flags & Py_TPFLAGS_IS_ABSTRACT)) {
made = objectNewNoArgs(cls);
assert(made);
} else
......
from abc import ABCMeta, abstractmethod
class C(object):
__metaclass__ = ABCMeta
@abstractmethod
def foo(self):
pass
try:
C()
assert 0
except TypeError as e:
print e
def c_init(self):
pass
C.__init__ = c_init
try:
C()
assert 0
except TypeError as e:
print e
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment