Opened 21 months ago

Last modified 4 months ago

#29988 new Cleanup/optimization

Use f-strings for string formatting once support for Python 3.5 is dropped

Reported by: Jaap Roes Owned by: nobody
Component: Core (Other) Version:
Severity: Normal Keywords: fstrings python3.6
Cc: Tom Forbes Triage Stage: Someday/Maybe
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The end of life date for Python 3.5 is 2020-09-13. This means that the next version of Django after this date (earliest 3.1?) can start using Literal String Interpolation (f-strings) for string formatting.

Not only are f-strings very programmer friendly, they are also very fast (source: A Closer Look At How Python f-strings Work).

Change History (8)

comment:1 Changed 21 months ago by Jaap Roes

Current master has 193 matches for find . -type f -name "*.py" -exec grep -n "['\"]\.format(" {} + | wc -l. (All direct invocations of the format method on a string literal).

There are 3435 matches for find . -type f -name "*.py" -exec grep -n "['\"] %" {} + | wc -l (All uses of the % operator on a string literal).

There's probably many more places where .format or % formatting is used on a variable string.

EDIT: There's also 435 matches for string concatenation (find . -type f -name "*.py" -exec grep -En "(['\"] \+)|(\+ ['\"])" {} + | wc -l)

Last edited 21 months ago by Jaap Roes (previous) (diff)

comment:2 Changed 21 months ago by Tim Graham

Component: UncategorizedCore (Other)
Triage Stage: UnreviewedSomeday/Maybe

See the django-developers discussion for some concerns (e.g. no i18n support and Florian's comment, "Knowing what certain members of the core team think about those f-strings, I think there will be first a big discussion if we will allow them at all in Django's codebase.").

comment:3 in reply to:  2 Changed 21 months ago by Jaap Roes

That discussion (and the one linked to) seem to be more about (or digress into) using .format instead of % formatting. I'm not in favor of going through and replacing all % formatting with .format calls. Instead Django should just start using a f-strings feature ("Literal String Interpolation") introduced in Python 3.6 when/where possible.

I'm aware of the concern about i18n, but a lot of the string formatting/concatenation in Django isn't translatable text and therefore isn't affected by that issue at all.

This is really more about replacing code like this:

path=handler.__module__ + '.' + handler.__qualname__, with path=f'{handler.__module__}.{handler.__qualname__}'

return "{}({}, {})".format(self.__class__.__name__, self.sql, self.params) with return f'{self.__class__.__name__}({self.sql}, {self.params})'

and sql = '%s %s%s ON (%s)' % (self.join_type, qn(self.table_name), alias_str, on_clause_sql) with sql = f'{self.join_type} {qn(self.table_name)}{alias_str} ON ({on_clause_sql})'

Which (arguably) benefits the readability and can have a positive performance impact on the Django code base.

comment:4 Changed 21 months ago by Tom Forbes

Cc: Tom Forbes added

comment:5 Changed 4 months ago by Jon Dufresne

Has patch: set

A first pass that only modifies simple uses of .format() such that the string expressions are shorter, are not translated strings, and do not nest quotes.

https://github.com/django/django/pull/12650

comment:6 Changed 4 months ago by Claude Paroz

I'm in favor of this change. However, I'm a bit hesitant for error messages. They are not translatable now, but they could in the future (and most should IMHO, but this is another story).

comment:7 Changed 4 months ago by Paolo Melchiorre

Django 2.2 is the last to support Python 3.5 so I'm in favor of using f-strings in Django 3.1 for the readability improvement.

Last edited 4 months ago by Paolo Melchiorre (previous) (diff)

comment:8 Changed 4 months ago by Simon Charette

I am in favor well where it makes sense and has clear readability benefits. I don't have strong rules to provide but I've already seen this feature abused in the wild to compose complex formatting string which makes hard to differentiate placeholders from their delimiters when function calls are involved.

I also share you Claude's concerns about error messages and logging message templates.

Note: See TracTickets for help on using tickets.
Back to Top