This rule raises an issue when multiple startswith() or endswith() calls on the same string are chained together using
the or operator to check for different prefixes or suffixes.
When you need to check if a string starts or ends with one of several possible values, chaining multiple startswith() or
endswith() calls with the or operator creates unnecessary verbosity and redundancy. Each additional prefix or suffix
requires a separate method call and another or operator, making the condition increasingly difficult to read and maintain.
This pattern is particularly common when validating file extensions, URL protocols, or any scenario where you need to check for multiple valid prefixes or suffixes.
The consolidated form is easier to read and maintain, reducing the cognitive load on developers reviewing or modifying the code. The performance gain from a single consolidated call is modest but accumulates in loops or hot paths.
Replace multiple startswith() or endswith() calls connected by or operators with a single call that uses a
tuple containing all the prefixes or suffixes to check.
Both startswith() and endswith() methods accept a tuple of strings as their first argument. When you pass a tuple, the
method checks if the string starts or ends with any of the values in that tuple. This has two main benefits:
if s.startswith("http://") or s.startswith("https://"): # Noncompliant: use a tuple argument instead
process_url(s)
if s.startswith(("http://", "https://")):
process_url(s)
if filename.endswith(".jpg") or filename.endswith(".png") or filename.endswith(".gif"): # Noncompliant: use a tuple argument instead
display_image(filename)
if filename.endswith((".jpg", ".png", ".gif")):
display_image(filename)
str.startswith()str.endswith()startswith or endswith methods should be used instead of string slicing in condition
expressions