@@ -216,6 +216,7 @@ def _wrapper(param):
216216 # no 'else' handling a LookupError here ; this case is covered by the first if/elif/else block
217217 # case 2: list or dictionary or dictionary of numbered encodings
218218 elif isinstance (p , int ):
219+ # if mapdict is a list, we shall align the parameter (starting from 1) as an index (starting from 0)
219220 if isinstance (mapdict , list ):
220221 p -= 1
221222 if isinstance (mapdict , list ) and 0 <= p < len (mapdict ) or \
@@ -252,26 +253,34 @@ def _wrapper(param):
252253 else :
253254 raise LookupError ("Bad parameter for encoding '{}': '{}'" .format (ename , p ))
254255 if ignore_case is not None :
255- case_d = ["upper" , "lower" ][any (c in "" .join (smapdict .values ()) for c in "abcdefghijklmnopqrstuvwxyz" )]
256- case_e = ["upper" , "lower" ][any (c in "" .join (smapdict .keys ()) for c in "abcdefghijklmnopqrstuvwxyz" )]
256+ cases = ["upper" , "lower" ]
257+ case_d = cases [any (c in str (list (smapdict .values ())) for c in "abcdefghijklmnopqrstuvwxyz" )]
258+ case_e = cases [any (c in str (list (smapdict .keys ())) for c in "abcdefghijklmnopqrstuvwxyz" )]
257259 i = ignore_case
258260 smapdict = {getattr (k , case_e )() if i in ["both" , "encode" ] else k : \
259- getattr (v , case_d )() if i in ["both" , "decode" ] else v for k , v in smapdict .items ()}
261+ ([getattr (x , case_d )() for x in v ] if isinstance (v , list ) else getattr (v , case_d )()) \
262+ if i in ["both" , "decode" ] else v for k , v in smapdict .items ()}
260263 if decode :
261264 tmp = {}
262265 # this has a meaning for encoding maps that could have clashes in encoded chars (e.g. Bacon's cipher ;
263266 # I => abaaa but also J => abaaa, with the following, we keep I instead of letting J overwrite it)
264267 for k , v in sorted (smapdict .items ()):
265- if v not in tmp .keys ():
266- tmp [v ] = k
268+ if not isinstance (v , list ):
269+ v = [v ]
270+ for x in v :
271+ if x not in tmp .keys ():
272+ tmp [x ] = k
267273 smapdict = tmp
268274 # this allows to avoid an error with Python2 in the "for i, c in enumerate(parts)" loop
269275 if '' not in smapdict .keys ():
270276 smapdict ['' ] = ""
271277 # determine token and result lengths
272278 tmaxlen = max (map (len , smapdict .keys ()))
273279 tminlen = max (1 , min (map (len , set (smapdict .keys ()) - {'' })))
274- rminlen = max (1 , min (map (len , set (smapdict .values ()) - {'' })))
280+ l = []
281+ for x in smapdict .values ():
282+ getattr (l , ["append" , "extend" ][isinstance (x , list )])(x )
283+ rminlen = max (1 , min (map (len , set (l ) - {'' })))
275284
276285 # generic encoding/decoding function for map encodings
277286 def code (text , errors = "strict" ):
@@ -291,12 +300,15 @@ def code(text, errors="strict"):
291300 # get the value from the mapping dictionary, trying the token with its inverted case if relevant
292301 def __get_value (token , position , case_changed = False ):
293302 try :
294- return smapdict [token ] + lsep
303+ result = smapdict [token ]
295304 except KeyError :
296305 if icase and not case_changed :
297306 token_inv_case = getattr (token , case )()
298307 return __get_value (token_inv_case , position , True )
299308 return handle_error (ename , errors , exc , lsep , repl_char , rminlen , decode )(token , position )
309+ if isinstance (result , list ):
310+ result = random .choice (result )
311+ return result + lsep
300312
301313 # if a separator is defined, rely on it by splitting the input text
302314 if decode and len (sep ) > 0 :
0 commit comments