(
buffer: &PyObject,
encoding: &str,
errors: &Py<PyUtf8Str>,
newline: Newlines,
vm: &VirtualMachine,
)
| 2917 | |
| 2918 | #[allow(clippy::type_complexity)] |
| 2919 | fn find_coder( |
| 2920 | buffer: &PyObject, |
| 2921 | encoding: &str, |
| 2922 | errors: &Py<PyUtf8Str>, |
| 2923 | newline: Newlines, |
| 2924 | vm: &VirtualMachine, |
| 2925 | ) -> PyResult<( |
| 2926 | Option<(PyObjectRef, Option<EncodeFunc>)>, |
| 2927 | Option<PyObjectRef>, |
| 2928 | )> { |
| 2929 | let codec = vm.state.codec_registry.lookup(encoding, vm)?; |
| 2930 | if !codec.is_text_codec(vm)? { |
| 2931 | return Err(vm.new_lookup_error(format!( |
| 2932 | "'{encoding}' is not a text encoding; use codecs.open() to handle arbitrary codecs" |
| 2933 | ))); |
| 2934 | } |
| 2935 | let errors = errors.to_owned().into_wtf8(); |
| 2936 | |
| 2937 | let encoder = if vm.call_method(buffer, "writable", ())?.try_to_bool(vm)? { |
| 2938 | let incremental_encoder = |
| 2939 | match codec.get_incremental_encoder(Some(errors.clone()), vm) { |
| 2940 | Ok(encoder) => encoder, |
| 2941 | Err(err) |
| 2942 | if err.fast_isinstance(vm.ctx.exceptions.type_error) |
| 2943 | || err.fast_isinstance(vm.ctx.exceptions.attribute_error) => |
| 2944 | { |
| 2945 | let name = vm |
| 2946 | .get_attribute_opt(codec.as_tuple().to_owned().into(), "name")? |
| 2947 | .and_then(|obj| obj.downcast::<PyStr>().ok()); |
| 2948 | StatelessIncrementalEncoder { |
| 2949 | encode: codec.get_encode_func().to_owned(), |
| 2950 | errors: Some(errors.clone()), |
| 2951 | name, |
| 2952 | } |
| 2953 | .into_ref(&vm.ctx) |
| 2954 | .into() |
| 2955 | } |
| 2956 | Err(err) => return Err(err), |
| 2957 | }; |
| 2958 | let encoding_name = vm.get_attribute_opt(incremental_encoder.clone(), "name")?; |
| 2959 | let encode_func = encoding_name.and_then(|name| { |
| 2960 | let name = name.downcast_ref::<PyStr>()?; |
| 2961 | match name.to_str()? { |
| 2962 | "utf-8" => Some(textio_encode_utf8 as EncodeFunc), |
| 2963 | _ => None, |
| 2964 | } |
| 2965 | }); |
| 2966 | Some((incremental_encoder, encode_func)) |
| 2967 | } else { |
| 2968 | None |
| 2969 | }; |
| 2970 | |
| 2971 | let decoder = if vm.call_method(buffer, "readable", ())?.try_to_bool(vm)? { |
| 2972 | let decoder = match codec.get_incremental_decoder(Some(errors.clone()), vm) { |
| 2973 | Ok(decoder) => decoder, |
| 2974 | Err(err) |
| 2975 | if err.fast_isinstance(vm.ctx.exceptions.type_error) |
| 2976 | || err.fast_isinstance(vm.ctx.exceptions.attribute_error) => |
nothing calls this directly
no test coverage detected