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]

Reply via email to