@@ -930,8 +930,8 @@ def check_sizeof(test, o, size):
930930 test .assertEqual (result , size , msg )
931931
932932#=======================================================================
933- # Decorator for running a function in a different locale, correctly resetting
934- # it afterwards.
933+ # Decorator/context manager for running a code in a different locale,
934+ # correctly resetting it afterwards.
935935
936936@contextlib .contextmanager
937937def run_with_locale (catstr , * locales ):
@@ -942,23 +942,68 @@ def run_with_locale(catstr, *locales):
942942 except AttributeError :
943943 # if the test author gives us an invalid category string
944944 raise
945- except :
945+ except Exception :
946946 # cannot retrieve original locale, so do nothing
947947 locale = orig_locale = None
948+ if '' not in locales :
949+ raise unittest .SkipTest ('no locales' )
948950 else :
949951 for loc in locales :
950952 try :
951953 locale .setlocale (category , loc )
952954 break
953- except :
955+ except locale . Error :
954956 pass
957+ else :
958+ if '' not in locales :
959+ raise unittest .SkipTest (f'no locales { locales } ' )
955960
956961 try :
957962 yield
958963 finally :
959964 if locale and orig_locale :
960965 locale .setlocale (category , orig_locale )
961966
967+ #=======================================================================
968+ # Decorator for running a function in multiple locales (if they are
969+ # availasble) and resetting the original locale afterwards.
970+
971+ def run_with_locales (catstr , * locales ):
972+ def deco (func ):
973+ @functools .wraps (func )
974+ def wrapper (self , / , * args , ** kwargs ):
975+ dry_run = '' in locales
976+ try :
977+ import locale
978+ category = getattr (locale , catstr )
979+ orig_locale = locale .setlocale (category )
980+ except AttributeError :
981+ # if the test author gives us an invalid category string
982+ raise
983+ except Exception :
984+ # cannot retrieve original locale, so do nothing
985+ pass
986+ else :
987+ try :
988+ for loc in locales :
989+ with self .subTest (locale = loc ):
990+ try :
991+ locale .setlocale (category , loc )
992+ except locale .Error :
993+ self .skipTest (f'no locale { loc !r} ' )
994+ else :
995+ dry_run = False
996+ func (self , * args , ** kwargs )
997+ finally :
998+ locale .setlocale (category , orig_locale )
999+ if dry_run :
1000+ # no locales available, so just run the test
1001+ # with the current locale
1002+ with self .subTest (locale = None ):
1003+ func (self , * args , ** kwargs )
1004+ return wrapper
1005+ return deco
1006+
9621007#=======================================================================
9631008# Decorator for running a function in a specific timezone, correctly
9641009# resetting it afterwards.
0 commit comments