Emit call to the wrapper function. If not_implemented_handler is non-empty, use this C code to handle a NotImplemented return value (if it's possible based on the return type).
(self, not_implemented_handler: str = "")
| 912 | bitmap_arg_index += 1 |
| 913 | |
| 914 | def emit_call(self, not_implemented_handler: str = "") -> None: |
| 915 | """Emit call to the wrapper function. |
| 916 | |
| 917 | If not_implemented_handler is non-empty, use this C code to handle |
| 918 | a NotImplemented return value (if it's possible based on the return type). |
| 919 | """ |
| 920 | native_args = ", ".join(f"arg_{arg}" for arg in self.arg_names) |
| 921 | if self.num_bitmap_args: |
| 922 | bitmap_args = ", ".join( |
| 923 | [bitmap_name(i) for i in reversed(range(self.num_bitmap_args))] |
| 924 | ) |
| 925 | native_args = f"{native_args}, {bitmap_args}" |
| 926 | |
| 927 | ret_type = self.ret_type |
| 928 | emitter = self.emitter |
| 929 | if ret_type.is_unboxed or self.use_goto(): |
| 930 | # TODO: The Py_RETURN macros return the correct PyObject * with reference count |
| 931 | # handling. Are they relevant? |
| 932 | emitter.emit_line( |
| 933 | "{}retval = {}({});".format( |
| 934 | emitter.ctype_spaced(ret_type), self.target_native_call, native_args |
| 935 | ) |
| 936 | ) |
| 937 | emitter.emit_lines(*self.cleanups) |
| 938 | if ret_type.is_unboxed: |
| 939 | emitter.emit_error_check("retval", ret_type, "return NULL;") |
| 940 | emitter.emit_box("retval", "retbox", ret_type, declare_dest=True) |
| 941 | |
| 942 | emitter.emit_line("return {};".format("retbox" if ret_type.is_unboxed else "retval")) |
| 943 | else: |
| 944 | if not_implemented_handler and not isinstance(ret_type, RInstance): |
| 945 | # The return value type may overlap with NotImplemented. |
| 946 | emitter.emit_line(f"PyObject *retbox = {self.target_native_call}({native_args});") |
| 947 | emitter.emit_lines( |
| 948 | "if (retbox == Py_NotImplemented) {", |
| 949 | not_implemented_handler, |
| 950 | "}", |
| 951 | "return retbox;", |
| 952 | ) |
| 953 | else: |
| 954 | emitter.emit_line(f"return {self.target_native_call}({native_args});") |
| 955 | # TODO: Tracebacks? |
| 956 | |
| 957 | def error(self) -> ErrorHandler: |
| 958 | """Figure out how to deal with errors in the wrapper.""" |
no test coverage detected