1. Formatted string used as docstring — PTC-W0033
Formatted string literals cannot be used as docstrings, even if they do not include expressions.
If used, the formatted strings are just evaluated as an expression in the function body.
def foo():
f"""This is intended to be the docstring for {__name__}"""
...
The value of foo.__doc__
would be None
here.
2. Unnecessary use of getattr
— PTC-W0034
This is raised when getattr
is used to check if an attribute exists, without specifying a default value.
Missing a default to getattr
will cause an AttributeError
to be raised for non-existent properties, which is the same as when a non-existent property is accessed directly.
It is recommended to either provide a default value to be returned by getattr
if the attribute is not found, or access the attribute directly as there is no additional safety in using getattr
if the attribute name is known ahead of time.
3. hasattr
used to check if the object is callable — PTC-W0035
It is unreliable to use hasattr(object, '__call__')
to check if an object is callabe as it can give wrong results if object
implements custom __getattr__
or its __call__
is itself not callabe. It is recommended to use the callable
built-in instead.
Here’s an example:
In [1]: class FooBar:
...: def __init__(self):
...: self.foo = "Foo"
...: self.bar = "Bar"
...:
...: def __getattr__(self, key):
...: return key
...:
In [2]: instance = FooBar()
When hasattr
is used to check if instance
is callable, it return True
In [3]: hasattr(instance, '__call__')
Out[3]: True
But when checked using the callable
built-in, it returns False
In [4]: callable(instance)
Out[4]: False
When instance
is called, here’s the traceback:
In [5]: instance()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-23-5dd8ea036ab8> in <module>
----> 1 instance()
TypeError: 'FooBar' object is not callable
4. Unnecessary else
/ elif
used after break
— PYL-R1723
break
causes control flow to be disrupted, as it will exit the block.
This makes the else
/ elif
block unnecessary here. This doesn’t mean you can not use it, but it is recommended to remove this else
/ elif
statement for a better readability.
Bad:
def changing_denominators(p, q):
while True:
if q == 0:
break
else:
print(p/q)
q = q - 1
Good:
def changing_denominators(p, q):
while True:
if q == 0:
break
print(p/q)
q = q - 1
5. Unnecessary elif
/ else
block after continue
— PYL-R1724
The else
/ elif
block here is unnecessary because the leading if
block has a continue
statement. This doesn’t mean you cannot use it, but it is recommended to remove this else
/ elif
statement for a better readability.
Bad:
def classify_number(x):
for num in range(x):
if x % 2 == 0:
continue
else:
print(f"{num} is Odd}")
Good:
def classify_number(x):
for num in range(x):
if x % 2 == 0:
continue
print(f"{num} is Odd}")
6. Subprocess run with an ignored non-zero exit — PYL-W1510
subprocess.run
uses a default of check=False
, which means that a nonzero exit code will be
ignored by default, instead of raising an exception.