Skip to content

Preserve native special-method lookup in automatic proxies - #362

Open
mayankdhingra02 wants to merge 1 commit into
GrahamDumpleton:developfrom
mayankdhingra02:fix-proxy-special-method-lookup
Open

mayankdhingra02 wants to merge 1 commit into
GrahamDumpleton:developfrom
mayankdhingra02:fix-proxy-special-method-lookup

Conversation

@mayankdhingra02

Copy link
Copy Markdown

Implicit special-method calls ignore attributes stored on the instance. The forwarding methods added by AutoObjectProxy and LazyObjectProxy currently use ordinary attribute access, so the proxy can behave differently from its wrapped object:

class Iterator:
    def __next__(self):
        return "type method"

obj = Iterator()
obj.__next__ = lambda: "instance attribute"

next(obj)                         # "type method"
next(wrapt.AutoObjectProxy(obj))  # "instance attribute" before this change

Look up forwarded hooks in the wrapped object's actual type MRO and preserve Python's descriptor binding rules. The descriptor __get__ hook retains its distinct raw-call behavior. This covers iteration, length hints, awaiting, asynchronous iteration, path conversion, and descriptor operations, including inherited hooks, instance/metaclass overrides, custom descriptors, static/class methods, and reassigned wrapped objects.

Added 14 regression tests and a change note. No C implementation or type stub changes.

Validation:

  • Every Justfile test-matrix cell passed via just test-version recipes in isolated copies of the same commit: Python 3.9–3.15 plus 3.14t/3.15t, each with a pure Python installation, the C extension enabled, and the C extension disabled at runtime (27 configurations).
  • just test-mypy passed for all seven target versions; Black and isort checks passed.
  • Independent source review and native-versus-proxy protocol probes passed. The new regressions reproduce failures on the unchanged base.

Local native builds used the installed macOS 15.5 SDK to match the compiler; no build configuration changes are included.

Resolve forwarded protocol hooks on the wrapped object type and preserve
the descriptor binding Python uses for implicit special method calls.
Instance attributes and custom attribute lookup should not replace the
hooks used by iteration, awaiting, path conversion or descriptors.

Signed-off-by: Mayank Dhingra <mayankdhingra02@gmail.com>
@GrahamDumpleton

Copy link
Copy Markdown
Owner

Definitely highlights an area which needs more investigation, but the general solution provided is possibly not the right approach to use in all cases. In some cases, rather than chaining to corresponding dunder method, it should be using builtins such as next(), aiter(), anext(), await on the wrapped object directly to ensure correct lookup and protocol requirements are satisfied. Will need to check whether there are other places outside AutoObjectProxy where such builtins, rather than chaining should be applied. Thanks for the PR highlighting the issue, but I will take it on as a task to investigate further before doing anything.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants