Emit code for unboxing a value of given type (from PyObject *). By default, assign error value to dest if the value has an incompatible type and raise TypeError. These can be customized using 'error' and 'raise_exception'. Generate a new reference unless 'borrow' is
(
self,
src: str,
dest: str,
typ: RType,
*,
declare_dest: bool = False,
error: ErrorHandler | None = None,
raise_exception: bool = True,
optional: bool = False,
borrow: bool = False,
)
| 989 | self.emit_line("else {") |
| 990 | |
| 991 | def emit_unbox( |
| 992 | self, |
| 993 | src: str, |
| 994 | dest: str, |
| 995 | typ: RType, |
| 996 | *, |
| 997 | declare_dest: bool = False, |
| 998 | error: ErrorHandler | None = None, |
| 999 | raise_exception: bool = True, |
| 1000 | optional: bool = False, |
| 1001 | borrow: bool = False, |
| 1002 | ) -> None: |
| 1003 | """Emit code for unboxing a value of given type (from PyObject *). |
| 1004 | |
| 1005 | By default, assign error value to dest if the value has an |
| 1006 | incompatible type and raise TypeError. These can be customized |
| 1007 | using 'error' and 'raise_exception'. |
| 1008 | |
| 1009 | Generate a new reference unless 'borrow' is True. |
| 1010 | |
| 1011 | Args: |
| 1012 | src: Name of source C variable |
| 1013 | dest: Name of target C variable |
| 1014 | typ: Type of value |
| 1015 | declare_dest: If True, also declare the variable 'dest' |
| 1016 | error: What happens on error |
| 1017 | raise_exception: If True, also raise TypeError on failure |
| 1018 | optional: If True, NULL src value is allowed and will map to error value |
| 1019 | borrow: If True, create a borrowed reference |
| 1020 | |
| 1021 | """ |
| 1022 | error = error or AssignHandler() |
| 1023 | # TODO: Verify refcount handling. |
| 1024 | if isinstance(error, AssignHandler): |
| 1025 | failure = f"{dest} = {self.c_error_value(typ)};" |
| 1026 | elif isinstance(error, GotoHandler): |
| 1027 | failure = "goto %s;" % error.label |
| 1028 | else: |
| 1029 | assert isinstance(error, ReturnHandler), error |
| 1030 | failure = "return %s;" % error.value |
| 1031 | if raise_exception: |
| 1032 | raise_exc = f'CPy_TypeError("{self.pretty_name(typ)}", {src}); ' |
| 1033 | failure = raise_exc + failure |
| 1034 | if is_int_rprimitive(typ) or is_short_int_rprimitive(typ): |
| 1035 | if declare_dest: |
| 1036 | self.emit_line(f"CPyTagged {dest};") |
| 1037 | self.emit_arg_check(src, dest, typ, f"(likely(PyLong_Check({src})))", optional) |
| 1038 | if borrow: |
| 1039 | self.emit_line(f" {dest} = CPyTagged_BorrowFromObject({src});") |
| 1040 | else: |
| 1041 | self.emit_line(f" {dest} = CPyTagged_FromObject({src});") |
| 1042 | self.emit_line("else {") |
| 1043 | self.emit_line(failure) |
| 1044 | self.emit_line("}") |
| 1045 | elif is_bool_or_bit_rprimitive(typ): |
| 1046 | # Whether we are borrowing or not makes no difference. |
| 1047 | if declare_dest: |
| 1048 | self.emit_line(f"char {dest};") |
no test coverage detected