From 58fc7897653b0a64658b3ece5d0ff429b4636130 Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Tue, 16 Oct 2007 16:54:23 +0000 Subject: [PATCH] Merged revisions 6442-6524 via svnmerge from [repos:django/trunk trunk]. git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6525 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 2 +- django/bin/compile-messages.py | 3 +- django/bin/make-messages.py | 95 +++++++++--------- django/conf/locale/de/LC_MESSAGES/django.mo | Bin 44119 -> 44534 bytes django/conf/locale/de/LC_MESSAGES/django.po | 67 ++++++------ django/core/handlers/modpython.py | 2 +- django/core/handlers/wsgi.py | 2 +- django/core/management/__init__.py | 2 +- django/core/management/base.py | 27 +++-- django/core/management/color.py | 10 +- django/core/management/commands/runserver.py | 2 +- django/core/management/commands/startapp.py | 2 +- django/db/backends/postgresql/operations.py | 2 +- django/db/models/fields/__init__.py | 2 +- django/http/__init__.py | 5 +- django/newforms/widgets.py | 18 +++- django/oldforms/__init__.py | 4 +- django/utils/datastructures.py | 5 +- django/utils/translation/__init__.py | 14 ++- django/utils/translation/trans_null.py | 1 - django/utils/translation/trans_real.py | 6 -- django/views/static.py | 16 ++- docs/databases.txt | 6 +- docs/i18n.txt | 9 +- docs/newforms.txt | 4 +- docs/request_response.txt | 4 +- docs/templates_python.txt | 2 +- docs/unicode.txt | 30 +++--- tests/modeltests/basic/models.py | 2 +- tests/modeltests/field_defaults/models.py | 2 +- tests/regressiontests/datastructures/tests.py | 8 ++ tests/regressiontests/i18n/models.py | 12 +++ tests/regressiontests/i18n/tests.py | 8 ++ 33 files changed, 218 insertions(+), 156 deletions(-) diff --git a/AUTHORS b/AUTHORS index a6926b37b2..5af5c71f6e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -313,7 +313,7 @@ answer newbie questions, and generally made Django that much better: Vlado Milton Waddams wam-djangobug@wamber.net - wangchun + Wang Chun Filip Wasilewski Dan Watson Chris Wesseling diff --git a/django/bin/compile-messages.py b/django/bin/compile-messages.py index 2838cb8aa4..8693022644 100755 --- a/django/bin/compile-messages.py +++ b/django/bin/compile-messages.py @@ -14,7 +14,8 @@ def compile_messages(locale=None): basedirs = [os.path.join('conf', 'locale'), 'locale'] if os.environ.get('DJANGO_SETTINGS_MODULE'): from django.conf import settings - basedirs += settings.LOCALE_PATHS + if hasattr(settings, 'LOCALE_PATHS'): + basedirs += settings.LOCALE_PATHS # Gather existing directories. basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs))) diff --git a/django/bin/make-messages.py b/django/bin/make-messages.py index 11616c9ca5..44040390ea 100755 --- a/django/bin/make-messages.py +++ b/django/bin/make-messages.py @@ -74,59 +74,62 @@ def make_messages(): if os.path.exists(potfile): os.unlink(potfile) + all_files = [] for (dirpath, dirnames, filenames) in os.walk("."): - for file in filenames: - if domain == 'djangojs' and file.endswith('.js'): - if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) + all_files.extend([(dirpath, f) for f in filenames]) + all_files.sort() + for dirpath, file in all_files: + if domain == 'djangojs' and file.endswith('.js'): + if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) + src = open(os.path.join(dirpath, file), "rb").read() + src = pythonize_re.sub('\n#', src) + open(os.path.join(dirpath, '%s.py' % file), "wb").write(src) + thefile = '%s.py' % file + cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % ( + os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) + (stdin, stdout, stderr) = os.popen3(cmd, 't') + msgs = stdout.read() + errors = stderr.read() + if errors: + print "errors happened while running xgettext on %s" % file + print errors + sys.exit(8) + old = '#: '+os.path.join(dirpath, thefile)[2:] + new = '#: '+os.path.join(dirpath, file)[2:] + msgs = msgs.replace(old, new) + if msgs: + open(potfile, 'ab').write(msgs) + os.unlink(os.path.join(dirpath, thefile)) + elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')): + thefile = file + if file.endswith('.html'): src = open(os.path.join(dirpath, file), "rb").read() - src = pythonize_re.sub('\n#', src) - open(os.path.join(dirpath, '%s.py' % file), "wb").write(src) thefile = '%s.py' % file - cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % ( - os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) - (stdin, stdout, stderr) = os.popen3(cmd, 't') - msgs = stdout.read() - errors = stderr.read() - if errors: - print "errors happened while running xgettext on %s" % file - print errors - sys.exit(8) + open(os.path.join(dirpath, thefile), "wb").write(templatize(src)) + if verbose: + sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) + cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % ( + domain, os.path.join(dirpath, thefile)) + (stdin, stdout, stderr) = os.popen3(cmd, 't') + msgs = stdout.read() + errors = stderr.read() + if errors: + print "errors happened while running xgettext on %s" % file + print errors + sys.exit(8) + if thefile != file: old = '#: '+os.path.join(dirpath, thefile)[2:] new = '#: '+os.path.join(dirpath, file)[2:] msgs = msgs.replace(old, new) - if msgs: - open(potfile, 'ab').write(msgs) + if os.path.exists(potfile): + # Strip the header + msgs = '\n'.join(dropwhile(len, msgs.split('\n'))) + else: + msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8') + if msgs: + open(potfile, 'ab').write(msgs) + if thefile != file: os.unlink(os.path.join(dirpath, thefile)) - elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')): - thefile = file - if file.endswith('.html'): - src = open(os.path.join(dirpath, file), "rb").read() - thefile = '%s.py' % file - open(os.path.join(dirpath, thefile), "wb").write(templatize(src)) - if verbose: - sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) - cmd = 'xgettext -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=ugettext_noop --keyword=ugettext_lazy --keyword=ungettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % ( - domain, os.path.join(dirpath, thefile)) - (stdin, stdout, stderr) = os.popen3(cmd, 't') - msgs = stdout.read() - errors = stderr.read() - if errors: - print "errors happened while running xgettext on %s" % file - print errors - sys.exit(8) - if thefile != file: - old = '#: '+os.path.join(dirpath, thefile)[2:] - new = '#: '+os.path.join(dirpath, file)[2:] - msgs = msgs.replace(old, new) - if os.path.exists(potfile): - # Strip the header - msgs = '\n'.join(dropwhile(len, msgs.split('\n'))) - else: - msgs = msgs.replace('charset=CHARSET', 'charset=UTF-8') - if msgs: - open(potfile, 'ab').write(msgs) - if thefile != file: - os.unlink(os.path.join(dirpath, thefile)) if os.path.exists(potfile): (stdin, stdout, stderr) = os.popen3('msguniq --to-code=utf-8 "%s"' % potfile, 'b') diff --git a/django/conf/locale/de/LC_MESSAGES/django.mo b/django/conf/locale/de/LC_MESSAGES/django.mo index 307976e4d5bb511b296973f9108c7405e7833a27..2699d25e55a01134e563a18e504413303fb119d9 100644 GIT binary patch delta 11754 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

jpjLPi`s3^jx&DhOWTj%Ib3LlVkFg-0!eG3E zYWEN3K<_zr2}4l>jz%39hl!Yk#V`e%;7%-uUUThD9g6{+-&Cfc5!FR?&=fV3o~Uay z7&Y=KE}x5C$yZ|pW}Ro-MWWipIcs5e@+R06x8MPMj5^<*6xP2Cg~Jpyv-_wH{zg4+ z-t+BEl+~FN^%UgCdKihirrod)&c&Yi94lgv1>Bgp7|Y{BXR(F$ac#Sh>tB`~{i%q= zrC0&eumRpfeObgWvP;(wb=NP$Mz|L{qt9adb=wsq$!DMjuo2b&6BT<)bB@V$Ys1+%? z%>KDP12w_xSPFA_mfM@8wzE4{X2*2Y$PZu%yoVY{?)U9~q^^R=x~n&%?uk99{YSACp2m_GwbIVCDXO1+ zs1^7Eb^JL@z-y?xKi?|*G&R97dj307(A{|+hhmWrY)6YxGg^r{@n%=Q1HH-jV>BK{ zFT9PRco%i;&1(A{5ry`}L@$+=U_dCHmtJs1w~l_5T1hz-Orbyw=-#zx7;yEm=+~G@^p2k(R|g7>{~P znxi`GiRx&ub2w^-V^AGWLQP;A2H-;H3Rk}Y)o!PAuZMy<*pL2r40WQ@r~zHZ0Q?Pg zGo_>U2XC+zaF%i=I1`<%oSmI-qWXIqHBirZw_`SHC6=OoO0C0^cnC8FfLii&)C~MK z+La1Kbrgy^J`&ZwEM{DL%((Wb2{u68Q!SC>JfcG7& zKZqGChPsqm4a@z`j`cK5}DgAD)63 zLR2UA5O;~+iO*f*wWSXa(;8orQLBojqcz)EJd^>G+J#* z7Bil@lSE#kDUp-7!oK=MGs@aVJ8j16*cIAPf0S}Aw_oQs*NLN4lq7s82l77kqWmYZ zh^VYaY+BwL){-Sd)D%)W&TsP%o?!)YT=L{AZtgCGq^H!55U@ zU}qa*6y^QIo0PxDz68G|%qPU##2(@tb?0#cQI7K8c!>z0Toy+Wug@YrbPf06RPxNN8+n@BmsuyhxOe=i@8>EbDR-ir=YQIEB7dUm zpSgWU#Us}!2+y(OVdhSpPOK%m5rMAVY0BAMIo5fbx=)E$$roV&(VlWN@xrwkM%_o0 zBXs^}B)^cvVPkw3eBi{FA_t*g_!z9Z3t`n|;Wlz(>n#J9w3>hBS?DHkKg zP;Q0V!YS{w#f;C7$>aacJ?1Bp1H^Q86ePM3Gs!pLV{C{Au_aN0&{l=I8@6bMQSLxF zk@!sYLShwjlot}(ek89& zY@&RRXh^(GJ_BDTzNGBUQ=n}f<<{6$?FntGFv69W=_J}-aush%cd&lh_>f<6`_!%` zkw9dj%}><-Of)8chuB6OCSOj>ATqZ@lrIy15m$-1ZpTQpU0q>+ufScSZ>Yip{k@cfOTXA(_iy5CU z^BF^31!5ZI$;2;2UP9X;OU7pzKK7_KCy1ex*Ane0zlRU-J3{~ODF6O{+fM06mrbMHUz9hy`~Z0v zk(C3U==u*LNhaF62H#SyNO>UM#fijO;(g*iv77o&i5tCLV-NZ`b0`b3FD;l1nGK8p4c@kd0+QdA{*)VhSb>+IQVjTHZ zSMHzL2tS~{D1OcP%`B3xIEH9Vc_3zz3aU=F7{FwOyyiS~, YEAR. +# Translation of django.po to German +# +# Copyright (C) 2005-2007, +# This file is distributed under the same license as the django package. # msgid "" "" @@ -1629,76 +1630,76 @@ msgstr "Webseite" msgid "flat pages" msgstr "Webseiten" -#: contrib/humanize/templatetags/humanize.py:17 +#: contrib/humanize/templatetags/humanize.py:20 msgid "th" -msgstr "" +msgstr "." -#: contrib/humanize/templatetags/humanize.py:17 +#: contrib/humanize/templatetags/humanize.py:20 msgid "st" -msgstr "" +msgstr "." -#: contrib/humanize/templatetags/humanize.py:17 +#: contrib/humanize/templatetags/humanize.py:20 msgid "nd" -msgstr "" +msgstr "." -#: contrib/humanize/templatetags/humanize.py:17 +#: contrib/humanize/templatetags/humanize.py:20 msgid "rd" -msgstr "" - -#: contrib/humanize/templatetags/humanize.py:47 -#, python-format -msgid "%(value).1f million" -msgid_plural "%(value).1f million" -msgstr[0] "" -msgstr[1] "" +msgstr "." #: contrib/humanize/templatetags/humanize.py:50 #, python-format -msgid "%(value).1f billion" -msgid_plural "%(value).1f billion" -msgstr[0] "" -msgstr[1] "" +msgid "%(value).1f million" +msgid_plural "%(value).1f million" +msgstr[0] "%(value).1f Million" +msgstr[1] "%(value).1f Millionen" #: contrib/humanize/templatetags/humanize.py:53 #, python-format +msgid "%(value).1f billion" +msgid_plural "%(value).1f billion" +msgstr[0] "%(value).1f Milliarde" +msgstr[1] "%(value).1f Milliarden" + +#: contrib/humanize/templatetags/humanize.py:56 +#, python-format msgid "%(value).1f trillion" msgid_plural "%(value).1f trillion" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%(value).1f Billion" +msgstr[1] "%(value).1f Billionen" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "one" msgstr "ein" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "two" msgstr "zwei" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "three" msgstr "drei" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "four" msgstr "vier" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "five" msgstr "fünf" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "six" msgstr "sechs" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "seven" msgstr "sieben" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "eight" msgstr "acht" -#: contrib/humanize/templatetags/humanize.py:68 +#: contrib/humanize/templatetags/humanize.py:71 msgid "nine" msgstr "neun" diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py index d4f5e55011..52419d9e6c 100644 --- a/django/core/handlers/modpython.py +++ b/django/core/handlers/modpython.py @@ -14,7 +14,7 @@ import os class ModPythonRequest(http.HttpRequest): def __init__(self, req): self._req = req - self.path = force_unicode(req.uri) + self.path = force_unicode(req.uri, errors='ignore') def __repr__(self): # Since this is called as part of error handling, we need to be very diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 16d1d822e0..95c5f9cbda 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -75,7 +75,7 @@ def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0): class WSGIRequest(http.HttpRequest): def __init__(self, environ): self.environ = environ - self.path = force_unicode(environ['PATH_INFO']) + self.path = force_unicode(environ['PATH_INFO'], errors='ignore') self.META = environ self.method = environ['REQUEST_METHOD'].upper() diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index e15dfccdf2..cd90fd6109 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -239,7 +239,7 @@ def setup_environ(settings_mod): project_directory, settings_filename = os.path.split(settings_mod.__file__) project_name = os.path.basename(project_directory) settings_name = os.path.splitext(settings_filename)[0] - sys.path.append(os.path.join(project_directory, '..')) + sys.path.append(os.path.join(project_directory, os.pardir)) project_module = __import__(project_name, {}, {}, ['']) sys.path.pop() diff --git a/django/core/management/base.py b/django/core/management/base.py index 26ecef4ff5..0c458126e8 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -1,10 +1,10 @@ +import os +import sys +from optparse import make_option, OptionParser + import django from django.core.exceptions import ImproperlyConfigured from django.core.management.color import color_style -import itertools -from optparse import make_option, OptionParser -import sys -import os class CommandError(Exception): pass @@ -19,7 +19,7 @@ def handle_default_options(options): os.environ['DJANGO_SETTINGS_MODULE'] = options.settings if options.pythonpath: sys.path.insert(0, options.pythonpath) - + class BaseCommand(object): # Metadata about this command. option_list = ( @@ -161,17 +161,25 @@ class NoArgsCommand(BaseCommand): args = '' def handle(self, *args, **options): - from django.db import models - if len(args) != 0: + if args: raise CommandError("Command doesn't accept any arguments") - return self.handle_noargs(**options) def handle_noargs(self, **options): raise NotImplementedError() def copy_helper(style, app_or_project, name, directory, other_name=''): - import django + """ + Copies either a Django application layout template or a Django project + layout template into the specified directory. + + * style - A color style object (see django.core.management.color). + * app_or_project - The string 'app' or 'project'. + * name - The name of the application or project. + * directory - The directory to copy the layout template to. + * other_name - When copying an application layout, this should be the name + of the project. + """ import re import shutil other = {'project': 'app', 'app': 'project'}[app_or_project] @@ -221,4 +229,3 @@ def _make_writeable(filename): st = os.stat(filename) new_permissions = stat.S_IMODE(st.st_mode) | stat.S_IWUSR os.chmod(filename, new_permissions) - diff --git a/django/core/management/color.py b/django/core/management/color.py index ce95401491..40fd4e7fdd 100644 --- a/django/core/management/color.py +++ b/django/core/management/color.py @@ -2,12 +2,14 @@ Sets up the terminal color scheme. """ -from django.utils import termcolors import sys +from django.utils import termcolors + def color_style(): - "Returns a Style object with the Django color scheme." - if sys.platform == 'win32' or sys.platform == 'Pocket PC' or sys.platform.startswith('java') or not sys.stdout.isatty(): + """Returns a Style object with the Django color scheme.""" + if (sys.platform == 'win32' or sys.platform == 'Pocket PC' + or sys.platform.startswith('java') or not sys.stdout.isatty()): return no_style() class dummy: pass style = dummy() @@ -21,7 +23,7 @@ def color_style(): return style def no_style(): - "Returns a Style object that has no colors." + """Returns a Style object that has no colors.""" class dummy: def __getattr__(self, attr): return lambda x: x diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py index 5b141d03ed..12808bcaad 100644 --- a/django/core/management/commands/runserver.py +++ b/django/core/management/commands/runserver.py @@ -20,7 +20,7 @@ class Command(BaseCommand): import django from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException from django.core.handlers.wsgi import WSGIHandler - if len(args) != 0: + if args: raise CommandError('Usage is runserver %s' % self.args) if not addrport: addr = '' diff --git a/django/core/management/commands/startapp.py b/django/core/management/commands/startapp.py index 1da2776cf5..c238e74a08 100644 --- a/django/core/management/commands/startapp.py +++ b/django/core/management/commands/startapp.py @@ -16,7 +16,7 @@ class Command(LabelCommand): directory = os.getcwd() # Determine the project_name a bit naively -- by looking at the name of # the parent directory. - project_dir = os.path.normpath(os.path.join(directory, '..')) + project_dir = os.path.normpath(os.path.join(directory, os.pardir)) parent_dir = os.path.basename(project_dir) project_name = os.path.basename(directory) if app_name == project_name: diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index 9f36596ace..20392b238e 100644 --- a/django/db/backends/postgresql/operations.py +++ b/django/db/backends/postgresql/operations.py @@ -100,5 +100,5 @@ class DatabaseOperations(BaseDatabaseOperations): style.SQL_FIELD(qn('id')), style.SQL_KEYWORD('IS NOT'), style.SQL_KEYWORD('FROM'), - style.SQL_TABLE(f.m2m_db_table()))) + style.SQL_TABLE(qn(f.m2m_db_table())))) return output diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 4766f97199..6186063b1d 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -238,7 +238,7 @@ class Field(object): if self.default is not NOT_PROVIDED: if callable(self.default): return self.default() - return self.default + return force_unicode(self.default, strings_only=True) if not self.empty_strings_allowed or (self.null and settings.DATABASE_ENGINE != 'oracle'): return None return "" diff --git a/django/http/__init__.py b/django/http/__init__.py index 9a47e70592..508c6d2f3e 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -47,8 +47,9 @@ class HttpRequest(object): def get_host(self): "Returns the HTTP host using the environment or request headers." # We try three options, in order of decreasing preference. - host = self.META.get('HTTP_X_FORWARDED_HOST', '') - if 'HTTP_HOST' in self.META: + if 'HTTP_X_FORWARDED_HOST' in self.META: + host = self.META['HTTP_X_FORWARDED_HOST'] + elif 'HTTP_HOST' in self.META: host = self.META['HTTP_HOST'] else: # Reconstruct the host using the algorithm from PEP 333. diff --git a/django/newforms/widgets.py b/django/newforms/widgets.py index 0e7752499e..2c235513d0 100644 --- a/django/newforms/widgets.py +++ b/django/newforms/widgets.py @@ -7,7 +7,9 @@ try: except NameError: from sets import Set as set # Python 2.3 fallback +import copy from itertools import chain + from django.utils.datastructures import MultiValueDict from django.utils.html import escape from django.utils.translation import ugettext @@ -32,6 +34,12 @@ class Widget(object): else: self.attrs = {} + def __deepcopy__(self, memo): + obj = copy.copy(self) + obj.attrs = self.attrs.copy() + memo[id(self)] = obj + return obj + def render(self, name, value, attrs=None): """ Returns this Widget rendered as HTML, as a Unicode string. @@ -88,7 +96,7 @@ class PasswordInput(Input): input_type = 'password' def __init__(self, attrs=None, render_value=True): - self.attrs = attrs or {} + super(PasswordInput, self).__init__(attrs) self.render_value = render_value def render(self, name, value, attrs=None): @@ -105,8 +113,8 @@ class MultipleHiddenInput(HiddenInput): of values. """ def __init__(self, attrs=None, choices=()): + super(MultipleHiddenInput, self).__init__(attrs) # choices can be any iterable - self.attrs = attrs or {} self.choices = choices def render(self, name, value, attrs=None, choices=()): @@ -145,9 +153,9 @@ class Textarea(Widget): class CheckboxInput(Widget): def __init__(self, attrs=None, check_test=bool): + super(CheckboxInput, self).__init__(attrs) # check_test is a callable that takes a value and returns True # if the checkbox should be checked for that value. - self.attrs = attrs or {} self.check_test = check_test def render(self, name, value, attrs=None): @@ -164,7 +172,7 @@ class CheckboxInput(Widget): class Select(Widget): def __init__(self, attrs=None, choices=()): - self.attrs = attrs or {} + super(Select, self).__init__(attrs) # choices can be any iterable, but we may need to render this widget # multiple times. Thus, collapse it into a list so it can be consumed # more than once. @@ -203,8 +211,8 @@ class NullBooleanSelect(Select): class SelectMultiple(Widget): def __init__(self, attrs=None, choices=()): + super(SelectMultiple, self).__init__(attrs) # choices can be any iterable - self.attrs = attrs or {} self.choices = choices def render(self, name, value, attrs=None, choices=()): diff --git a/django/oldforms/__init__.py b/django/oldforms/__init__.py index 9bb90416c4..5f7b9fc2ad 100644 --- a/django/oldforms/__init__.py +++ b/django/oldforms/__init__.py @@ -500,7 +500,7 @@ class SelectField(FormField): selected_html = u'' if smart_unicode(value) == str_data: selected_html = u' selected="selected"' - output.append(u' ' % (escape(value), selected_html, escape(display_name))) + output.append(u' ' % (escape(value), selected_html, force_unicode(escape(display_name)))) output.append(u' ') return u'\n'.join(output) @@ -612,7 +612,7 @@ class SelectMultipleField(SelectField): selected_html = u'' if smart_unicode(value) in str_data_list: selected_html = u' selected="selected"' - output.append(u' ' % (escape(value), selected_html, escape(choice))) + output.append(u' ' % (escape(value), selected_html, force_unicode(escape(choice)))) output.append(u' ') return u'\n'.join(output) diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index 2f3c9bb568..d750f098f0 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -54,7 +54,10 @@ class SortedDict(dict): def __init__(self, data=None): if data is None: data = {} dict.__init__(self, data) - self.keyOrder = data.keys() + if isinstance(data, dict): + self.keyOrder = data.keys() + else: + self.keyOrder=[key for key, value in data] def __setitem__(self, key, value): dict.__setitem__(self, key, value) diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index 13fc8a847a..9ca7419e1e 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -2,6 +2,7 @@ Internationalization support. """ from django.utils.functional import lazy +from django.utils.encoding import force_unicode __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext', 'ngettext_lazy', 'string_concat', 'activate', 'deactivate', @@ -39,7 +40,7 @@ def delayed_loader(*args, **kwargs): g['real_%s' % name] = getattr(trans, name) # Make the originally requested function call on the way out the door. - return g[caller](*args, **kwargs) + return g['real_%s' % caller](*args, **kwargs) g = globals() for name in __all__: @@ -63,14 +64,10 @@ def 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) -string_concat = lazy(string_concat, unicode) def activate(language): return real_activate(language) @@ -108,3 +105,10 @@ def templatize(src): def deactivate_all(): return real_deactivate_all() +def string_concat(*strings): + """ + Lazy variant of string concatenation, needed for translations that are + constructed from multiple parts. + """ + return u''.join([force_unicode(s) for s in strings]) +string_concat = lazy(string_concat, unicode) diff --git a/django/utils/translation/trans_null.py b/django/utils/translation/trans_null.py index e3f89567a5..771a80e99c 100644 --- a/django/utils/translation/trans_null.py +++ b/django/utils/translation/trans_null.py @@ -13,7 +13,6 @@ 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 get_language = lambda: settings.LANGUAGE_CODE diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index 5fff1ea63a..250af04e8c 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -516,9 +516,3 @@ def templatize(src): out.write(blankout(t.contents, 'X')) return out.getvalue() -def string_concat(*strings): - """" - Lazy variant of string concatenation, needed for translations that are - constructed from multiple parts. - """ - return u''.join([force_unicode(s) for s in strings]) diff --git a/django/views/static.py b/django/views/static.py index 3ec4ca14a1..dce45d914d 100644 --- a/django/views/static.py +++ b/django/views/static.py @@ -1,6 +1,8 @@ -from django.template import loader -from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified -from django.template import Template, Context, TemplateDoesNotExist +""" +Views and functions for serving static files. These are only to be used +during development, and SHOULD NOT be used in a production setting. +""" + import mimetypes import os import posixpath @@ -9,6 +11,10 @@ import rfc822 import stat import urllib +from django.template import loader +from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseNotModified +from django.template import Template, Context, TemplateDoesNotExist + def serve(request, path, document_root=None, show_indexes=False): """ Serve static files below a given point in the directory structure. @@ -29,12 +35,12 @@ def serve(request, path, document_root=None, show_indexes=False): newpath = '' for part in path.split('/'): if not part: - # strip empty path components + # Strip empty path components. continue drive, part = os.path.splitdrive(part) head, part = os.path.split(part) if part in (os.curdir, os.pardir): - # strip '.' amd '..' in path + # Strip '.' and '..' in path. continue newpath = os.path.join(newpath, part).replace('\\', '/') if newpath and path != newpath: diff --git a/docs/databases.txt b/docs/databases.txt index 4d8824aa3d..213c2d666c 100644 --- a/docs/databases.txt +++ b/docs/databases.txt @@ -175,9 +175,9 @@ operators. You will also need the `cx_Oracle`_ driver, version 4.3.1 or newer. .. _`cx_Oracle`: http://cx-oracle.sourceforge.net/ To run ``python manage.py syncdb``, you'll need to create an Oracle database -user with CREATE TABLE, CREATE SEQUENCE, and CREATE PROCEDURE privileges. To -run Django's test suite, the user also needs CREATE and DROP DATABASE and -CREATE and DROP TABLESPACE privileges. +user with CREATE TABLE, CREATE SEQUENCE, CREATE PROCEDURE, and CREATE TRIGGER +privileges. To run Django's test suite, the user also needs +CREATE and DROP DATABASE and CREATE and DROP TABLESPACE privileges. Connecting to the Database -------------------------- diff --git a/docs/i18n.txt b/docs/i18n.txt index bf73c88008..2c43e7884e 100644 --- a/docs/i18n.txt +++ b/docs/i18n.txt @@ -456,10 +456,13 @@ otherwise, they'll be tacked together without whitespace! .. admonition:: Mind your charset - When creating a ``.po`` file with your favorite text editor, first edit + When creating a PO file with your favorite text editor, first edit the charset line (search for ``"CHARSET"``) and set it to the charset - you'll be using to edit the content. Generally, utf-8 should work for most - languages, but ``gettext`` should handle any charset you throw at it. + you'll be using to edit the content. Due to the way the ``gettext`` tools + work internally and because we want to allow non-ASCII source strings in + Django's core and your applications, you **must** use UTF-8 as the encoding + for your PO file (this means that everybody will be using the same + encoding, which is important when Django processes the PO files). To reexamine all source code and templates for new translation strings and update all message files for **all** languages, run this:: diff --git a/docs/newforms.txt b/docs/newforms.txt index 11e19e847f..2005adeec8 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -2075,9 +2075,9 @@ More coming soon ================ That's all the documentation for now. For more, see the file -http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms/tests.py +http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms -- the unit tests for ``django.newforms``. This can give you a good idea of -what's possible. +what's possible. (Each submodule there contains separate tests.) If you're really itching to learn and use this library, please be patient. We're working hard on finishing both the code and documentation. diff --git a/docs/request_response.txt b/docs/request_response.txt index 7806886841..8da00cdf09 100644 --- a/docs/request_response.txt +++ b/docs/request_response.txt @@ -381,8 +381,8 @@ Methods ``mimetype``. Historically, the parameter was only called ``mimetype``, but since this is actually the value included in the HTTP ``Content-Type`` header, it can also include the character set encoding, which makes it - more than just a MIME type specification. If ``mimetype`` is specifiedi - (not None), that value is used. Otherwise, ``content_type`` is used. If + more than just a MIME type specification. If ``mimetype`` is specified + (not None), that value is used. Otherwise, ``content_type`` is used. If neither is given, the ``DEFAULT_CONTENT_TYPE`` setting is used. ``__setitem__(header, value)`` diff --git a/docs/templates_python.txt b/docs/templates_python.txt index b6173ad39a..bd105888ce 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -316,7 +316,7 @@ optional, third positional argument, ``processors``. In this example, the }, [ip_address_processor]) return t.render(c) -Note:: +.. note:: If you're using Django's ``render_to_response()`` shortcut to populate a template with the contents of a dictionary, your template will be passed a ``Context`` instance by default (not a ``RequestContext``). To use a diff --git a/docs/unicode.txt b/docs/unicode.txt index 1ab255970c..a0e2648f57 100644 --- a/docs/unicode.txt +++ b/docs/unicode.txt @@ -110,19 +110,22 @@ Conversion functions The ``django.utils.encoding`` module contains a few functions that are handy for converting back and forth between Unicode and bytestrings. - * ``smart_unicode(s, encoding='utf-8', errors='strict')`` converts its - input to a Unicode string. The ``encoding`` parameter specifies the input - encoding. (For example, Django uses this internally when processing form - input data, which might not be UTF-8 encoded.) The ``errors`` parameter - takes any of the values that are accepted by Python's ``unicode()`` - function for its error handling. + * ``smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict')`` + converts its input to a Unicode string. The ``encoding`` parameter + specifies the input encoding. (For example, Django uses this internally + when processing form input data, which might not be UTF-8 encoded.) The + ``strings_only`` parameter, if set to True, will result in Python + numbers, booleans and ``None`` not being converted to a string (they keep + their original types). The ``errors`` parameter takes any of the values + that are accepted by Python's ``unicode()`` function for its error + handling. If you pass ``smart_unicode()`` an object that has a ``__unicode__`` method, it will use that method to do the conversion. - * ``force_unicode(s, encoding='utf-8', errors='strict')`` is identical to - ``smart_unicode()`` in almost all cases. The difference is when the - first argument is a `lazy translation`_ instance. While + * ``force_unicode(s, encoding='utf-8', strings_only=False, errors='strict')`` + is identical to ``smart_unicode()`` in almost all cases. The difference + is when the first argument is a `lazy translation`_ instance. While ``smart_unicode()`` preserves lazy translations, ``force_unicode()`` forces those objects to a Unicode string (causing the translation to occur). Normally, you'll want to use ``smart_unicode()``. However, @@ -132,11 +135,10 @@ for converting back and forth between Unicode and bytestrings. * ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')`` is essentially the opposite of ``smart_unicode()``. It forces the first - argument to a bytestring. The ``strings_only`` parameter, if set to True, - will result in Python integers, booleans and ``None`` not being - converted to a string (they keep their original types). This is slightly - different semantics from Python's builtin ``str()`` function, but the - difference is needed in a few places within Django's internals. + argument to a bytestring. The ``strings_only`` parameter has the same + behaviour as for ``smart_unicode()`` and ``force_unicode()``. This is + slightly different semantics from Python's builtin ``str()`` function, + but the difference is needed in a few places within Django's internals. Normally, you'll only need to use ``smart_unicode()``. Call it as early as possible on any input data that might be either Unicode or a bytestring, and diff --git a/tests/modeltests/basic/models.py b/tests/modeltests/basic/models.py index 58770ef2ce..2f4b932fe0 100644 --- a/tests/modeltests/basic/models.py +++ b/tests/modeltests/basic/models.py @@ -152,7 +152,7 @@ TypeError: 'foo' is an invalid keyword argument for this function >>> a6 = Article(pub_date=datetime(2005, 7, 31)) >>> a6.save() >>> a6.headline -'Default headline' +u'Default headline' # For DateTimeFields, Django saves as much precision (in seconds) as you # give it. diff --git a/tests/modeltests/field_defaults/models.py b/tests/modeltests/field_defaults/models.py index 23c4733b8f..1132f1ca41 100644 --- a/tests/modeltests/field_defaults/models.py +++ b/tests/modeltests/field_defaults/models.py @@ -42,7 +42,7 @@ __test__ = {'API_TESTS':""" # Access database columns via Python attributes. >>> a.headline -'Default headline' +u'Default headline' # make sure the two dates are sufficiently close >>> d = now - a.pub_date diff --git a/tests/regressiontests/datastructures/tests.py b/tests/regressiontests/datastructures/tests.py index 3920e1ca40..b58ee79693 100644 --- a/tests/regressiontests/datastructures/tests.py +++ b/tests/regressiontests/datastructures/tests.py @@ -55,6 +55,14 @@ True >>> print repr(d) {'one': 'not one', 'two': 'two', 'three': 'three'} +Init from sequence of tuples +>>> d = SortedDict(( +... (1, "one"), +... (0, "zero"), +... (2, "two"))) +>>> print repr(d) +{1: 'one', 0: 'zero', 2: 'two'} + ### DotExpandedDict ############################################################ >>> d = DotExpandedDict({'person.1.firstname': ['Simon'], 'person.1.lastname': ['Willison'], 'person.2.firstname': ['Adrian'], 'person.2.lastname': ['Holovaty']}) diff --git a/tests/regressiontests/i18n/models.py b/tests/regressiontests/i18n/models.py index e69de29bb2..e1eefb8477 100644 --- a/tests/regressiontests/i18n/models.py +++ b/tests/regressiontests/i18n/models.py @@ -0,0 +1,12 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +class TestModel(models.Model): + text = models.CharField(max_length=10, default=_('Anything')) + +__test__ = {'API_TESTS': ''' +>>> tm = TestModel() +>>> tm.save() +''' +} + diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py index 8a7d2bee3e..99204451e4 100644 --- a/tests/regressiontests/i18n/tests.py +++ b/tests/regressiontests/i18n/tests.py @@ -30,4 +30,12 @@ True >>> s4 = ugettext_lazy('Some other string') >>> s == s4 False + +unicode(string_concat(...)) should not raise a TypeError - #4796 + +>>> import django.utils.translation +>>> reload(django.utils.translation) + +>>> unicode(django.utils.translation.string_concat("dja", "ngo")) +u'django' """