Skip to content

Commit 1e9dfae

Browse files
committed
MAINT: re-enable monkeypatch circumvention
1 parent dbd78b2 commit 1e9dfae

1 file changed

Lines changed: 17 additions & 0 deletions

File tree

src/array_api_extra/testing.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ def test_myfunc(xp):
238238
raw_attr = getattr_static(cls, method_name)
239239
method = getattr(cls, method_name)
240240
cloned_method = _clone_function(method)
241+
# Update the ``__qualname__`` because this will be used later to check
242+
# whether something is a method defined in the class of interest, or just
243+
# a reference to a function that's stored in a class.
244+
cloned_method.__qualname__ = f"{cls.__name__}.{method_name}"
241245

242246
method_to_set: Any
243247
if isinstance(raw_attr, staticmethod):
@@ -378,6 +382,19 @@ def iter_tagged() -> Iterator[
378382
with contextlib.suppress(KeyError, TypeError):
379383
tags = _ufuncs_tags[func]
380384
if tags is not None:
385+
if isinstance(target, type):
386+
# There's a common pattern to wrap functions in namespace
387+
# classes to bypass lazy_xp_function like this:
388+
#
389+
# class naked:
390+
# myfunc = mymodule.myfunc
391+
#
392+
# To ensure this still works when checking for tags in
393+
# attributes of classes, use ``__qualname__`` to check whether
394+
# or not ``func`` was originally defined within ``target``.
395+
qn = getattr(func, "__qualname__", "")
396+
if not qn.startswith(f"{target.__name__}."):
397+
continue
381398
# put attr, and func in the outputs so we can later tell
382399
# if this was a staticmethod or classmethod.
383400
yield target, name, attr, func, tags

0 commit comments

Comments
 (0)