|
35 | 35 | is_dict_rprimitive, |
36 | 36 | is_fixed_width_rtype, |
37 | 37 | is_float_rprimitive, |
| 38 | + is_int16_rprimitive, |
38 | 39 | is_int32_rprimitive, |
39 | 40 | is_int64_rprimitive, |
40 | 41 | is_int_rprimitive, |
@@ -900,28 +901,35 @@ def emit_unbox( |
900 | 901 | self.emit_line(f" {dest} = 1;") |
901 | 902 | elif is_int64_rprimitive(typ): |
902 | 903 | # Whether we are borrowing or not makes no difference. |
| 904 | + assert not optional # Not supported for overlapping error values |
903 | 905 | if declare_dest: |
904 | 906 | self.emit_line(f"int64_t {dest};") |
905 | 907 | self.emit_line(f"{dest} = CPyLong_AsInt64({src});") |
906 | | - # TODO: Handle 'optional' |
907 | | - # TODO: Handle 'failure' |
| 908 | + if not isinstance(error, AssignHandler): |
| 909 | + self.emit_unbox_failure_with_overlapping_error_value(dest, typ, failure) |
908 | 910 | elif is_int32_rprimitive(typ): |
909 | 911 | # Whether we are borrowing or not makes no difference. |
| 912 | + assert not optional # Not supported for overlapping error values |
910 | 913 | if declare_dest: |
911 | 914 | self.emit_line(f"int32_t {dest};") |
912 | 915 | self.emit_line(f"{dest} = CPyLong_AsInt32({src});") |
913 | | - # TODO: Handle 'optional' |
914 | | - # TODO: Handle 'failure' |
| 916 | + if not isinstance(error, AssignHandler): |
| 917 | + self.emit_unbox_failure_with_overlapping_error_value(dest, typ, failure) |
| 918 | + elif is_int16_rprimitive(typ): |
| 919 | + # Whether we are borrowing or not makes no difference. |
| 920 | + assert not optional # Not supported for overlapping error values |
| 921 | + if declare_dest: |
| 922 | + self.emit_line(f"int16_t {dest};") |
| 923 | + self.emit_line(f"{dest} = CPyLong_AsInt16({src});") |
| 924 | + if not isinstance(error, AssignHandler): |
| 925 | + self.emit_unbox_failure_with_overlapping_error_value(dest, typ, failure) |
915 | 926 | elif is_float_rprimitive(typ): |
| 927 | + assert not optional # Not supported for overlapping error values |
916 | 928 | if declare_dest: |
917 | 929 | self.emit_line("double {};".format(dest)) |
918 | 930 | # TODO: Don't use __float__ and __index__ |
919 | 931 | self.emit_line(f"{dest} = PyFloat_AsDouble({src});") |
920 | | - self.emit_lines( |
921 | | - f"if ({dest} == -1.0 && PyErr_Occurred()) {{", f"{dest} = -113.0;", "}" |
922 | | - ) |
923 | | - # TODO: Handle 'optional' |
924 | | - # TODO: Handle 'failure' |
| 932 | + self.emit_lines(f"if ({dest} == -1.0 && PyErr_Occurred()) {{", failure, "}") |
925 | 933 | elif isinstance(typ, RTuple): |
926 | 934 | self.declare_tuple_struct(typ) |
927 | 935 | if declare_dest: |
@@ -1006,7 +1014,7 @@ def emit_box( |
1006 | 1014 | self.emit_lines(f"{declaration}{dest} = Py_None;") |
1007 | 1015 | if not can_borrow: |
1008 | 1016 | self.emit_inc_ref(dest, object_rprimitive) |
1009 | | - elif is_int32_rprimitive(typ): |
| 1017 | + elif is_int32_rprimitive(typ) or is_int16_rprimitive(typ): |
1010 | 1018 | self.emit_line(f"{declaration}{dest} = PyLong_FromLong({src});") |
1011 | 1019 | elif is_int64_rprimitive(typ): |
1012 | 1020 | self.emit_line(f"{declaration}{dest} = PyLong_FromLongLong({src});") |
@@ -1137,6 +1145,13 @@ def _emit_traceback( |
1137 | 1145 | if DEBUG_ERRORS: |
1138 | 1146 | self.emit_line('assert(PyErr_Occurred() != NULL && "failure w/o err!");') |
1139 | 1147 |
|
| 1148 | + def emit_unbox_failure_with_overlapping_error_value( |
| 1149 | + self, dest: str, typ: RType, failure: str |
| 1150 | + ) -> None: |
| 1151 | + self.emit_line(f"if ({dest} == {self.c_error_value(typ)} && PyErr_Occurred()) {{") |
| 1152 | + self.emit_line(failure) |
| 1153 | + self.emit_line("}") |
| 1154 | + |
1140 | 1155 |
|
1141 | 1156 | def c_array_initializer(components: list[str], *, indented: bool = False) -> str: |
1142 | 1157 | """Construct an initializer for a C array variable. |
|
0 commit comments