|
96 | 96 | str_encode_utf8_strict, |
97 | 97 | ) |
98 | 98 | from mypyc.primitives.tuple_ops import new_tuple_set_item_op |
| 99 | +from mypyc.primitives.weakref_ops import new_proxy_op |
99 | 100 |
|
100 | 101 | # Specializers are attempted before compiling the arguments to the |
101 | 102 | # function. Specializers can return None to indicate that they failed |
@@ -888,3 +889,31 @@ def translate_ord(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value |
888 | 889 | if isinstance(arg, (StrExpr, BytesExpr)) and len(arg.value) == 1: |
889 | 890 | return Integer(ord(arg.value)) |
890 | 891 | return None |
| 892 | + |
| 893 | + |
| 894 | +@specialize_function("weakref.proxy") |
| 895 | +def translate_proxy(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | None: |
| 896 | + """ |
| 897 | + Special case for weakref.proxy(...). |
| 898 | + |
| 899 | + If there's only one argument (the object), pass None for the callback. |
| 900 | + If there are two arguments, use them as (object, callback). |
| 901 | + Otherwise, fallback to a normal Python call by returning None. |
| 902 | + """ |
| 903 | + line = expr.line |
| 904 | + num_args = len(expr.args) |
| 905 | + |
| 906 | + # If the user supplied something other than 1 or 2 args, just fail |
| 907 | + # and let MyPyC do a generic Python call. |
| 908 | + if num_args not in (1, 2): |
| 909 | + # NOTE: should we raise a compiler error here? |
| 910 | + return None |
| 911 | + |
| 912 | + obj_val = builder.accept(expr.args[0]) |
| 913 | + if num_args == 1: |
| 914 | + callback_val = builder.none_object() |
| 915 | + else: |
| 916 | + callback_val = builder.accept(expr.args[1]) |
| 917 | + |
| 918 | + # Emit a direct C call to PyWeakref_NewProxy |
| 919 | + return builder.call_c(new_proxy_op, [obj_val, callback_val], line) |
0 commit comments