|
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 | +from mypyc.primitives.weakref_ops import ( |
| 100 | + new_proxy_op, |
| 101 | + new_ref_op, |
| 102 | +) |
100 | 103 |
|
101 | 104 | # Specializers are attempted before compiling the arguments to the |
102 | 105 | # function. Specializers can return None to indicate that they failed |
@@ -891,29 +894,51 @@ def translate_ord(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value |
891 | 894 | return None |
892 | 895 |
|
893 | 896 |
|
894 | | -@specialize_function("weakref.proxy") |
| 897 | +@specialize_function("weakref.ReferenceType") |
895 | 898 | def translate_proxy(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | None: |
896 | 899 | """ |
897 | | - Special case for weakref.proxy(...). |
| 900 | + Special case for weakref.ref(...). |
898 | 901 |
|
899 | 902 | If there's only one argument (the object), pass None for the callback. |
900 | 903 | If there are two arguments, use them as (object, callback). |
901 | 904 | Otherwise, fallback to a normal Python call by returning None. |
902 | 905 | """ |
903 | | - line = expr.line |
| 906 | + obj_val = builder.accept(expr.args[0]) |
904 | 907 | 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): |
| 908 | + if num_args == 1: |
| 909 | + callback_val = builder.none_object() |
| 910 | + elif num_args == 2: |
| 911 | + callback_val = builder.accept(expr.args[1]) |
| 912 | + else: |
| 913 | + # If the user supplied something other than 1 or 2 args, just fail |
| 914 | + # and let MyPyC do a generic Python call. |
909 | 915 | # NOTE: should we raise a compiler error here? |
910 | 916 | return None |
911 | 917 |
|
| 918 | + # Emit a direct C call to PyWeakref_NewProxy |
| 919 | + return builder.call_c(new_ref_op, [obj_val, callback_val], expr.line) |
| 920 | + |
| 921 | + |
| 922 | +@specialize_function("weakref.proxy") |
| 923 | +def translate_proxy(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value | None: |
| 924 | + """ |
| 925 | + Special case for weakref.proxy(...). |
| 926 | +
|
| 927 | + If there's only one argument (the object), pass None for the callback. |
| 928 | + If there are two arguments, use them as (object, callback). |
| 929 | + Otherwise, fallback to a normal Python call by returning None. |
| 930 | + """ |
912 | 931 | obj_val = builder.accept(expr.args[0]) |
| 932 | + num_args = len(expr.args) |
913 | 933 | if num_args == 1: |
914 | 934 | callback_val = builder.none_object() |
915 | | - else: |
| 935 | + elif num_args == 2: |
916 | 936 | callback_val = builder.accept(expr.args[1]) |
| 937 | + else: |
| 938 | + # If the user supplied something other than 1 or 2 args, just fail |
| 939 | + # and let MyPyC do a generic Python call. |
| 940 | + # NOTE: should we raise a compiler error here? |
| 941 | + return None |
917 | 942 |
|
918 | 943 | # Emit a direct C call to PyWeakref_NewProxy |
919 | | - return builder.call_c(new_proxy_op, [obj_val, callback_val], line) |
| 944 | + return builder.call_c(new_proxy_op, [obj_val, callback_val], expr.line) |
0 commit comments