@@ -854,8 +854,8 @@ def check_sizeof(test, o, size):
854854 test .assertEqual (result , size , msg )
855855
856856#=======================================================================
857- # Decorator for running a function in a different locale, correctly resetting
858- # it afterwards.
857+ # Decorator/context manager for running a code in a different locale,
858+ # correctly resetting it afterwards.
859859
860860@contextlib .contextmanager
861861def run_with_locale (catstr , * locales ):
@@ -866,23 +866,68 @@ def run_with_locale(catstr, *locales):
866866 except AttributeError :
867867 # if the test author gives us an invalid category string
868868 raise
869- except :
869+ except Exception :
870870 # cannot retrieve original locale, so do nothing
871871 locale = orig_locale = None
872+ if '' not in locales :
873+ raise unittest .SkipTest ('no locales' )
872874 else :
873875 for loc in locales :
874876 try :
875877 locale .setlocale (category , loc )
876878 break
877- except :
879+ except locale . Error :
878880 pass
881+ else :
882+ if '' not in locales :
883+ raise unittest .SkipTest (f'no locales { locales } ' )
879884
880885 try :
881886 yield
882887 finally :
883888 if locale and orig_locale :
884889 locale .setlocale (category , orig_locale )
885890
891+ #=======================================================================
892+ # Decorator for running a function in multiple locales (if they are
893+ # availasble) and resetting the original locale afterwards.
894+
895+ def run_with_locales (catstr , * locales ):
896+ def deco (func ):
897+ @functools .wraps (func )
898+ def wrapper (self , / , * args , ** kwargs ):
899+ dry_run = '' in locales
900+ try :
901+ import locale
902+ category = getattr (locale , catstr )
903+ orig_locale = locale .setlocale (category )
904+ except AttributeError :
905+ # if the test author gives us an invalid category string
906+ raise
907+ except Exception :
908+ # cannot retrieve original locale, so do nothing
909+ pass
910+ else :
911+ try :
912+ for loc in locales :
913+ with self .subTest (locale = loc ):
914+ try :
915+ locale .setlocale (category , loc )
916+ except locale .Error :
917+ self .skipTest (f'no locale { loc !r} ' )
918+ else :
919+ dry_run = False
920+ func (self , * args , ** kwargs )
921+ finally :
922+ locale .setlocale (category , orig_locale )
923+ if dry_run :
924+ # no locales available, so just run the test
925+ # with the current locale
926+ with self .subTest (locale = None ):
927+ func (self , * args , ** kwargs )
928+ return wrapper
929+ return deco
930+
886931#=======================================================================
887932# Decorator for running a function in a specific timezone, correctly
888933# resetting it afterwards.
0 commit comments