-
-
Notifications
You must be signed in to change notification settings - Fork 31k
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
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,7 @@ _Py_IDENTIFIER(__subclasshook__); | |
negative cache to be cleared before its next use. | ||
Note: this counter is private. Use `abc.get_cache_token()` for | ||
external code. */ | ||
static PyObject *abc_invalidation_counter; | ||
static unsigned long long abc_invalidation_counter = 0; | ||
|
||
/* This object stores internal state for ABCs. | ||
Note that we can use normal sets for caches, | ||
|
@@ -35,7 +35,7 @@ typedef struct { | |
PyObject *_abc_registry; | ||
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. All of registry, cache, and negative cache are normal sets of weak references; there should be comments stating that for either all of none of them |
||
PyObject *_abc_cache; /* Normal set of weak references. */ | ||
PyObject *_abc_negative_cache; /* Normal set of weak references. */ | ||
PyObject *_abc_negative_cache_version; | ||
unsigned long long _abc_negative_cache_version; | ||
} _abc_data; | ||
|
||
static void | ||
|
@@ -44,7 +44,6 @@ abc_data_dealloc(_abc_data *self) | |
Py_XDECREF(self->_abc_registry); | ||
Py_XDECREF(self->_abc_cache); | ||
Py_XDECREF(self->_abc_negative_cache); | ||
Py_DECREF(self->_abc_negative_cache_version); | ||
Py_TYPE(self)->tp_free(self); | ||
} | ||
|
||
|
@@ -60,7 +59,6 @@ abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
self->_abc_cache = NULL; | ||
self->_abc_negative_cache = NULL; | ||
self->_abc_negative_cache_version = abc_invalidation_counter; | ||
Py_INCREF(abc_invalidation_counter); | ||
return (PyObject *) self; | ||
} | ||
|
||
|
@@ -239,7 +237,7 @@ static PyObject * | |
_abc__get_dump(PyObject *module, PyObject *self) | ||
/*[clinic end generated code: output=9d9569a8e2c1c443 input=2c5deb1bfe9e3c79]*/ | ||
{ | ||
PyObject *registry, *cache, *negative_cache; | ||
PyObject *registry, *cache, *negative_cache, *cache_version; | ||
_abc_data *impl = _get_impl(self); | ||
if (impl == NULL) { | ||
return NULL; | ||
|
@@ -262,13 +260,19 @@ _abc__get_dump(PyObject *module, PyObject *self) | |
Py_DECREF(cache); | ||
return NULL; | ||
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. Add |
||
} | ||
Py_INCREF(impl->_abc_negative_cache_version); /* PyTuple_Pack doesn't do this. */ | ||
PyObject *res = PyTuple_Pack(4, | ||
registry, cache, negative_cache, impl->_abc_negative_cache_version); | ||
cache_version = PyLong_FromUnsignedLongLong(impl->_abc_negative_cache_version); | ||
if (cache_version == NULL) { | ||
Py_DECREF(impl); | ||
Py_DECREF(registry); | ||
Py_DECREF(cache); | ||
Py_DECREF(negative_cache); | ||
return NULL; | ||
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. Add |
||
} | ||
PyObject *res = PyTuple_Pack(4, registry, cache, negative_cache, cache_version); | ||
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 could be written simpler as: PyObject *res = Py_BuildValue("NNNK",
PySet_New(impl->_abc_registry),
PySet_New(impl->_abc_cache),
PySet_New(impl->_abc_negative_cache),
impl->_abc_negative_cache_version); |
||
Py_DECREF(registry); | ||
Py_DECREF(cache); | ||
Py_DECREF(negative_cache); | ||
Py_DECREF(impl->_abc_negative_cache_version); | ||
Py_DECREF(cache_version); | ||
Py_DECREF(impl); | ||
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. Add all remaining decrefs |
||
return res; | ||
} | ||
|
@@ -475,16 +479,7 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) | |
Py_DECREF(impl); | ||
|
||
/* Invalidate negative cache */ | ||
PyObject *one = PyLong_FromLong(1); | ||
if (one == NULL) { | ||
return NULL; | ||
} | ||
PyObject *next_version = PyNumber_Add(abc_invalidation_counter, one); | ||
Py_DECREF(one); | ||
if (next_version == NULL) { | ||
return NULL; | ||
} | ||
Py_SETREF(abc_invalidation_counter, next_version); | ||
abc_invalidation_counter++; | ||
|
||
Py_INCREF(subclass); | ||
return subclass; | ||
|
@@ -525,11 +520,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, | |
} | ||
subtype = (PyObject *)Py_TYPE(instance); | ||
if (subtype == subclass) { | ||
int r = PyObject_RichCompareBool( | ||
impl->_abc_negative_cache_version, | ||
abc_invalidation_counter, Py_EQ); | ||
assert(r >= 0); // Both should be PyLong | ||
if (r > 0) { | ||
if (impl->_abc_negative_cache_version == abc_invalidation_counter) { | ||
incache = _in_weak_set(impl->_abc_negative_cache, subclass); | ||
if (incache < 0) { | ||
goto end; | ||
|
@@ -614,19 +605,13 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, | |
} | ||
|
||
/* 2. Check negative cache; may have to invalidate. */ | ||
int r = PyObject_RichCompareBool(impl->_abc_negative_cache_version, | ||
abc_invalidation_counter, Py_LT); | ||
assert(r >= 0); // Both should be PyLong | ||
if (r > 0) { | ||
if (impl->_abc_negative_cache_version < abc_invalidation_counter) { | ||
/* Invalidate the negative cache. */ | ||
if (impl->_abc_negative_cache != NULL && | ||
PySet_Clear(impl->_abc_negative_cache) < 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. PEP 7 requires |
||
goto end; | ||
} | ||
/* INCREF the new value of cache version, | ||
then carefully DECREF the old one. */ | ||
Py_INCREF(abc_invalidation_counter); | ||
Py_SETREF(impl->_abc_negative_cache_version, abc_invalidation_counter); | ||
impl->_abc_negative_cache_version = abc_invalidation_counter; | ||
} | ||
else { | ||
incache = _in_weak_set(impl->_abc_negative_cache, subclass); | ||
|
@@ -811,8 +796,7 @@ static PyObject * | |
_abc_get_cache_token_impl(PyObject *module) | ||
/*[clinic end generated code: output=c7d87841e033dacc input=1d49ab7218687f59]*/ | ||
{ | ||
Py_INCREF(abc_invalidation_counter); | ||
return abc_invalidation_counter; | ||
return PyLong_FromUnsignedLongLong(abc_invalidation_counter); | ||
} | ||
|
||
static struct PyMethodDef module_functions[] = { | ||
|
@@ -848,6 +832,5 @@ PyInit__abc(void) | |
} | ||
_abc_data_type.tp_doc = abc_data_doc; | ||
|
||
abc_invalidation_counter = PyLong_FromLong(0); | ||
return PyModule_Create(&_abcmodule); | ||
} |
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 comment is out of date