Do not rely on dicts.merge to change target
Also make dicts.merge actually not touch target. This is much cleaner
than modifying in place, especially since we assign the result of the
dicts.merge call to target most of the time anyway.
Patch by: Sverre Rabbelier
"""Functions for working with "safe strings": strings that can be displayed safelywithout further escaping in HTML. Marking something as a "safe string" meansthat the producer of the string has already turned characters that should notbe interpreted by the HTML engine (e.g. '<') into the appropriate entities."""from django.utils.functional import curry, Promiseclass EscapeData(object): passclass EscapeString(str, EscapeData): """ A string that should be HTML-escaped when output. """ passclass EscapeUnicode(unicode, EscapeData): """ A unicode object that should be HTML-escaped when output. """ passclass SafeData(object): passclass SafeString(str, SafeData): """ A string subclass that has been specifically marked as "safe" (requires no further escaping) for HTML output purposes. """ def __add__(self, rhs): """ Concatenating a safe string with another safe string or safe unicode object is safe. Otherwise, the result is no longer safe. """ t = super(SafeString, self).__add__(rhs) if isinstance(rhs, SafeUnicode): return SafeUnicode(t) elif isinstance(rhs, SafeString): return SafeString(t) return t def _proxy_method(self, *args, **kwargs): """ Wrap a call to a normal unicode method up so that we return safe results. The method that is being wrapped is passed in the 'method' argument. """ method = kwargs.pop('method') data = method(self, *args, **kwargs) if isinstance(data, str): return SafeString(data) else: return SafeUnicode(data) decode = curry(_proxy_method, method = str.decode)class SafeUnicode(unicode, SafeData): """ A unicode subclass that has been specifically marked as "safe" for HTML output purposes. """ def __add__(self, rhs): """ Concatenating a safe unicode object with another safe string or safe unicode object is safe. Otherwise, the result is no longer safe. """ t = super(SafeUnicode, self).__add__(rhs) if isinstance(rhs, SafeData): return SafeUnicode(t) return t def _proxy_method(self, *args, **kwargs): """ Wrap a call to a normal unicode method up so that we return safe results. The method that is being wrapped is passed in the 'method' argument. """ method = kwargs.pop('method') data = method(self, *args, **kwargs) if isinstance(data, str): return SafeString(data) else: return SafeUnicode(data) encode = curry(_proxy_method, method = unicode.encode)def mark_safe(s): """ Explicitly mark a string as safe for (HTML) output purposes. The returned object can be used everywhere a string or unicode object is appropriate. Can be called multiple times on a single string. """ if isinstance(s, SafeData): return s if isinstance(s, str) or (isinstance(s, Promise) and s._delegate_str): return SafeString(s) if isinstance(s, (unicode, Promise)): return SafeUnicode(s) return SafeString(str(s))def mark_for_escaping(s): """ Explicitly mark a string as requiring HTML escaping upon output. Has no effect on SafeData subclasses. Can be called multiple times on a single string (the resulting escaping is only applied once). """ if isinstance(s, (SafeData, EscapeData)): return s if isinstance(s, str) or (isinstance(s, Promise) and s._delegate_str): return EscapeString(s) if isinstance(s, (unicode, Promise)): return EscapeUnicode(s) return EscapeString(str(s))