Index: django/newforms/forms.py
===================================================================
--- django/newforms/forms.py	(revision 5583)
+++ django/newforms/forms.py	(working copy)
@@ -57,12 +57,15 @@
     # class is different than Form. See the comments by the Form class for more
     # information. Any improvements to the form API should be made to *this*
     # class, not to the Form class.
-    def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None):
+    def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None, error_list_class=None):
         self.is_bound = data is not None
         self.data = data or {}
         self.auto_id = auto_id
         self.prefix = prefix
         self.initial = initial or {}
+        if not error_list_class:
+            error_list_class = ErrorList 
+        self.error_list_class = error_list_class
         self._errors = None # Stores the errors after clean() has been called.
 
         # The base_fields class attribute is the *class-wide* definition of
@@ -116,7 +119,7 @@
         output, hidden_fields = [], []
         for name, field in self.fields.items():
             bf = BoundField(self, field, name)
-            bf_errors = ErrorList([escape(error) for error in bf.errors]) # Escape and cache in local variable.
+            bf_errors = self.error_list_class([escape(error) for error in bf.errors]) # Escape and cache in local variable.
             if bf.is_hidden:
                 if bf_errors:
                     top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors])
@@ -167,7 +170,7 @@
         field -- i.e., from Form.clean(). Returns an empty ErrorList if there
         are none.
         """
-        return self.errors.get(NON_FIELD_ERRORS, ErrorList())
+        return self.errors.get(NON_FIELD_ERRORS, self.error_list_class())
 
     def full_clean(self):
         """
@@ -248,7 +251,7 @@
         Returns an ErrorList for this field. Returns an empty ErrorList
         if there are none.
         """
-        return self.form.errors.get(self.name, ErrorList())
+        return self.form.errors.get(self.name, self.form.error_list_class())
     errors = property(_errors)
 
     def as_widget(self, widget, attrs=None):
Index: docs/newforms.txt
===================================================================
--- docs/newforms.txt	(revision 5583)
+++ docs/newforms.txt	(working copy)
@@ -554,6 +554,29 @@
     <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
     <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
 
+Customizing the error list format
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, forms use ``django.newforms.util.ErrorList`` to output validation
+errors. If you would like to use an alternate form of displaying errors, you
+can tell your forms to use a different output format. For example::
+
+    >>> from django.newforms.util import ErrorList
+    >>> class DivErrorList(ErrorList):
+    ...     def __str__(self):
+    ...         return self.as_divs()
+    ...     def as_divs(self):
+    ...         if not self: return u''
+    ...         return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self])
+    >>> f = ContactForm(data, auto_id=False, error_list_class=DivErrorList)
+    >>> f.as_p()
+    <div class="errorlist"><div class="error">This field is required.</div></div>
+    <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
+    <p>Message: <input type="text" name="message" value="Hi there" /></p>
+    <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
+    <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
+    <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
+
 More granular output
 ~~~~~~~~~~~~~~~~~~~~
 
Index: tests/regressiontests/forms/tests.py
===================================================================
--- tests/regressiontests/forms/tests.py	(revision 5583)
+++ tests/regressiontests/forms/tests.py	(working copy)
@@ -3690,6 +3690,31 @@
 True
 >>> f.cleaned_data['username']
 u'sirrobin'
+
+#######################################
+# Test overriding ErrorList in a form #
+#######################################
+
+>>> from django.newforms.util import ErrorList
+>>> class DivErrorList(ErrorList):
+...     def __str__(self):
+...         return self.as_divs()
+...     def as_divs(self):
+...         if not self: return u''
+...         return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self])
+>>> class CommentForm(Form):
+...     name = CharField(max_length=50, required=False)
+...     email = EmailField()
+...     comment = CharField()
+>>> data = dict(email='invalid')
+>>> f = CommentForm(data, auto_id=False, error_list_class=DivErrorList)
+>>> print f.as_p()
+<p>Name: <input type="text" name="name" maxlength="50" /></p>
+<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
+<p>Email: <input type="text" name="email" value="invalid" /></p>
+<div class="errorlist"><div class="error">This field is required.</div></div>
+<p>Comment: <input type="text" name="comment" /></p>
+
 """
 
 __test__ = {
