#!/usr/bin/python def escape_core(level, text): ''' Used by `escape` Levels of escaping ------------------ `level` == 0: No treatment. `level` == 1: '<', '>' and '&' `level` == 2: '<', '>', '&', '"' and "'" ''' text = '{}'.format(text) if level == 0: return text elif level >= 1: escaped = text.replace( '&', '&').replace( '<', '<').replace( '>', '>' ) if level == 1: return escaped elif level >= 2: return escaped.replace('"', '"').replace("'", ''') else: assert False, "Level too high." def escape(s, *args, **kwargs): ''' (CGI) escaping replacement for `str.format`. escape('{}', 2, 'http://example.com/', 1, 'example.com', ) Arguments: s [level text] ... [key=(level, text)] ... Levels of escaping ------------------ `level` == 0: No treatment. `level` == 1: '<', '>' and '&' `level` == 2: '<', '>', '&', '"' and "'" ''' assert len(args)%2 == 0 args = list(args) # Needed for `pop`ping. safe_args = [] while args: level = args.pop(0) text = args.pop(0) safe_args.append(escape_core(level, text)) safe_kwargs = {} for key in kwargs: safe_kwargs[key] = escape_core(kwargs[key][0], kwargs[key][1]) return s.format(*safe_args, **safe_kwargs)