Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion mypyc/primitives/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,5 @@ def load_address_op(name: str, type: RType, src: str) -> LoadAddressDescription:
import mypyc.primitives.list_ops
import mypyc.primitives.misc_ops
import mypyc.primitives.str_ops
import mypyc.primitives.tuple_ops # noqa: F401
import mypyc.primitives.tuple_ops
import mypyc.primitives.weakref_ops # noqa: F401
22 changes: 22 additions & 0 deletions mypyc/primitives/weakref_ops.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from mypyc.ir.ops import ERR_MAGIC
from mypyc.ir.rtypes import object_rprimitive, pointer_rprimitive
from mypyc.primitives.registry import function_op

# Weakref operations

new_ref_op = function_op(
name="weakref.ReferenceType",
arg_types=[object_rprimitive],
return_type=object_rprimitive,
c_function_name="PyWeakref_NewRef",
extra_int_constants=[(0, pointer_rprimitive)],
error_kind=ERR_MAGIC,
)

new_ref__with_callback_op = function_op(
name="weakref.ReferenceType",
arg_types=[object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
c_function_name="PyWeakref_NewRef",
error_kind=ERR_MAGIC,
)
51 changes: 51 additions & 0 deletions mypyc/test-data/irbuild-weakref.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[case testWeakrefRef]
import weakref
from typing import Any, Callable
def f(x: object) -> object:
return weakref.ref(x)

[out]
def f(x):
x, r0 :: object
L0:
r0 = PyWeakref_NewRef(x, 0)
return r0

[case testWeakrefRefCallback]
import weakref
from typing import Any, Callable
def f(x: object, cb: Callable[[object], Any]) -> object:
return weakref.ref(x, cb)

[out]
def f(x, cb):
x, cb, r0 :: object
L0:
r0 = PyWeakref_NewRef(x, cb)
return r0

[case testFromWeakrefRef]
from typing import Any, Callable
from weakref import ref
def f(x: object) -> object:
return ref(x)

[out]
def f(x):
x, r0 :: object
L0:
r0 = PyWeakref_NewRef(x, 0)
return r0

[case testFromWeakrefRefCallback]
from typing import Any, Callable
from weakref import ref
def f(x: object, cb: Callable[[object], Any]) -> object:
return ref(x, cb)

[out]
def f(x, cb):
x, cb, r0 :: object
L0:
r0 = PyWeakref_NewRef(x, cb)
return r0
25 changes: 25 additions & 0 deletions mypyc/test-data/run-weakref.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Test cases for weakrefs (compile and run)

[case testWeakrefRef]
import pytest # type: ignore [import-not-found]
from weakref import ref
from mypy_extensions import mypyc_attr

@mypyc_attr(native_class=False)
class Object:
"""some random weakreffable object"""
pass

def test_weakref_ref():
obj = Object()
r = ref(obj)
assert r() is obj
obj = None
assert r() is None, r()

def test_weakref_ref_with_callback():
obj = Object()
r = ref(obj, lambda x: x)
assert r() is obj
obj = None
assert r() is None, r()
1 change: 1 addition & 0 deletions mypyc/test/test_irbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"irbuild-constant-fold.test",
"irbuild-glue-methods.test",
"irbuild-math.test",
"irbuild-weakref.test",
]

if sys.version_info >= (3, 10):
Expand Down
1 change: 1 addition & 0 deletions mypyc/test/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"run-singledispatch.test",
"run-attrs.test",
"run-signatures.test",
"run-weakref.test",
"run-python37.test",
"run-python38.test",
]
Expand Down
11 changes: 11 additions & 0 deletions test-data/unit/lib-stub/weakref.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from collections.abc import Callable
from typing import Any, Generic, TypeVar
from typing_extensions import Self

_T = TypeVar("_T")

class ReferenceType(Generic[_T]): # "weakref"
__callback__: Callable[[Self], Any]
def __new__(cls, o: _T, callback: Callable[[Self], Any] | None = ..., /) -> Self: ...

ref = ReferenceType