Skip to content

gh-92810: Reduce memory usage by ABCMeta.__subclasscheck__ #131914

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

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
675bec5
gh-92810: Avoid O(n^2) complexity in ABCMeta.__subclasscheck__
dolfinus Mar 30, 2025
701ecc9
gh-92810: Apply fixes
dolfinus Mar 31, 2025
041f109
gh-92810: Apply fixes
dolfinus Mar 31, 2025
9bc4385
gh-92810: Apply fixes
dolfinus Mar 31, 2025
3d80b1e
gh-92810: Apply fixes
dolfinus Mar 31, 2025
b7603e0
gh-92810: Return __subclasses__clause back
dolfinus Apr 21, 2025
dd0d18c
gh-92810: Revert _abc.c changes
dolfinus Apr 21, 2025
8d695fd
gh-92810: Fix linter errors
dolfinus Apr 21, 2025
a2650b6
gh-92810: Add recursive issubclass check to _abc.c
dolfinus Jun 13, 2025
7afa5ea
gh-92810: Remove WeakKeyDictionary from _py_abc
dolfinus Jun 13, 2025
57980d3
gh-92810: Add news entry
dolfinus Jun 13, 2025
bbaf38a
gh-92810: Fix news entry
dolfinus Jun 13, 2025
6fc994d
gh-92810: Fixes after review
dolfinus Jun 22, 2025
b3b5895
gh-92810: Fixes after review
dolfinus Jun 22, 2025
69c5038
gh-92810: Fixes after review
dolfinus Jun 23, 2025
dc1b6d5
gh-92810: Fixes after review
dolfinus Jun 23, 2025
cd097ab
gh-92810: Introduce FT wrappers for uint64_t atomics
dolfinus Jun 23, 2025
f3a21a7
gh-92810: Use FT atomic wrappers for ABC invalidation counter
dolfinus Jun 23, 2025
e24e815
gh-92810: Fix missing FT wrapper
dolfinus Jun 23, 2025
b723912
gh-92810: Address review fixes
dolfinus Aug 4, 2025
0295846
Merge branch 'main' into improvement/ABCMeta_subclasscheck
dolfinus Aug 4, 2025
16f39bd
gh-92810: Address review fixes
dolfinus Aug 4, 2025
2dc6453
gh-92810: Add What's New entry
dolfinus Aug 4, 2025
968766d
gh-92810: Fix What's New entry syntax
dolfinus Aug 4, 2025
a6e4461
gh-92810: Address review fixes
dolfinus Aug 4, 2025
80d3281
gh-92810: Address review fixes
dolfinus Aug 4, 2025
ff38b9e
gh-92810: Properly reset recursion check
dolfinus Aug 4, 2025
23df287
Merge branch 'main' into improvement/ABCMeta_subclasscheck
dolfinus Aug 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
gh-92810: Revert _abc.c changes
  • Loading branch information
dolfinus committed Apr 21, 2025
commit dd0d18ccf6a4edd67418d0ef918fa791a57d29cb
50 changes: 1 addition & 49 deletions Modules/_abc.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,50 +590,6 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
}
Py_DECREF(impl);

/* Recursively register the subclass in all ABC bases, to avoid recursive lookups.
>>> class Ancestor1(ABC): pass
>>> class Ancestor2(Ancestor1): pass
>>> class Other: pass
>>> Ancestor2.register(Other) # same result for Ancestor1.register(Other)
>>> issubclass(Other, Ancestor2) is True
>>> issubclass(Other, Ancestor1) is True
*/
PyObject *mro = PyObject_GetAttrString(self, "__mro__");
if (mro == NULL) {
return NULL;
}

if (!PyTuple_CheckExact(mro)) {
PyErr_SetString(PyExc_TypeError, "__mro__ must be an exact tuple");
goto error;
}

for (Py_ssize_t pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) {
PyObject *base_class = PyTuple_GET_ITEM(mro, pos); // borrowed
PyObject *base_class_data;

if (PyObject_GetOptionalAttr(base_class,
&_Py_ID(_abc_impl),
&base_class_data) < 0)
{
goto error;
}

if (base_class_data == NULL) {
// not ABC class
continue;
}

_abc_data *base_class_state = _abc_data_CAST(base_class_data);
int res = _add_to_weak_set(base_class_state,
&base_class_state->_abc_registry,
subclass);
Py_DECREF(base_class_data);
if (res < 0) {
goto error;
}
}

/* Invalidate negative cache */
increment_invalidation_counter(get_abc_state(module));

Expand All @@ -648,10 +604,6 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
}
}
return Py_NewRef(subclass);

error:
Py_XDECREF(mro);
return NULL;
}


Expand Down Expand Up @@ -878,7 +830,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
}
}

/* Recursive calls lead to uncontrolled negative cache growth, avoid this */
/* No dice; update negative cache. */
if (_add_to_weak_set(impl, &impl->_abc_negative_cache, subclass) < 0) {
goto end;
}
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy