jenkins-bot has submitted this change. (
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1222701?usp=email )
Change subject: [IMPR] BaseSite.__getattr__: Use direct __code__ inspection for
performance
......................................................................
[IMPR] BaseSite.__getattr__: Use direct __code__ inspection for performance
Instead of inspect.signature(), __getattr__ now inspects the method's
__code__ object to determine the first parameter. This avoids expensive
generic callable introspection in this hot path. It is ~16× faster than
the old implementation; the overhead is only 60% against direct lookup.
Bug: T413398
Change-Id: Ib9cdf3884498de9d1624dfd5b9ef428116719959
---
M docs/api_ref/pywikibot.site.rst
M pywikibot/site/_basesite.py
2 files changed, 28 insertions(+), 9 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/docs/api_ref/pywikibot.site.rst b/docs/api_ref/pywikibot.site.rst
index 6fe32e4..bbacc29 100644
--- a/docs/api_ref/pywikibot.site.rst
+++ b/docs/api_ref/pywikibot.site.rst
@@ -18,6 +18,8 @@
.. automodule:: pywikibot.site._basesite
.. autoclass:: BaseSite
+ :members:
+ :special-members: __getattr__
.. method:: category_redirects(fallback: str = '_default')
diff --git a/pywikibot/site/_basesite.py b/pywikibot/site/_basesite.py
index 24bdcbe..d234f27 100644
--- a/pywikibot/site/_basesite.py
+++ b/pywikibot/site/_basesite.py
@@ -1,6 +1,6 @@
"""Objects with site methods independent of the communication interface."""
#
-# (C) Pywikibot team, 2008-2025
+# (C) Pywikibot team, 2008-2026
#
# Distributed under the terms of the MIT license.
#
@@ -185,21 +185,38 @@
def __getattr__(self, name: str):
"""Delegate undefined methods calls to the Family object.
+ Only public :class:`Family instance methods are delegated.
+
+ A method is considered delegatable if:
+ - it is a bound instance method of Family,
+ - it is public (name does not start with '_'),
+ - its first logical parameter is *code*.
+
+ .. note::
+ For performance reasons, the method signature is inspected
+ via the method's ``__code__`` object instead of
+ ``inspect.signature()``. This avoids expensive generic
+ introspection in this hot path and is safe because Family
+ methods are guaranteed to be pure Python.
+
.. versionchanged:: 9.0
Only delegate to public Family methods which have ``code`` as
first parameter.
+ .. versionchanged:: 11.0
+ Use direct ``__code__`` inspection instead of
+ ``inspect.signature()`` to significantly improve attribute
+ access performance.
"""
if not name.startswith('_'):
obj = getattr(self.family, name, None)
if inspect.ismethod(obj):
- params = inspect.signature(obj).parameters
- if params:
- parameter = next(iter(params))
- if parameter == 'code':
- method = functools.partial(obj, self.code)
- if hasattr(obj, '__doc__'):
- method.__doc__ = obj.__doc__
- return method
+ code = obj.__code__
+ params = code.co_varnames[:code.co_argcount]
+ if len(params) > 1 and params[1] == 'code':
+ method = functools.partial(obj, self.code)
+ if hasattr(obj, '__doc__'):
+ method.__doc__ = obj.__doc__
+ return method
raise AttributeError(f'{type(self).__name__} instance has no '
f'attribute {name!r}') from None
--
To view, visit
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1222701?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ib9cdf3884498de9d1624dfd5b9ef428116719959
Gerrit-Change-Number: 1222701
Gerrit-PatchSet: 3
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: Matěj Suchánek <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]