% vs {} string formatting for public APIs

167 views
Skip to first unread message

Jon Dufresne

unread,
Feb 18, 2016, 12:30:35 AM2/18/16
to django-d...@googlegroups.com
Hi,

I noticed that some Django public APIs use the % old-style string
formatting while others use the {} new-style formatting.

For example:

{} style

* success_url [0] (Converted to {} in 1.8)
* format_html [1]

% style

* ValidationError [2]
* related_name [3]


Is this difference intentional?

As success_url recently moved to {}, I'm guessing {} is Django's
preferred style?

If this different is not intentional, I would like to propose a change
to ValidationError to use the {} style formatting. This change would
go through the same deprecation path as used by success_url. Thoughts?

I think this would create a greater API consistency throughout the
framework. I think using a single, consistent string formatting API
follows the design philosophy "principle of least surprise".

Ultimately, I don't care what format is preferred, but I think one
should be used consistently.

I have created a proof of concept as to what this would mean as a
change. The change still requires new tests and docs; so it still WIP.

https://github.com/django/django/compare/master...jdufresne:remove-percent-placeholder

If there is support for this change, I would like to follow through a
ticket and finished PR.

Cheers,
Jon


[0] https://docs.djangoproject.com/en/1.9/ref/class-based-views/mixins-editing/#django.views.generic.edit.ModelFormMixin.success_url
[1] https://docs.djangoproject.com/en/1.9/ref/utils/#django.utils.html.format_html
[2] https://docs.djangoproject.com/en/1.9/ref/forms/validation/#raising-validationerror
[3] https://docs.djangoproject.com/en/1.9/topics/db/models/#be-careful-with-related-name

Tim Graham

unread,
Feb 22, 2016, 8:15:12 AM2/22/16
to Django developers (Contributions to Django itself)
As Claude noted in the ticket for the success_url change:

"I think that using the old percent-based interpolation method in get_success_url was not very wise, considering that % is a common escape marker in URLs. I'd suggest using the new format interpolation method to elude conflicts with escaping percent characters in URLs."
https://code.djangoproject.com/ticket/24133

I guess I don't see much downside to making the change as you suggested except that it could be quite tedious for large projects to adapt.

Claude Paroz

unread,
Feb 22, 2016, 1:48:28 PM2/22/16
to Django developers (Contributions to Django itself)
Hello,

I don't see much gain with that change, except for specific cases. This would also bring a bunch of compatibility issues. I'd rather make the change when it does bring something. I understand your consistency argument, but we need to balance that with the work generated by the change in all existin projects. A -0 from me.

Claude

James Bennett

unread,
Feb 22, 2016, 2:03:46 PM2/22/16
to django-d...@googlegroups.com
The only argument I see for format() over the % operator is that bytes objects explicitly do not have the format() method and so it'll catch errors where a bytes object is passed to something expecting a string.

But since we're already Unicode-ifying everything at the boundaries and have been since before Python 3 existed, I don't think there's much gain from that, and it's not like %-formatting is going away. So I'd argue that it's fine to keep things as they are for now, use format() in future commits if it's cleaner, or just adopt a policy of "if you're in there making a change and it won't break back compat, feel free to update to format() while you're at it" for people doing patches, rather than try to force all usage to convert in one go.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/5c9a0cfa-d618-470e-9530-522b0466d6f8%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages