summaryrefslogtreecommitdiff
path: root/django/utils
diff options
context:
space:
mode:
Diffstat (limited to 'django/utils')
-rw-r--r--django/utils/datastructures.py50
-rw-r--r--django/utils/text.py24
2 files changed, 65 insertions, 9 deletions
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
index 21a72f2d1e..f27bc1cfff 100644
--- a/django/utils/datastructures.py
+++ b/django/utils/datastructures.py
@@ -332,17 +332,49 @@ class DotExpandedDict(dict):
except TypeError: # Special-case if current isn't a dict.
current = {bits[-1]: v}
-class FileDict(dict):
+class ImmutableList(tuple):
"""
- A dictionary used to hold uploaded file contents. The only special feature
- here is that repr() of this object won't dump the entire contents of the
- file to the output. A handy safeguard for a large file upload.
+ A tuple-like object that raises useful errors when it is asked to mutate.
+
+ Example::
+
+ >>> a = ImmutableList(range(5), warning="You cannot mutate this.")
+ >>> a[3] = '4'
+ Traceback (most recent call last):
+ ...
+ AttributeError: You cannot mutate this.
"""
- def __repr__(self):
- if 'content' in self:
- d = dict(self, content='<omitted>')
- return dict.__repr__(d)
- return dict.__repr__(self)
+
+ def __new__(cls, *args, **kwargs):
+ if 'warning' in kwargs:
+ warning = kwargs['warning']
+ del kwargs['warning']
+ else:
+ warning = 'ImmutableList object is immutable.'
+ self = tuple.__new__(cls, *args, **kwargs)
+ self.warning = warning
+ return self
+
+ def complain(self, *wargs, **kwargs):
+ if isinstance(self.warning, Exception):
+ raise self.warning
+ else:
+ raise AttributeError, self.warning
+
+ # All list mutation functions complain.
+ __delitem__ = complain
+ __delslice__ = complain
+ __iadd__ = complain
+ __imul__ = complain
+ __setitem__ = complain
+ __setslice__ = complain
+ append = complain
+ extend = complain
+ insert = complain
+ pop = complain
+ remove = complain
+ sort = complain
+ reverse = complain
class DictWrapper(dict):
"""
diff --git a/django/utils/text.py b/django/utils/text.py
index aa190c8c4f..3686a454a8 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -3,6 +3,7 @@ from django.conf import settings
from django.utils.encoding import force_unicode
from django.utils.functional import allow_lazy
from django.utils.translation import ugettext_lazy
+from htmlentitydefs import name2codepoint
# Capitalizes the first letter of a string.
capfirst = lambda x: x and force_unicode(x)[0].upper() + force_unicode(x)[1:]
@@ -222,3 +223,26 @@ def smart_split(text):
yield bit
smart_split = allow_lazy(smart_split, unicode)
+def _replace_entity(match):
+ text = match.group(1)
+ if text[0] == u'#':
+ text = text[1:]
+ try:
+ if text[0] in u'xX':
+ c = int(text[1:], 16)
+ else:
+ c = int(text)
+ return unichr(c)
+ except ValueError:
+ return match.group(0)
+ else:
+ try:
+ return unichr(name2codepoint[text])
+ except (ValueError, KeyError):
+ return match.group(0)
+
+_entity_re = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));")
+
+def unescape_entities(text):
+ return _entity_re.sub(_replace_entity, text)
+unescape_entities = allow_lazy(unescape_entities, unicode)