@@ -425,6 +425,8 @@ class Missing(Failure):
425425 """
426426
427427 def __init__ (self , missing_item , collection , help = None ):
428+ if isinstance (collection , list ):
429+ collection = _process_list (collection , _raw )
428430 super ().__init__ (rationale = _ ("Did not find {} in {}" ).format (_raw (missing_item ), _raw (collection )), help = help )
429431
430432 if missing_item == EOF :
@@ -500,10 +502,49 @@ def wrapper(*args, **kwargs):
500502 return wrapper
501503 return decorator
502504
505+ def _process_list (lst , processor , flatten = "shallow" , joined_by = "\n " ):
506+ """
507+ Applies a function `processor` to every element of a list.
508+
509+ `flatten` has 3 choices:
510+ - `none`: Apply `processor` to every element of a list without flattening (e.g. `['1', '2', '[3]']`).
511+ - `shallow`: Flatten by one level only and apply `processor` (e.g. `'1\\ n2\\ n[3]'`).
512+ - `deep`: Recursively flatten and apply `processor` (e.g. `'1\\ n2\\ n3'`).
513+
514+ Example usage:
515+ if isinstance(obj, list):
516+ return _process_list(obj, _raw, joined_by=" ")
517+
518+ :param lst: A list to be modified.
519+ :type lst: list
520+ :param processor: The function that processes each item.
521+ :type processor: callable
522+ :param flatten: The level of flattening to apply. One of "none", "shallow", or "deep".
523+ :type flatten: str
524+ :param joined_by: If `flatten` is one of "shallow" or "deep", uses this string to join the elements of the list.
525+ :param joined_by: str
526+ :rtype: list | str
527+ """
528+ match flatten :
529+ case "shallow" :
530+ return joined_by .join (processor (item ) for item in lst )
531+ case "deep" :
532+ def _flatten_deep (x ):
533+ for item in x :
534+ if isinstance (item , list ):
535+ yield from _flatten_deep (item )
536+ else :
537+ yield item
538+
539+ return joined_by .join (processor (item ) for item in _flatten_deep (lst ))
540+ case _:
541+ # for "none" and every other case
542+ return [processor (item ) for item in lst ]
543+
503544def _truncate (s , other ):
504545 def normalize (obj ):
505546 if isinstance (obj , list ):
506- return " \n " . join ( map ( str , obj ) )
547+ return _process_list ( obj , str )
507548 else :
508549 return str (obj )
509550
@@ -538,10 +579,6 @@ def normalize(obj):
538579
539580def _raw (s ):
540581 """Get raw representation of s."""
541-
542- if isinstance (s , list ):
543- s = "\n " .join (_raw (item ) for item in s )
544-
545582 if s == EOF :
546583 return "EOF"
547584 elif s == TIMEOUT :
0 commit comments