@@ -921,8 +921,8 @@ def check_sizeof(test, o, size):
921921 test .assertEqual (result , size , msg )
922922
923923#=======================================================================
924- # Decorator for running a function in a different locale, correctly resetting
925- # it afterwards.
924+ # Decorator/context manager for running a code in a different locale,
925+ # correctly resetting it afterwards.
926926
927927@contextlib .contextmanager
928928def run_with_locale (catstr , * locales ):
@@ -933,23 +933,68 @@ def run_with_locale(catstr, *locales):
933933 except AttributeError :
934934 # if the test author gives us an invalid category string
935935 raise
936- except :
936+ except Exception :
937937 # cannot retrieve original locale, so do nothing
938938 locale = orig_locale = None
939+ if '' not in locales :
940+ raise unittest .SkipTest ('no locales' )
939941 else :
940942 for loc in locales :
941943 try :
942944 locale .setlocale (category , loc )
943945 break
944- except :
946+ except locale . Error :
945947 pass
948+ else :
949+ if '' not in locales :
950+ raise unittest .SkipTest (f'no locales { locales } ' )
946951
947952 try :
948953 yield
949954 finally :
950955 if locale and orig_locale :
951956 locale .setlocale (category , orig_locale )
952957
958+ #=======================================================================
959+ # Decorator for running a function in multiple locales (if they are
960+ # availasble) and resetting the original locale afterwards.
961+
962+ def run_with_locales (catstr , * locales ):
963+ def deco (func ):
964+ @functools .wraps (func )
965+ def wrapper (self , / , * args , ** kwargs ):
966+ dry_run = '' in locales
967+ try :
968+ import locale
969+ category = getattr (locale , catstr )
970+ orig_locale = locale .setlocale (category )
971+ except AttributeError :
972+ # if the test author gives us an invalid category string
973+ raise
974+ except Exception :
975+ # cannot retrieve original locale, so do nothing
976+ pass
977+ else :
978+ try :
979+ for loc in locales :
980+ with self .subTest (locale = loc ):
981+ try :
982+ locale .setlocale (category , loc )
983+ except locale .Error :
984+ self .skipTest (f'no locale { loc !r} ' )
985+ else :
986+ dry_run = False
987+ func (self , * args , ** kwargs )
988+ finally :
989+ locale .setlocale (category , orig_locale )
990+ if dry_run :
991+ # no locales available, so just run the test
992+ # with the current locale
993+ with self .subTest (locale = None ):
994+ func (self , * args , ** kwargs )
995+ return wrapper
996+ return deco
997+
953998#=======================================================================
954999# Decorator for running a function in a specific timezone, correctly
9551000# resetting it afterwards.
0 commit comments