Index: django/utils/translation/trans_real.py
===================================================================
--- django/utils/translation/trans_real.py	(revision 125)
+++ django/utils/translation/trans_real.py	(working copy)
@@ -247,32 +247,23 @@
         _default = translation(settings.LANGUAGE_CODE)
     return _default
 
-def do_translate(message, translation_function):
+def gettext(message):
     """
-    Translate 'message' using the given 'translation_function' name -- which
-    will be either gettext or ugettext.
+    This function will be patched into the builtins module to provide the _
+    helper function. It will use the current thread as a discriminator to find
+    the translation object to use. If no current translation is activated, the
+    message will be run through the default translation object.
     """
     global _default, _active
     t = _active.get(currentThread(), None)
     if t is not None:
-        return getattr(t, translation_function)(message)
+        return t.ugettext(message)
     if _default is None:
         from django.conf import settings
         _default = translation(settings.LANGUAGE_CODE)
-    return getattr(_default, translation_function)(message)
+    return _default.ugettext(message)
+ugettext = gettext
 
-def gettext(message):
-    """
-    This function will be patched into the builtins module to provide the _
-    helper function. It will use the current thread as a discriminator to find
-    the translation object to use. If no current translation is activated, the
-    message will be run through the default translation object.
-    """
-    return do_translate(message, 'gettext')
-
-def ugettext(message):
-    return do_translate(message, 'ugettext')
-
 def gettext_noop(message):
     """
     Marks strings for translation but doesn't translate them now. This can be
@@ -282,31 +273,21 @@
     """
     return message
 
-def do_ntranslate(singular, plural, number, translation_function):
+def ngettext(singular, plural, number):
+    """
+    Returns a unicode string of the translation of either the singular or
+    plural, based on the number.
+    """
     global _default, _active
-
     t = _active.get(currentThread(), None)
     if t is not None:
-        return getattr(t, translation_function)(singular, plural, number)
+        return t.ungetext(singular, plural, number)
     if _default is None:
         from django.conf import settings
         _default = translation(settings.LANGUAGE_CODE)
-    return getattr(_default, translation_function)(singular, plural, number)
+    return _default.ungettext(singular, plural, number)
+ungettext = ngettext
 
-def ngettext(singular, plural, number):
-    """
-    Returns a UTF-8 bytestring of the translation of either the singular or
-    plural, based on the number.
-    """
-    return do_ntranslate(singular, plural, number, 'ngettext')
-
-def ungettext(singular, plural, number):
-    """
-    Returns a unicode strings of the translation of either the singular or
-    plural, based on the number.
-    """
-    return do_ntranslate(singular, plural, number, 'ungettext')
-
 def check_for_language(lang_code):
     """
     Checks whether there is a global language file for the given language
Index: django/utils/translation/__init__.py
===================================================================
--- django/utils/translation/__init__.py	(revision 125)
+++ django/utils/translation/__init__.py	(working copy)
@@ -48,28 +48,23 @@
 
 def gettext_noop(message):
     return real_gettext_noop(message)
-
 ugettext_noop = gettext_noop
 
 def gettext(message):
     return real_gettext(message)
+ugettext = gettext
 
 def ngettext(singular, plural, number):
     return real_ngettext(singular, plural, number)
+ungettext = ngettext
 
-def ugettext(message):
-    return real_ugettext(message)
-
-def ungettext(singular, plural, number):
-    return real_ungettext(singular, plural, number)
-
 def string_concat(*strings):
     return real_string_concat(*strings)
 
-ngettext_lazy = lazy(ngettext, str)
-gettext_lazy = lazy(gettext, str)
-ungettext_lazy = lazy(ungettext, unicode)
-ugettext_lazy = lazy(ugettext, unicode)
+ngettext_lazy = lazy(ngettext, unicode)
+gettext_lazy = lazy(gettext, unicode)
+ungettext_lazy = ngettext_lazy
+ugettext_lazy = gettext_lazy
 string_concat = lazy(string_concat, unicode)
 
 def activate(language):
Index: django/utils/translation/trans_null.py
===================================================================
--- django/utils/translation/trans_null.py	(revision 125)
+++ django/utils/translation/trans_null.py	(working copy)
@@ -6,13 +6,9 @@
 from django.utils.encoding import force_unicode
 
 def ngettext(singular, plural, number):
-    if number == 1: return singular
-    return plural
-ngettext_lazy = ngettext
+    return force_unicode({1: singular}.get(number, plural))
+ungettext = ngettext_lazy = ngettext
 
-def ungettext(singular, plural, number):
-    return force_unicode(ngettext(singular, plural, number))
-
 string_concat = lambda *strings: u''.join([force_unicode(el) for el in strings])
 activate = lambda x: None
 deactivate = deactivate_all = install = lambda: None
@@ -32,13 +28,9 @@
 }
 
 def gettext(message):
-    return TECHNICAL_ID_MAP.get(message, message)
+    return force_unicode(TECHNICAL_ID_MAP.get(message, message))
+ugettext = gettext_noop = gettext_lazy = _ = gettext
 
-def ugettext(message):
-    return force_unicode(gettext(message))
-
-gettext_noop = gettext_lazy = _ = gettext
-
 def to_locale(language):
     p = language.find('-')
     if p >= 0:
