rspec/rules/S3457/python/rule.adoc

71 lines
3.0 KiB
Plaintext
Raw Normal View History

2021-01-27 13:42:22 +01:00
Formatting strings, either with the ``++%++`` operator or ``++str.format++`` method, requires a valid string and arguments matching this string's replacement fields.
2020-06-22 13:16:10 +02:00
2021-02-02 15:02:10 +01:00
2021-01-27 13:42:22 +01:00
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.
2020-06-22 13:16:10 +02:00
2021-02-02 15:02:10 +01:00
2020-06-22 13:16:10 +02:00
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.
2021-02-02 15:02:10 +01:00
2020-06-22 13:16:10 +02:00
This rule raises an issue when:
2021-01-27 13:42:22 +01:00
* 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.
2020-06-22 13:16:10 +02:00
* 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
2020-06-22 13:16:10 +02:00
----
"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.
2020-06-22 13:16:10 +02:00
----
== Compliant Solution
2020-06-22 13:16:10 +02:00
----
"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")
2020-06-22 13:16:10 +02:00
----
== See
2020-06-22 13:16:10 +02:00
* https://docs.python.org/3/library/string.html#format-string-syntax[Python documentation - Format String Syntax]
* https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting[Python documentation - printf-style String Formatting]
* https://docs.python.org/3/howto/logging.html#loggers[Python documentation - Loggers]
* https://docs.python.org/3/howto/logging-cookbook.html#using-particular-formatting-styles-throughout-your-application[Python documentation - Using particular formatting styles throughout your application]
* https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals[Python documentation - Formatted string literals]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
include::message.adoc[]
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]