-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-31333: Re-implement ABCMeta in C #5273
Changes from 1 commit
5c34508
cb7ffcf
b83ee80
181e83f
c084a7f
a192d5d
35a2472
4812450
b9038e2
bbee578
a3464fd
947bf7d
7ffc59e
41287a7
569cc44
34665a8
576acac
30098b4
51ede5d
5263e1a
1f7aee9
11fea70
7ff3fbb
9b4eb2f
ab20a33
39f2692
493d0ec
2fe2c54
9476af6
ab68cdb
3eb0a60
ed36b76
25fc5b9
b2f75b9
cdb5cdf
a1a3a52
a66b08c
86af9ae
b22232a
e51c5ca
bac7a43
4571649
0d7513b
c429f49
357b56d
cd80fcb
34e13c3
c5633b6
3cbbc12
23bcb07
0aab479
86e0660
c55e482
5f9526a
8174b61
bb8d623
ef59e54
22699fe
95cbf34
4d596cc
fa3cba3
6f18293
9100891
36c5643
dd2abda
99d950c
3762d49
404d1ce
0dc5fae
287b26a
ef34364
d4d78a1
f58822e
3b74bdc
db1c852
6e62be7
5384726
a48eecc
16a8db1
5ad3ea8
86a9b8d
36c2013
09c5370
207d8e9
a15377b
d31da13
eaff1cb
48de70e
3bd0666
702347a
e0c978b
b370dfe
a1ae0a7
4746211
001b416
fc528df
289c414
ac0c639
079e3be
9c49e5a
4146588
c133605
f82e04d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -269,6 +269,7 @@ _destroy(PyObject *setweakref, PyObject *objweakref) | |
Py_RETURN_NONE; | ||
Py_INCREF(set); | ||
if (PySet_Discard(set, objweakref) < 0) { | ||
Py_DECREF(set); | ||
return NULL; | ||
} | ||
Py_DECREF(set); | ||
|
@@ -299,6 +300,7 @@ _destroy_guarded(PyObject *setweakref, PyObject *objweakref) | |
} | ||
} else { | ||
if (PySet_Discard(gset->data, objweakref) < 0) { | ||
Py_DECREF(set); | ||
return NULL; | ||
} | ||
} | ||
|
@@ -326,14 +328,19 @@ _add_to_weak_set(PyObject *set, PyObject *obj, int guarded) | |
} | ||
ref = PyWeakref_NewRef(obj, destroy_cb); | ||
if (!ref) { | ||
Py_DECREF(wr); | ||
return 0; | ||
} | ||
if (guarded) { | ||
set = ((_guarded_set *) set)->data; | ||
} | ||
if (PySet_Add(set, ref) < 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This way it would be a bit more concise: int ret = PySet_Add(set, ref);
Py_DECREF(wr);
Py_DECREF(ref);
return ret; |
||
Py_DECREF(wr); | ||
Py_DECREF(ref); | ||
return 0; | ||
} | ||
Py_DECREF(wr); | ||
Py_DECREF(ref); | ||
return 1; | ||
} | ||
|
||
|
@@ -392,9 +399,11 @@ _exit_iter(PyObject *self) | |
return 0; | ||
} | ||
if (PySet_Discard(registry->data, ref) < 0) { | ||
Py_DECREF(ref); | ||
Py_DECREF(impl); | ||
return 0; | ||
} | ||
Py_DECREF(ref); | ||
} | ||
Py_DECREF(impl); | ||
return 1; | ||
|
@@ -506,6 +515,7 @@ _reset_caches(PyObject *m, PyObject *args) | |
Py_DECREF(impl); | ||
return NULL; | ||
} | ||
Py_DECREF(impl); | ||
Py_RETURN_NONE; | ||
} | ||
|
||
|
@@ -740,7 +750,7 @@ PyDoc_STRVAR(_abc_register_doc, | |
static PyObject * | ||
_abc_register(PyObject *m, PyObject *args) | ||
{ | ||
PyObject *self, *subclass = NULL; | ||
PyObject *self, *one, *subclass = NULL; | ||
int result; | ||
if (!PyArg_UnpackTuple(args, "_abc_register", 2, 2, &self, &subclass)) { | ||
return NULL; | ||
|
@@ -774,7 +784,9 @@ _abc_register(PyObject *m, PyObject *args) | |
Py_INCREF(subclass); | ||
/* Invalidate negative cache */ | ||
Py_DECREF(abc_invalidation_counter); | ||
abc_invalidation_counter = PyNumber_Add(abc_invalidation_counter, PyLong_FromLong(1)); | ||
one = PyLong_FromLong(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check that |
||
abc_invalidation_counter = PyNumber_Add(abc_invalidation_counter, one); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check that |
||
Py_DECREF(one); | ||
return subclass; | ||
} | ||
|
||
|
@@ -793,32 +805,41 @@ _abc_instancecheck(PyObject *m, PyObject *args) | |
/* Inline the cache checking. */ | ||
incache = _in_cache(self, subclass); | ||
if (incache < 0) { | ||
Py_DECREF(subclass); | ||
return NULL; | ||
} | ||
if (incache > 0) { | ||
Py_DECREF(subclass); | ||
Py_RETURN_TRUE; | ||
} | ||
subtype = (PyObject *)Py_TYPE(instance); | ||
if (subtype == subclass) { | ||
incache = _in_negative_cache(self, subclass); | ||
if (incache < 0) { | ||
Py_DECREF(subclass); | ||
return NULL; | ||
} | ||
if ((PyObject_RichCompareBool(_get_negative_cache_version(self), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
abc_invalidation_counter, Py_EQ) > 0) && incache) { | ||
Py_DECREF(subclass); | ||
Py_RETURN_FALSE; | ||
} | ||
/* Fall back to the subclass check. */ | ||
return PyObject_CallMethod(self, "__subclasscheck__", "O", subclass); | ||
result = PyObject_CallMethod(self, "__subclasscheck__", "O", subclass); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd use _Py_IDENTIFIER(__subclasscheck__);
result = _PyObject_CallMethodIdObjArgs(
self, &PyId___subclasscheck__", subclass, NULL); It's also faster. |
||
Py_DECREF(subclass); | ||
return result; | ||
} | ||
result = PyObject_CallMethod(self, "__subclasscheck__", "O", subclass); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto, _PyObject_CallMethodIdObjArgs |
||
if (!result) { | ||
Py_DECREF(subclass); | ||
return NULL; | ||
} | ||
if (result == Py_True) { | ||
Py_DECREF(subclass); | ||
return Py_True; | ||
} | ||
Py_DECREF(result); | ||
Py_DECREF(subclass); | ||
return PyObject_CallMethod(self, "__subclasscheck__", "O", subtype); | ||
} | ||
|
||
|
@@ -904,7 +925,9 @@ _abc_subclasscheck(PyObject *m, PyObject *args) | |
/* 5. Check if it's a subclass of a registered class (recursive). */ | ||
pos = 0; | ||
Py_hash_t hash; | ||
_enter_iter(self); | ||
if (!_enter_iter(self)) { | ||
return NULL; | ||
} | ||
while (_PySet_NextEntry(_get_registry(self), &pos, &key, &hash)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The result of |
||
rkey = PyWeakref_GetObject(key); | ||
if (rkey == Py_None) { | ||
|
@@ -920,11 +943,15 @@ _abc_subclasscheck(PyObject *m, PyObject *args) | |
_exit_iter(self); | ||
return NULL; | ||
} | ||
_exit_iter(self); | ||
if (!_exit_iter(self)) { | ||
return NULL; | ||
} | ||
Py_RETURN_TRUE; | ||
} | ||
} | ||
_exit_iter(self); | ||
if (!_exit_iter(self)) { | ||
return NULL; | ||
} | ||
|
||
/* 6. Check if it's a subclass of a subclass (recursive). */ | ||
subclasses = PyObject_CallMethod(self, "__subclasses__", NULL); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This entire for loop now does nothing