UseFstringRule

Encourages the use of f-string instead of %-formatting or .format() for high code quality and efficiency.

Following two cases not covered:

  1. arguments length greater than 30 characters: for better readibility reason

    For example:

    1: this is the answer: %d” % (a_long_function_call() + b_another_long_function_call()) 2: f”this is the answer: {a_long_function_call() + b_another_long_function_call()}” 3: result = a_long_function_call() + b_another_long_function_call() f”this is the answer: {result}”

    Line 1 is more readable than line 2. Ideally, we’d like developers to manually fix this case to line 3

  2. only %s placeholders are linted against for now. We leave it as future work to support other placeholders.

    For example, %d raises TypeError for non-numeric objects, whereas f“{x:d}” raises ValueError. This discrepancy in the type of exception raised could potentially break the logic in the code where the exception is handled

Message

Do not use printf style formatting or .format(). Use f-string instead to be more readable and efficient. See https://www.python.org/dev/peps/pep-0498/

Has Autofix: Yes

VALID Code Examples

# 1:

somebody='you'; f"Hey, {somebody}."

# 2:

"hey"

# 3:

"hey" + "there"

# 4:

b"a type %s" % var

INVALID Code Examples

# 1:

"Hey, {somebody}.".format(somebody="you")

# 2:

"%s" % "hi"

Autofix:

---
+++
@@ -1 +1 @@
-"%s" % "hi"
+f"{'hi'}"

# 3:

"a name: %s" % name

Autofix:

---
+++
@@ -1 +1 @@
-"a name: %s" % name
+f"a name: {name}"

# 4:

"an attribute %s ." % obj.attr

Autofix:

---
+++
@@ -1 +1 @@
-"an attribute %s ." % obj.attr
+f"an attribute {obj.attr} ."

# 5:

r"raw string value=%s" % val

Autofix:

---
+++
@@ -1 +1 @@
-r"raw string value=%s" % val
+fr"raw string value={val}"

# 6:

"{%s}" % val

Autofix:

---
+++
@@ -1 +1 @@
-"{%s}" % val
+f"{{{val}}}"

# 7:

"{%s" % val

Autofix:

---
+++
@@ -1 +1 @@
-"{%s" % val
+f"{{{val}"

# 8:

"The type of var: %s" % type(var)

Autofix:

---
+++
@@ -1 +1 @@
-"The type of var: %s" % type(var)
+f"The type of var: {type(var)}"

# 9:

"%s" % obj.this_is_a_very_long_expression(parameter)["a_very_long_key"]

# 10:

"type of var: %s, value of var: %s" % (type(var), var)

Autofix:

---
+++
@@ -1 +1 @@
-"type of var: %s, value of var: %s" % (type(var), var)
+f"type of var: {type(var)}, value of var: {var}"

# 11:

'%s" double quote is used' % var

Autofix:

---
+++
@@ -1 +1 @@
-'%s" double quote is used' % var
+f'{var}" double quote is used'

# 12:

"var1: %s, var2: %s, var3: %s, var4: %s" % (class_object.attribute, dict_lookup["some_key"], some_module.some_function(), var4)

Autofix:

---
+++
@@ -1 +1 @@
-"var1: %s, var2: %s, var3: %s, var4: %s" % (class_object.attribute, dict_lookup["some_key"], some_module.some_function(), var4)
+f"var1: {class_object.attribute}, var2: {dict_lookup['some_key']}, var3: {some_module.some_function()}, var4: {var4}"

# 13:

"a list: %s" % " ".join(var)

Autofix:

---
+++
@@ -1 +1 @@
-"a list: %s" % " ".join(var)
+f"a list: {' '.join(var)}"