@@ -382,6 +382,23 @@ mod _codecs_windows {
382382 use crate :: { builtins:: PyStrRef , builtins:: PyUtf8StrRef , function:: ArgBytesLike } ;
383383 use rustpython_host_env:: windows as host_windows;
384384
385+ fn string_from_utf16 (
386+ encoding : & str ,
387+ data : & [ u8 ] ,
388+ wide : & [ u16 ] ,
389+ vm : & VirtualMachine ,
390+ ) -> PyResult < String > {
391+ String :: from_utf16 ( wide) . map_err ( |err| {
392+ vm. new_unicode_decode_error (
393+ vm. ctx . new_str ( encoding) ,
394+ vm. ctx . new_bytes ( data. to_vec ( ) ) ,
395+ 0 ,
396+ data. len ( ) ,
397+ vm. ctx . new_str ( format ! ( "{encoding}_decode failed: {err}" ) ) ,
398+ )
399+ } )
400+ }
401+
385402 #[ derive( FromArgs ) ]
386403 struct MbcsEncodeArgs {
387404 #[ pyarg( positional) ]
@@ -399,9 +416,7 @@ mod _codecs_windows {
399416 Some ( s) => s,
400417 None => {
401418 // String contains surrogates - not encodable with mbcs
402- return Err ( vm. new_unicode_encode_error (
403- "'mbcs' codec can't encode character: surrogates not allowed" ,
404- ) ) ;
419+ return encode_code_page_errors ( host_windows:: CP_ACP , & args. s , errors, "mbcs" , vm) ;
405420 }
406421 } ;
407422 let char_len = args. s . char_len ( ) ;
@@ -433,9 +448,7 @@ mod _codecs_windows {
433448 . map_err ( |err| vm. new_os_error ( format ! ( "mbcs_encode failed: {err}" ) ) ) ?;
434449
435450 if errors == "strict" && used_default_char {
436- return Err ( vm. new_unicode_encode_error (
437- "'mbcs' codec can't encode characters: invalid character" ,
438- ) ) ;
451+ return encode_code_page_errors ( host_windows:: CP_ACP , & args. s , errors, "mbcs" , vm) ;
439452 }
440453
441454 buffer. truncate ( result) ;
@@ -484,8 +497,7 @@ mod _codecs_windows {
484497 )
485498 . map_err ( |err| vm. new_os_error ( format ! ( "mbcs_decode failed: {err}" ) ) ) ?;
486499 buffer. truncate ( result) ;
487- let s = String :: from_utf16 ( & buffer)
488- . map_err ( |e| vm. new_unicode_decode_error ( format ! ( "mbcs_decode failed: {e}" ) ) ) ?;
500+ let s = string_from_utf16 ( "mbcs" , data. as_ref ( ) , & buffer, vm) ?;
489501 return Ok ( ( s, len) ) ;
490502 }
491503
@@ -500,8 +512,7 @@ mod _codecs_windows {
500512 )
501513 . map_err ( |err| vm. new_os_error ( format ! ( "mbcs_decode failed: {err}" ) ) ) ?;
502514 buffer. truncate ( result) ;
503- let s = String :: from_utf16 ( & buffer)
504- . map_err ( |e| vm. new_unicode_decode_error ( format ! ( "mbcs_decode failed: {e}" ) ) ) ?;
515+ let s = string_from_utf16 ( "mbcs" , data. as_ref ( ) , & buffer, vm) ?;
505516
506517 Ok ( ( s, len) )
507518 }
@@ -523,9 +534,7 @@ mod _codecs_windows {
523534 Some ( s) => s,
524535 None => {
525536 // String contains surrogates - not encodable with oem
526- return Err ( vm. new_unicode_encode_error (
527- "'oem' codec can't encode character: surrogates not allowed" ,
528- ) ) ;
537+ return encode_code_page_errors ( host_windows:: CP_OEMCP , & args. s , errors, "oem" , vm) ;
529538 }
530539 } ;
531540 let char_len = args. s . char_len ( ) ;
@@ -557,9 +566,7 @@ mod _codecs_windows {
557566 . map_err ( |err| vm. new_os_error ( format ! ( "oem_encode failed: {err}" ) ) ) ?;
558567
559568 if errors == "strict" && used_default_char {
560- return Err ( vm. new_unicode_encode_error (
561- "'oem' codec can't encode characters: invalid character" ,
562- ) ) ;
569+ return encode_code_page_errors ( host_windows:: CP_OEMCP , & args. s , errors, "oem" , vm) ;
563570 }
564571
565572 buffer. truncate ( result) ;
@@ -609,8 +616,7 @@ mod _codecs_windows {
609616 )
610617 . map_err ( |err| vm. new_os_error ( format ! ( "oem_decode failed: {err}" ) ) ) ?;
611618 buffer. truncate ( result) ;
612- let s = String :: from_utf16 ( & buffer)
613- . map_err ( |e| vm. new_unicode_decode_error ( format ! ( "oem_decode failed: {e}" ) ) ) ?;
619+ let s = string_from_utf16 ( "oem" , data. as_ref ( ) , & buffer, vm) ?;
614620 return Ok ( ( s, len) ) ;
615621 }
616622
@@ -625,8 +631,7 @@ mod _codecs_windows {
625631 )
626632 . map_err ( |err| vm. new_os_error ( format ! ( "oem_decode failed: {err}" ) ) ) ?;
627633 buffer. truncate ( result) ;
628- let s = String :: from_utf16 ( & buffer)
629- . map_err ( |e| vm. new_unicode_decode_error ( format ! ( "oem_decode failed: {e}" ) ) ) ?;
634+ let s = string_from_utf16 ( "oem" , data. as_ref ( ) , & buffer, vm) ?;
630635
631636 Ok ( ( s, len) )
632637 }
@@ -1024,7 +1029,7 @@ mod _codecs_windows {
10241029 }
10251030 }
10261031 let object = vm. ctx . new_bytes ( data. to_vec ( ) ) ;
1027- return Err ( vm. new_unicode_decode_error_real (
1032+ return Err ( vm. new_unicode_decode_error (
10281033 encoding_str,
10291034 object,
10301035 fail_pos,
@@ -1115,7 +1120,7 @@ mod _codecs_windows {
11151120 }
11161121 "strict" => {
11171122 let object = vm. ctx . new_bytes ( data. to_vec ( ) ) ;
1118- return Err ( vm. new_unicode_decode_error_real (
1123+ return Err ( vm. new_unicode_decode_error (
11191124 encoding_str,
11201125 object,
11211126 pos,
@@ -1126,7 +1131,7 @@ mod _codecs_windows {
11261131 _ => {
11271132 // Custom error handler
11281133 let object = vm. ctx . new_bytes ( data. to_vec ( ) ) ;
1129- let exc = vm. new_unicode_decode_error_real (
1134+ let exc = vm. new_unicode_decode_error (
11301135 encoding_str. clone ( ) ,
11311136 object,
11321137 pos,
0 commit comments