@@ -610,84 +610,47 @@ impl FormatSpec {
610610 num : & Complex64 ,
611611 locale : & LocaleInfo ,
612612 ) -> Result < String , FormatSpecError > {
613- // For complex, format real and imaginary parts separately with locale
614- if self . alternate_form {
615- return Err ( FormatSpecError :: NotAllowed ( "Alternate form (#)" ) ) ;
616- }
617- if matches ! (
618- self . format_type,
619- Some (
620- FormatType :: String
621- | FormatType :: Binary
622- | FormatType :: Octal
623- | FormatType :: Hex ( _)
624- | FormatType :: Character
625- | FormatType :: Decimal
626- | FormatType :: Number ( Case :: Upper )
627- | FormatType :: Unknown ( _)
628- )
629- ) {
630- let ch = char:: from ( self . format_type . as_ref ( ) . unwrap ( ) ) ;
631- return Err ( FormatSpecError :: UnknownFormatCode ( ch, "complex" ) ) ;
632- }
633-
634- let precision = self . precision . unwrap_or ( 6 ) ;
635- let format_type = match self . format_type {
636- Some ( FormatType :: Number ( case) ) => FormatType :: GeneralFormat ( case) ,
637- _ => return self . format_complex ( num) ,
638- } ;
639-
640- let magnitude_format = FormatSpec {
641- format_type : Some ( format_type) ,
642- precision : Some ( if precision == 0 { 1 } else { precision } ) ,
613+ // Reuse format_complex_re_im with 'g' type to get the base formatted parts,
614+ // then apply locale grouping. This matches CPython's format_complex_internal:
615+ // 'n' → 'g', add_parens=0, skip_re=0.
616+ let locale_spec = FormatSpec {
617+ format_type : Some ( FormatType :: GeneralFormat ( Case :: Lower ) ) ,
643618 ..* self
644619 } ;
620+ let ( formatted_re, formatted_im) = locale_spec. format_complex_re_im ( num) ?;
645621
646- let re_str = if num. re == 0.0 && !num. re . is_sign_negative ( ) {
647- None
622+ // Apply locale grouping to both parts
623+ let grouped_re = if formatted_re. is_empty ( ) {
624+ formatted_re
648625 } else {
649- let re_sign = if num. re . is_sign_negative ( ) && !num. re . is_nan ( ) {
650- "-"
626+ // Split sign from magnitude, apply grouping, recombine
627+ let ( sign, mag) = if formatted_re. starts_with ( '-' )
628+ || formatted_re. starts_with ( '+' )
629+ || formatted_re. starts_with ( ' ' )
630+ {
631+ formatted_re. split_at ( 1 )
651632 } else {
652- ""
633+ ( "" , formatted_re . as_str ( ) )
653634 } ;
654- let re_mag = magnitude_format. format_float ( num. re . abs ( ) ) ?;
655- let re_grouped = Self :: apply_locale_formatting ( re_mag, locale) ;
656- Some ( format ! ( "{re_sign}{re_grouped}" ) )
657- } ;
658-
659- let im_sign = if num. im . is_sign_negative ( ) && !num. im . is_nan ( ) {
660- "-"
661- } else {
662- ""
635+ format ! ( "{sign}{}" , Self :: apply_locale_formatting( mag. to_string( ) , locale) )
663636 } ;
664- let im_mag = magnitude_format. format_float ( num. im . abs ( ) ) ?;
665- let im_grouped = Self :: apply_locale_formatting ( im_mag, locale) ;
666637
667- let has_re = re_str. is_some ( ) ;
668- let formatted = if let Some ( re_str) = re_str {
669- let sep = if num. im >= 0.0 || num. im . is_nan ( ) {
670- "+"
671- } else {
672- ""
673- } ;
674- format ! ( "({re_str}{sep}{im_sign}{im_grouped}j)" )
638+ // formatted_im is like "+1234j" or "-1234j" or "1234j"
639+ // Split sign, magnitude, and 'j' suffix
640+ let im_str = & formatted_im;
641+ let ( im_sign, im_rest) = if im_str. starts_with ( '+' ) || im_str. starts_with ( '-' ) {
642+ im_str. split_at ( 1 )
675643 } else {
676- format ! ( "{im_sign}{im_grouped}j" )
644+ ( "" , im_str . as_str ( ) )
677645 } ;
646+ let im_mag = im_rest. strip_suffix ( 'j' ) . unwrap_or ( im_rest) ;
647+ let im_grouped = Self :: apply_locale_formatting ( im_mag. to_string ( ) , locale) ;
648+ let grouped_im = format ! ( "{im_sign}{im_grouped}j" ) ;
678649
679- let format_sign = self . sign . unwrap_or ( FormatSign :: Minus ) ;
680- let sign_str = match format_sign {
681- FormatSign :: Plus => "+" ,
682- FormatSign :: Minus => "" ,
683- FormatSign :: MinusOrSpace => " " ,
684- } ;
650+ // No parentheses for 'n' format (CPython: add_parens=0)
651+ let magnitude_str = format ! ( "{grouped_re}{grouped_im}" ) ;
685652
686- self . format_sign_and_align (
687- & AsciiStr :: new ( & formatted) ,
688- if has_re { "" } else { sign_str } ,
689- FormatAlign :: Right ,
690- )
653+ self . format_sign_and_align ( & AsciiStr :: new ( & magnitude_str) , "" , FormatAlign :: Right )
691654 }
692655
693656 pub fn format_bool ( & self , input : bool ) -> Result < String , FormatSpecError > {
0 commit comments