diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 5812b7e55e..148afe0e38 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -99,7 +99,7 @@ SERVER_EMAIL = 'root@localhost' SEND_BROKEN_LINK_EMAILS = False # Database connection info. -DATABASE_ENGINE = '' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. +DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. DATABASE_NAME = '' # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. diff --git a/django/conf/locale/es/LC_MESSAGES/django.mo b/django/conf/locale/es/LC_MESSAGES/django.mo index c7b992ae23..8edce68c53 100644 Binary files a/django/conf/locale/es/LC_MESSAGES/django.mo and b/django/conf/locale/es/LC_MESSAGES/django.mo differ diff --git a/django/conf/locale/es/LC_MESSAGES/django.po b/django/conf/locale/es/LC_MESSAGES/django.po index 0fbea3c7ca..9c68183113 100644 --- a/django/conf/locale/es/LC_MESSAGES/django.po +++ b/django/conf/locale/es/LC_MESSAGES/django.po @@ -1,22 +1,22 @@ # translation of django.po to Castellano # This file is distributed under the same license as the PACKAGE package. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Copyright (C) 2007 THE PACKAGE'S COPYRIGHT HOLDER. # # Ricardo Javier Cárdenes Medina , 2005. # Ricardo Javier Cardenes Medina , 2005. # AgarFu , 2007. +# Mario Gonzalez msgid "" msgstr "" "Project-Id-Version: django\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-02-24 17:08+0000\n" -"PO-Revision-Date: 2007-02-24 17:12+0000\n" +"PO-Revision-Date: 2007-02-24 18:02-0600\n" "Last-Translator: AgarFu \n" -"Language-Team: Castellano \n" +"Language-Team: Castellano \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: utils/dates.py:6 @@ -187,7 +187,7 @@ msgstr[1] "meses" msgid "week" msgid_plural "weeks" msgstr[0] "semana" -msgstr[1] "" +msgstr[1] "semanas" #: utils/timesince.py:15 msgid "day" @@ -209,23 +209,23 @@ msgstr[1] "minutos" #: utils/translation/trans_real.py:362 msgid "DATE_FORMAT" -msgstr "FORMATO_DE_FECHA" +msgstr "j N Y" #: utils/translation/trans_real.py:363 msgid "DATETIME_FORMAT" -msgstr "FORMATO_DE_FECHA_Y_HORA" +msgstr "j N Y P" #: utils/translation/trans_real.py:364 msgid "TIME_FORMAT" -msgstr "FORMATO_DE_HORA" +msgstr "P" #: utils/translation/trans_real.py:380 msgid "YEAR_MONTH_FORMAT" -msgstr "FORMATO_DE_AÑO_Y_MES" +msgstr "F Y" #: utils/translation/trans_real.py:381 msgid "MONTH_DAY_FORMAT" -msgstr "FORMATO_DE_MES_Y_DÍA" +msgstr "j \\de F" #: conf/global_settings.py:39 msgid "Arabic" @@ -340,9 +340,8 @@ msgid "Slovak" msgstr "Eslovaco" #: conf/global_settings.py:67 -#, fuzzy msgid "Slovenian" -msgstr "Eslovaco" +msgstr "Esloveno" #: conf/global_settings.py:68 msgid "Serbian" @@ -354,7 +353,7 @@ msgstr "Sueco" #: conf/global_settings.py:70 msgid "Tamil" -msgstr "" +msgstr "Tamil" #: conf/global_settings.py:71 msgid "Turkish" @@ -388,14 +387,12 @@ msgid "Please enter a valid %s." msgstr "Por favor, introduzca un %s válido." #: db/models/fields/related.py:642 -#, fuzzy msgid "Separate multiple IDs with commas." -msgstr " Separe múltiples IDs con comas." +msgstr "Separe múltiples IDs con comas." #: db/models/fields/related.py:644 -#, fuzzy msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one." -msgstr "Pulse \"Control\" o \"Command\" en un Mac para escoger más de uno." +msgstr "Mantenga presionado \"Control\", o \"Command\" en un Mac, para seleccionar más de uno." #: db/models/fields/related.py:691 #, python-format @@ -462,9 +459,9 @@ msgid "Select a valid choice. %s is not one of the available choices." msgstr "Escoja una opción válida; '%s' no es una de las opciones disponibles." #: newforms/fields.py:101 newforms/fields.py:254 -#, fuzzy, python-format +#, python-format msgid "Ensure this value has at most %d characters." -msgstr "Asegúrese de que su texto tiene menos de %s carácter." +msgstr "Asegúrese de que su texto tiene a lo más %d caracteres." #: newforms/fields.py:103 newforms/fields.py:256 #, python-format @@ -478,7 +475,7 @@ msgstr "Introduzca un n #: newforms/fields.py:128 #, python-format msgid "Ensure this value is less than or equal to %s." -msgstr "Asegñurese de que este valor es menor o igual a %s." +msgstr "Asegúrese de que este valor es menor o igual a %s." #: newforms/fields.py:130 #, python-format @@ -533,11 +530,10 @@ msgid "This value must contain only letters, numbers and underscores." msgstr "Este valor debe contener sólo letras, números y guiones bajos." #: core/validators.py:68 -#, fuzzy msgid "" "This value must contain only letters, numbers, underscores, dashes or " "slashes." -msgstr "Este valor debe contener sólo letras, números, guiones bajos y barras (/)." +msgstr "Este valor debe contener letras, números, guiones bajos o barras solamente." #: core/validators.py:72 msgid "This value must contain only letters, numbers, underscores or hyphens." @@ -659,8 +655,8 @@ msgstr "Introduzca una abreviatura v #, python-format msgid "Watch your mouth! The word %s is not allowed here." msgid_plural "Watch your mouth! The words %s are not allowed here." -msgstr[0] "¡Vigila tu boca! Aquí no admitimos la palabra %s." -msgstr[1] "¡Vigila tu boca! Aquí no admitimos las palabras %s." +msgstr[0] "¡Cuida tu vocabulario! Aquí no admitimos la palabra %s." +msgstr[1] "¡Cuida tu vocabulario! Aquí no admitimos las palabras %s." #: core/validators.py:272 #, python-format @@ -690,9 +686,9 @@ msgid "Duplicate values are not allowed." msgstr "No se admiten valores duplicados." #: core/validators.py:364 -#, fuzzy, python-format +#, python-format msgid "This value must be between %(lower)s and %(upper)s." -msgstr "Este valor no debe ser mayor que %s." +msgstr "Este valor debe estar entre %(lower)s y %(upper)s." #: core/validators.py:367 #, python-format @@ -725,7 +721,7 @@ msgstr[1] "" "total." #: core/validators.py:423 -#, fuzzy, python-format +#, python-format msgid "Please enter a valid decimal number with a whole part of at most %s digit." msgid_plural "Please enter a valid decimal number with a whole part of at most %s digits." msgstr[0] "" @@ -901,13 +897,12 @@ msgid "template name" msgstr "nombre de plantilla" #: contrib/flatpages/models.py:13 -#, fuzzy msgid "" "Example: 'flatpages/contact_page.html'. If this isn't provided, the system " "will use 'flatpages/default.html'." msgstr "" -"Ejemplo: 'flatpages/contact_page'. Si no lo proporciona, el sistema usará " -"'flatpages/default'." +"Ejemplo: 'flatpages/contact_page.html'. Si no es proporcionado, el sistema usará " +"'flatpages/default.html'." #: contrib/flatpages/models.py:14 msgid "registration required" @@ -926,9 +921,8 @@ msgid "flat pages" msgstr "páginas estáticas" #: contrib/auth/views.py:39 -#, fuzzy msgid "Logged out" -msgstr "Terminar sesión" +msgstr "Sesión terminada" #: contrib/auth/models.py:38 contrib/auth/models.py:57 msgid "name" @@ -1225,12 +1219,10 @@ msgid "approved by staff" msgstr "aprobado por el staff" #: contrib/comments/models.py:176 -#, fuzzy msgid "free comment" msgstr "Comentario libre" #: contrib/comments/models.py:177 -#, fuzzy msgid "free comments" msgstr "Comentarios libres" @@ -1243,12 +1235,10 @@ msgid "score date" msgstr "fecha de la puntuación" #: contrib/comments/models.py:237 -#, fuzzy msgid "karma score" msgstr "Punto karma" #: contrib/comments/models.py:238 -#, fuzzy msgid "karma scores" msgstr "Puntos karma" @@ -1273,12 +1263,10 @@ msgid "flag date" msgstr "fecha de la marca" #: contrib/comments/models.py:268 -#, fuzzy msgid "user flag" msgstr "Marca de usuario" #: contrib/comments/models.py:269 -#, fuzzy msgid "user flags" msgstr "Marcas de usuario" @@ -1292,12 +1280,10 @@ msgid "deletion date" msgstr "fecha de eliminación" #: contrib/comments/models.py:280 -#, fuzzy msgid "moderator deletion" msgstr "Eliminación de moderador" #: contrib/comments/models.py:281 -#, fuzzy msgid "moderator deletions" msgstr "Eliminaciones de moderador" @@ -1758,7 +1744,7 @@ msgstr "Acci #: contrib/admin/templates/admin/object_history.html:26 msgid "DATE_WITH_TIME_FULL" -msgstr "FECHA_CON_TIEMP_COMPLETO" +msgstr "j M Y P" #: contrib/admin/templates/admin/object_history.html:36 msgid "" @@ -2330,9 +2316,8 @@ msgid "Add user" msgstr "Añadir usuario" #: contrib/admin/views/auth.py:57 -#, fuzzy msgid "Password changed successfully." -msgstr "Cambio de clave exitoso" +msgstr "La clave se ha cambiado exitosamente." #: contrib/admin/views/auth.py:64 #, python-format diff --git a/django/conf/locale/sv/LC_MESSAGES/djangojs.mo b/django/conf/locale/sv/LC_MESSAGES/djangojs.mo index c73aa30560..d099af156c 100644 Binary files a/django/conf/locale/sv/LC_MESSAGES/djangojs.mo and b/django/conf/locale/sv/LC_MESSAGES/djangojs.mo differ diff --git a/django/conf/locale/sv/LC_MESSAGES/djangojs.po b/django/conf/locale/sv/LC_MESSAGES/djangojs.po index 4d0c1e9034..c677dc7d9c 100644 --- a/django/conf/locale/sv/LC_MESSAGES/djangojs.po +++ b/django/conf/locale/sv/LC_MESSAGES/djangojs.po @@ -21,7 +21,7 @@ msgstr "" #: contrib/admin/media/js/SelectFilter2.js:33 #, perl-format msgid "Available %s" -msgstr "" +msgstr "Tillgänglig %s" #: contrib/admin/media/js/SelectFilter2.js:41 #, fuzzy @@ -30,39 +30,39 @@ msgstr "Välj en tidpunkt" #: contrib/admin/media/js/SelectFilter2.js:46 msgid "Add" -msgstr "" +msgstr "Lägg till" #: contrib/admin/media/js/SelectFilter2.js:48 msgid "Remove" -msgstr "" +msgstr "Tag bort" #: contrib/admin/media/js/SelectFilter2.js:53 #, perl-format msgid "Chosen %s" -msgstr "" +msgstr "Valde %s" #: contrib/admin/media/js/SelectFilter2.js:54 msgid "Select your choice(s) and click " -msgstr "" +msgstr "Välj ditt/dina val och klicka " #: contrib/admin/media/js/SelectFilter2.js:59 msgid "Clear all" -msgstr "" +msgstr "Avmarkera alla" #: contrib/admin/media/js/dateparse.js:26 #: contrib/admin/media/js/calendar.js:24 msgid "" "January February March April May June July August September October November " "December" -msgstr "" +msgstr "Januari Februari Mars April Maj Juni Juli Augusti September Oktober November December" #: contrib/admin/media/js/dateparse.js:27 msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday" -msgstr "" +msgstr "Söndag Mondag Tisdag Onsdag Torsdag Fredag Lördag" #: contrib/admin/media/js/calendar.js:25 msgid "S M T W T F S" -msgstr "" +msgstr "S M T O T F L" #: contrib/admin/media/js/admin/DateTimeShortcuts.js:45 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:80 @@ -92,7 +92,7 @@ msgstr "Mitt pÃ¥ dagen" #: contrib/admin/media/js/admin/DateTimeShortcuts.js:87 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:168 msgid "Cancel" -msgstr "Ã…ngra" +msgstr "Avbryt" #: contrib/admin/media/js/admin/DateTimeShortcuts.js:111 #: contrib/admin/media/js/admin/DateTimeShortcuts.js:162 diff --git a/django/conf/project_template/settings.py b/django/conf/project_template/settings.py index 4fc03c809b..d36553b84d 100644 --- a/django/conf/project_template/settings.py +++ b/django/conf/project_template/settings.py @@ -9,7 +9,7 @@ ADMINS = ( MANAGERS = ADMINS -DATABASE_ENGINE = '' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. +DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. DATABASE_NAME = '' # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. diff --git a/django/conf/urls/admin_password_reset.py b/django/conf/urls/admin_password_reset.py deleted file mode 100644 index afa078205a..0000000000 --- a/django/conf/urls/admin_password_reset.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.conf.urls.defaults import * - -urlpatterns = patterns('django.views', - (r'^$', 'registration.passwords.password_reset', {'is_admin_site' : True}), - (r'^done/$', 'registration.passwords.password_reset_done'), -) diff --git a/django/conf/urls/registration.py b/django/conf/urls/registration.py deleted file mode 100644 index 9b41e434f9..0000000000 --- a/django/conf/urls/registration.py +++ /dev/null @@ -1,19 +0,0 @@ -from django.conf.urls.defaults import * - -urlpatterns = patterns('', - (r'^login/$', 'django.contrib.auth.views.login'), - (r'^logout/$', 'django.contrib.auth.views.logout'), - (r'^login_another/$', 'django.contrib.auth.views.logout_then_login'), - - (r'^register/$', 'ellington.registration.views.registration.signup'), - (r'^register/(?P\w{32})/$', 'ellington.registration.views.registration.register_form'), - - (r'^profile/$', 'ellington.registration.views.profile.profile'), - (r'^profile/welcome/$', 'ellington.registration.views.profile.profile_welcome'), - (r'^profile/edit/$', 'ellington.registration.views.profile.edit_profile'), - - (r'^password_reset/$', 'django.contrib.auth.views.password_reset'), - (r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'), - (r'^password_change/$', 'django.contrib.auth.views.password_change'), - (r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'), -) diff --git a/django/template/__init__.py b/django/template/__init__.py index 90fd13e1ce..678d19293c 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -667,7 +667,11 @@ def resolve_variable(path, context): except (TypeError, AttributeError): try: # list-index lookup current = current[int(bits[0])] - except (IndexError, ValueError, KeyError): + except (IndexError, # list index out of range + ValueError, # invalid literal for int() + KeyError, # current is a dict without `int(bits[0])` key + TypeError, # unsubscriptable object + ): raise VariableDoesNotExist("Failed lookup for key [%s] in %r", (bits[0], current)) # missing attribute except Exception, e: if getattr(e, 'silent_variable_failure', False): diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index c20da05144..94ab76c483 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -16,6 +16,9 @@ class MergeDict(object): def __contains__(self, key): return self.has_key(key) + + def __copy__(self): + return self.__class__(*self.dicts) def get(self, key, default=None): try: @@ -42,6 +45,10 @@ class MergeDict(object): if dict.has_key(key): return True return False + + def copy(self): + """ returns a copy of this object""" + return self.__copy__() class SortedDict(dict): "A dictionary that keeps its keys in the order in which they're inserted." diff --git a/docs/authentication.txt b/docs/authentication.txt index f5736a3cd7..5186c5672c 100644 --- a/docs/authentication.txt +++ b/docs/authentication.txt @@ -86,10 +86,10 @@ objects in the same way as any other `Django model`_:: myuser.groups.add(group, group,...) myuser.groups.remove(group, group,...) myuser.groups.clear() - myuser.permissions = [permission_list] - myuser.permissions.add(permission, permission, ...) - myuser.permissions.remove(permission, permission, ...] - myuser.permissions.clear() + myuser.user_permissions = [permission_list] + myuser.user_permissions.add(permission, permission, ...) + myuser.user_permissions.remove(permission, permission, ...] + myuser.user_permissions.clear() In addition to those automatic API methods, ``User`` objects have the following custom methods: diff --git a/docs/db-api.txt b/docs/db-api.txt index 99bb30054b..3dc0efbabd 100644 --- a/docs/db-api.txt +++ b/docs/db-api.txt @@ -1621,6 +1621,15 @@ For example, this deletes all ``Entry`` objects with a ``pub_date`` year of Entry.objects.filter(pub_date__year=2005).delete() +When Django deletes an object, it emulates the behavior of the SQL +constraint ``ON DELETE CASCADE`` -- in other words, any objects which +had foreign keys pointing at the object to be deleted will be deleted +along with it. For example:: + + b = Blog.objects.get(pk=1) + # This will delete the Blog and all of its Entry objects. + b.delete() + Note that ``delete()`` is the only ``QuerySet`` method that is not exposed on a ``Manager`` itself. This is a safety mechanism to prevent you from accidentally requesting ``Entry.objects.delete()``, and deleting *all* the entries. If you diff --git a/docs/tutorial04.txt b/docs/tutorial04.txt index 7b19bdaeaf..b1c8c7d4fc 100644 --- a/docs/tutorial04.txt +++ b/docs/tutorial04.txt @@ -206,6 +206,21 @@ for the polls app, we manually specify a template name for the results view: ``template_name='polls/results.html'``. Otherwise, both views would use the same template. Note that we use ``dict()`` to return an altered dictionary in place. +.. note:: ``all()`` is lazy + + It might look a little frightening to see ``Poll.objects.all()`` being used + in a detail view which only needs one ``Poll`` object, but don't worry; + ``Poll.objects.all()`` is actually a special object called a ``QuerySet``, + which is "lazy" and doesn't hit your database until it absolutely has to. By + the time the database query happens, the ``object_detail`` generic view will + have narrowed its scope down to a single object, so the eventual query will + only select one row from the database. + + If you'd like to know more about how that works, The Django database API + documentation `explains the lazy nature of QuerySet objects`_. + +.. _explains the lazy nature of QuerySet objects: ../db_api/#querysets-are-lazy + In previous parts of the tutorial, the templates have been provided with a context that contains the ``poll`` and ``latest_poll_list`` context variables. However, the generic views provide the variables ``object`` and ``object_list`` as context. diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt index da4be2c746..3f51ce4b91 100644 --- a/docs/url_dispatch.txt +++ b/docs/url_dispatch.txt @@ -390,6 +390,13 @@ to pass metadata and options to views. .. _generic views: ../generic_views/ .. _syndication framework: ../syndication/ +.. admonition:: Dealing with conflicts + + It's possible to have a URL pattern which captures named keyword arguments, + and also passes arguments with the same names in its dictionary of extra + arguments. When this happens, the arguments in the dictionary will be used + instead of the arguments captured in the URL. + Passing extra options to ``include()`` -------------------------------------- diff --git a/tests/regressiontests/datastructures/__init__.py b/tests/regressiontests/datastructures/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regressiontests/datastructures/models.py b/tests/regressiontests/datastructures/models.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regressiontests/datastructures/tests.py b/tests/regressiontests/datastructures/tests.py new file mode 100644 index 0000000000..624e7a50bf --- /dev/null +++ b/tests/regressiontests/datastructures/tests.py @@ -0,0 +1,34 @@ +""" +# Tests for stuff in django.utils.datastructures. + +>>> from django.utils.datastructures import * + +### MergeDict ################################################################# + +>>> d1 = {'chris':'cool','camri':'cute','cotton':'adorable','tulip':'snuggable', 'twoofme':'firstone'} +>>> d2 = {'chris2':'cool2','camri2':'cute2','cotton2':'adorable2','tulip2':'snuggable2'} +>>> d3 = {'chris3':'cool3','camri3':'cute3','cotton3':'adorable3','tulip3':'snuggable3'} +>>> d4 = {'twoofme':'secondone'} +>>> md = MergeDict( d1,d2,d3 ) +>>> md['chris'] +'cool' +>>> md['camri'] +'cute' +>>> md['twoofme'] +'firstone' +>>> md2 = md.copy() +>>> md2['chris'] +'cool' + +### MultiValueDict ########################################################## + +>>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']}) +>>> d['name'] +'Simon' +>>> d.getlist('name') +['Adrian', 'Simon'] +>>> d.get('lastname', 'nonexistent') +'nonexistent' +>>> d.setlist('lastname', ['Holovaty', 'Willison']) + +""" \ No newline at end of file diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 3bae6a2609..0165824951 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -127,6 +127,29 @@ class Templates(unittest.TestCase): # Fail silently when accessing a non-simple method 'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, ("","INVALID")), + # List-index syntax allows a template to access a certain item of a subscriptable object. + 'list-index01': ("{{ var.1 }}", {"var": ["first item", "second item"]}, "second item"), + + # Fail silently when the list index is out of range. + 'list-index02': ("{{ var.5 }}", {"var": ["first item", "second item"]}, ("", "INVALID")), + + # Fail silently when the variable is not a subscriptable object. + 'list-index03': ("{{ var.1 }}", {"var": None}, ("", "INVALID")), + + # Fail silently when variable is a dict without the specified key. + 'list-index04': ("{{ var.1 }}", {"var": {}}, ("", "INVALID")), + + # Dictionary lookup wins out when dict's key is a string. + 'list-index05': ("{{ var.1 }}", {"var": {'1': "hello"}}, "hello"), + + # But list-index lookup wins out when dict's key is an int, which + # behind the scenes is really a dictionary lookup (for a dict) + # after converting the key to an int. + 'list-index06': ("{{ var.1 }}", {"var": {1: "hello"}}, "hello"), + + # Dictionary lookup wins out when there is a string and int version of the key. + 'list-index07': ("{{ var.1 }}", {"var": {'1': "hello", 1: "world"}}, "hello"), + # Basic filter usage 'basic-syntax21': ("{{ var|upper }}", {"var": "Django is the greatest!"}, "DJANGO IS THE GREATEST!"), @@ -167,7 +190,7 @@ class Templates(unittest.TestCase): 'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, ("12", "1INVALID2")), # In methods that raise an exception without a "silent_variable_attribute" set to True, - # the exception propogates + # the exception propagates 'basic-syntax34': (r'1{{ var.method4 }}2', {"var": SomeClass()}, SomeOtherException), # Escaped backslash in argument