Skip to content

[mypyc] Allow weak references to classes that allow interpreted subclasses - #22468

Open
Jahongir-Qurbonov wants to merge 1 commit into
python:masterfrom
Jahongir-Qurbonov:mypyc-weakref-interpreted-subclasses
Open

Jahongir-Qurbonov wants to merge 1 commit into
python:masterfrom
Jahongir-Qurbonov:mypyc-weakref-interpreted-subclasses

Conversation

@Jahongir-Qurbonov

Copy link
Copy Markdown
Contributor

Weak reference support for native classes was added in #22387. Along with it, mypyc reports a compile error when the target of weakref.ref() or weakref.proxy() has the type of a native class without weak reference support. This gave a false positive for classes that allow interpreted subclasses:

import weakref
from mypy_extensions import mypyc_attr

@mypyc_attr(allow_interpreted_subclasses=True)
class A:
    pass

def f(a: A) -> object:
    return weakref.ref(a)

mypyc reported Cannot create weak reference to instance of native class "A" for f. But a may be an instance of an interpreted subclass of A, and interpreted subclasses always support weak references (this is also what the docs say). Now the error is not reported if the class allows interpreted subclasses. Calling f with an instance of A itself still raises TypeError at runtime, like it does when the static type is object. All base classes of a class that allows interpreted subclasses must allow them as well, so it's enough to check the class itself.

I also removed a TODO comment in the generated tp_dealloc that said weak references created inside __del__ are not cleared. The weak reference list is cleared after PyObject_CallFinalizerFromDealloc() returns, so these are cleared too. (CPython's second clearing pass in subtype_dealloc is for the legacy tp_del slot, which mypyc doesn't use.)

Tests: I added a class that allows interpreted subclasses to the irbuild error test case. In run-weakref.test, an interpreted subclass instance passed to a compiled weakref.ref() call now works, and an instance of the native class still raises TypeError. The existing __del__ test now also creates a weak reference inside __del__ and checks that it's dead after the object is freed.

…asses

mypyc reported a compile error for weakref.ref(a) or weakref.proxy(a)
when 'a' has the type of a native class without weak reference support.
This is a false positive if the class has
@mypyc_attr(allow_interpreted_subclasses=True), since the value may be
an instance of an interpreted subclass, and interpreted subclasses
always support weak references. Don't report the error in this case;
an instance of the native class itself still raises TypeError at
runtime. Since all base classes of a class that allows interpreted
subclasses must also allow them, checking the class itself is enough.

Also remove an incorrect TODO comment in the generated tp_dealloc
claiming that weak references created inside __del__ are not cleared.
The weak reference list is cleared after the finalizer has run, so
these are cleared as well. Add a test for this.
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.

1 participant