Description

Formatting strings, either with the % operator or str.format method, requires a valid string and arguments matching this string’s replacement fields.

This also applies to loggers from the logging module. Internally they use %-formatting. The only difference is that they will log an error instead of raising an exception when provided arguments are invalid.

Formatted string literals, also called "f-strings", are generally simpler to use, and any syntax mistake will fail at compile time. However it is easy to forget curly braces and it won’t raise any error.

This rule raises an issue when:

  • A string formatted with % will not return the expected string because some arguments are not used.

  • A string formatted with str.format will not return the expected string because some arguments are not used.

  • An "f-string" doesn’t contain any replacement field, which probably means that some curly braces are missing.

  • Loggers will log an error because their message is not formatted properly.

Rule S2275 covers cases where formatting a string will raise an exception.

Noncompliant Code Example

"Error %(message)s" % {"message": "something failed", "extra": "some dead code"}  # Noncompliant. Remove the unused argument "extra" or add a replacement field.

"Error: User {} has not been able to access []".format("Alice", "MyFile")  # Noncompliant. Remove 1 unexpected argument or add a replacement field.

user = "Alice"
resource = "MyFile"
message = f"Error: User [user] has not been able to access [resource]"  # Noncompliant. Add replacement fields or use a normal string instead of an f-string.

import logging
logging.error("Error: User %s has not been able to access %s", "Alice")  # Noncompliant. Add 1 missing argument.

Compliant Solution

"Error %(message)s" % {"message": "something failed"}

"Error: User {} has not been able to access {}".format("Alice", "MyFile")

user = "Alice"
resource = "MyFile"
message = f"Error: User {user} has not been able to access {resource}"

import logging
logging.error("Error: User %s has not been able to access %s", "Alice", "MyFile")

See


Implementation Specification

(visible only on this page)

Message

  • Add replacement fields or use a normal string instead of an f-string.

  • Remove this unused argument.

  • Remove X unused positional arguments.

  • Fix this formatted string’s syntax.

  • Name unnamed replacement field(s).

  • Replace formatting argument(s) with a mapping; Replacement fields are named.

  • Use only positional or named fields, don’t mix them.

  • Replace this value with a number as "%d" requires.

  • Replace this value with an integer as "%X" requires.

  • Replace this value with an integer as "*" requires.

  • Add X missing argument(s).

  • Remove X unexpected argument(s); format string expects Y arguments.

  • Replace this key; %-format accepts only string keys.

  • Provide a value for field "X".

  • Remove this unused argument or add a replacement field.


(visible only on this page)

is duplicated by: S3941

on 10 Dec 2015, 09:07:59 Tamas Vajk wrote:

\[~ann.campbell.2] Removed the performance label, as the performance impact is insignificant.

on 10 Dec 2015, 14:44:05 Ann Campbell wrote:

I’ve updated SQALE characteristic to match [~tamas.vajk]