- FTP000: internal errors
- FTP001 - FTP199: general purpose checks
- FTP200 - FTP219:
flask
andwerkzeug
checks - FTP220 - FTP239:
requests
checks
Error while loading this plugin or any other internal error
Checks if one of the debug modules pdb
, ipdb
, pudb
, wdb
, pdbpp
and debugger
is used
Checks if the debug builtin breakpoint
is used
Checks for usage of datetime.datetime.utcnow
. The value is current UTC time but
without any timezone assigned. Preferred is datetime.datetime.now
with a timezone
parameter.
The check is only active if datetime.datetime.utcnow
is somehow imported.
Checks if a module/file name follows the PEP-8 convention
Find duplicate class fields (multiple assigns to the same name in the class body). No functions or blocks are checked.
Find any usage of unicode directionality formatting characters. These characters are used to display left-to-right/right-to-left text in the same line and are interpreted by the bidi algorithm. However, having these characters in source code can lead to attacks like early returns because the code is executed in another way than written. A normal code review will not detect these issues. The easiest way is to ban these characters. For details see this paper.
Checks for usage of datetime.datetime.utcfromtimestamp
.
The value is current UTC time but without any timezone assigned.
Preferred is datetime.datetime.fromtimestamp
with a timezone parameter.
The check is only active if datetime.datetime.utcfromtimestamp
is somehow imported.
Checks for unnecessary parenthesis, like print((1,2,3))
and also one line return statements
like return (a, b)
.
By default, the parenthesis of a return of a single element tuple is kept.
This can be disabled by using enforce-parens-in-return-single-element-tuple
Checks for classes extending BaseException
Checks if a disallowed developer comment identifier is used. Please refer to the developer comment configuration.
Checks if the tracking id reference in a developer comment is missing. Please refer to the developer comment configuration.
Checks if an invalid tracking id reference in a developer comment is used. Please refer to the developer comment configuration.
Checks if the description of a developer comment is missing. Please refer to the developer comment configuration.
Checks for calls of urllib.parse.urlparse
.
This function can parse a special ;parameters
part inside the path which is not recommended.
The function urllib.parse.urlsplit
does basically the same but ignores the
parameters
part and is therefore faster.
The check is only active if urllib.parse.urlparse
is somehow imported.
Checks for imports of pkg_resources
. This module should not be used anymore as
better and faster alternatives are available in importlib
and its backports
Find usage of python2 metaclass declaration with __metaclass__
inside the class body.
Instead use metaclass=
in the class signature.
Find legacy calls of typing.NamedTuple
. Instead, extend typing.NamedTuple
by creating a new class
Find legacy calls of typing.TypedDict
. Instead, extend typing.TypedDict
by creating a new class
reserved for a future check
Checks if an encoding comment (# -*- coding: utf-8 -*-
) is used.
These comments are not needed in python 3 anymore
Checks if a string value (or a part of it) can be replaced with string.ascii_letters
Checks if a string value (or a part of it) can be replaced with string.ascii_lowercase
Checks if a string value (or a part of it) can be replaced with string.ascii_uppercase
Checks if a string value (or a part of it) can be replaced with string.digits
Checks for isinstance
calls with an one-element tuple
Checks for imports the easteregg modules this
, antigravity
, __hello__
and __phello__
,
Checks for easteregg imports of the __future__
module: braces
and barry_as_FLUFL
.
Find empty doc comments (#:
)
Find enumeration
loops where the index variable is named _
.
Use a classical for loop instead
Checks if any unnecessary future import is used
Checks if percentage formatting is used in logging calls
Checks if a f-string is used in logging calls
Checks if str.format is used in logging calls.
Checks if exc_info=True
is used in exception logging calls. This argument is redundant.
Checks if the deprecated logging method warn
is used.
Checks if exc_info=True
is used in error logging calls. Use exception instead.
Checks if keys used in the extra
dict of logging calls clashes with existing
logging.LogRecord
fields. This can lead to errors during runtime
Checks if float('NaN')
is used, because math.nan
should be preferred
Check if a dunder is used in the middle of the name like a__b
.
Double underscores at the start and at the end are ignored.
Checks if a file is in a folder without an init.py file. The error is reported on the first line of the file. If files are checked which should not be part of a namespace package (e.g. setup.py), a noqa comment or "per-file-ignores" can be used.
Checks if a module is used which is not specified as a requirement. Please refer to the requirement check configuration.
Checks if a class defines a magic method like __hex__
which is legacy from python2 and is no
longer needed
Checks if a function starting with get_
has at least one return or yield statement. The function
will be ignored, if it's a stub (e.g. just has a pass statement or only throws an exception)
Checks if an exception is raised from itself, e.g. raise exc from exc
Checks if a bad function like help
or exit
is called
Checks if an except block only contains a reraise of the caught exception
Checks if a too generic exception (Exception
and BaseException
) is raised
Checks if a float is used as a dict key. Floats have precision errors, so using them as keys is unreliable and can lead to errors
Checks if a single element unpacking is used (e.g. (a,) = my_list
).
It can be simplified to a = mylist[0]
Checks if a print
statement is used
Checks if a pprint.pprint
statement is used
Checks if a pprint.pp
statement is used
Checks if a pprint.PrettyPrinter
statement is used
Checks if a union type annotation can utilize the new syntax of PEP 604. For example,
a: Union[Foo, Bar]
can be rewritten to a: Foo|bar
.
This check is only active when at least one of the following conditions is true:
- running python 3.10+
- a
from __future__ import annotations
import is present in the module - the current code is inside a
typing.TYPE_CHECKING
block
Also, the check will only consider type annotations (to prevent invalid syntax) if at least one of the following conditions is true:
- python 3.9 or below is used
- the code is not inside a
typing.TYPE_CHECKING
block
Checks if an optional type annotations can utilize the new syntax of PEP 604. For example,
a: Optional[Foo]
can be rewritten to a: Foo|None
.
For more details see FTP054
Checks if a builtin alias in the typing
module can be rewritten as the builtin itself
as of PEP 585.
E.g. typing.List[str]
can be changed to list[str]
.
This check is only active when at least one of the following conditions is true:
- running python 3.9+
- a
from __future__ import annotations
import is present in the module - the current code is inside a
typing.TYPE_CHECKING
block
Also, the check will only consider type annotations (to prevent invalid syntax) if at least one of the following conditions is true:
- the code is not inside a
typing.TYPE_CHECKING
block
Checks if relative imports are used
Checks if an unnecessary import alias is used, e.g. import foo as foo
Checks if an argument in a function call has a pointless starred expression.
For single starred expressions, lists, dicts, tuples, sets, strings and bytes are checked.
As an example, foo(*[1, 2, 3])
can be simplified to foo(1, 2, 3)
.
For double starred expressions, only dicts are checked.
An issue is only raised if all keys of the dict are strings, else the dict is not considered
static and will be ignore.
As an example, foo(**{'a': 1, 'b': 2})
can be simplified to foo(a=1, b=2)
.
Checks if a percentage formatting is used
Checks if "".format()
is used
Checks if str.format
is used
Check if contextlib.wraps
is used. The call will work at runtime, but wraps
comes
originally from functools.wraps
and contextlib
doesn't re-export it, so it
should be considered as an implementation detail which is not stable.
Therefore functools.wraps
should be used.
Check if __debug__
is used. This constant is false when python is not started in optimized
-O
mode. Because this mode is basically never used and having code which only runs when not
running in a special mode can have unexpected side effects, this constant should not be used.
Check if collections.namedtuple
is used. typing.NamedTuple
should be used
instead, since it integrates nicer with IDE's and type checkers
Check if an enum.Enum
subclass is used which also extends int
, so e.g.
class MyEnum(Enum, int)
.
For that the alias enum.IntEnum
can be used
Check if an enum.Enum
subclass is used which also extends str
, so e.g.
class MyEnum(Enum, str)
.
For that the alias enum.StrEnum
can be used.
The check is only active for python3.11+
Check if a call of subprocess.run
has the value subprocess.PIPE
assigned
to both stdout
and stderr
. In this case, it can be simplified to capture_output=True
.
Check if a variable has a name which can lead to confusion like pi = 5
or nan = 4
.
Checks for super calls with arguments
Check for assign and return statements.
Normally the check also finds statements like a: int = 2; return a
.
To configure the step to ignore assignments with annotations, use ignore-annotation-in-assign-return
.
By default the check is disabled if the variable name happens to be part of a global/nonlocal statement.
The check is also suppressed, if the assign-return is part of a try
block and in the
corresponding finally
block the variable is used
Checks for unicode string prefixes like u"abc"
Checks for the usage of functools.lru_cache
which can be replaced with
functools.cache
.
The check is only active if functools.lru_cache
is somehow imported.
Checks if a functools.cache
or functools.lru_cache
is used on a class method.
Since the self
argument is cached as well, garbage collection is blocked, leading to memory leaks.
If the method is decorated with staticmethod
or classmethod
, the issue doesn't happen.
Note, that the check only considers methods which are defined as a direct child of a class.
Check if subprocess.run
or subprocess.Popen
is called with universal_newlines
.
This keyword argument can be replaced with text
which is more readable
Checks for import of from re import DEBUG
or usage of re.DEBUG
Checks for type comments which should be replaced by annotations. type:ignore
is ignored
Check if in a type annotation containing a union, None
always comes last. For instance
a: int|float|None
is okay, but a: int|None|float
is not.
This check does not work for unions using typing.Union
and does also not consider
typing.Optional
Checks for unnecessary lambda statement which can be replaced with their built-in function
alternative, e.g. lambda: []
with list
Checks for implicit concatenated strings on the same line
Checks for missing onerror
keyword in os.walk
.
The check is only active if os.walk
is somehow imported.
Checks for unnecessary usage of metaclass=abc.ABCMeta
, which can be simplified to abc.ABC
Checks for unnecessary usage of str()
, like str("a")
Checks for unnecessary usage of int()
, like int(1)
Checks for unnecessary usage of float()
, like float(1.1)
Checks for unnecessary usage of bool()
, like bool(True)
Checks for imports of xml.etree.cElementTree
Checks for the usage of io.open
which can be simplified to open
.
Checks for the usage of OSError
aliases
EnvironmentError
, IOError
and WindowsError
.
In addition, it also finds usage and imports of socket.error
and select.error
.
In this case, calls like raise socket.error()
are not checked.
Checks for unsorted __all__
attributes on any level.
The check is only done if the type is a list, tuple or set during parsing
(e.g. list
is a function and not a list during parsing).
Only items which are strings are used in the sort check, all others are ignored.
Checks if backslashes are used to split long lines.
Checks for unnecessary usage of 0 as starting point with no step size defined
in range
call.
Find functions starting with is_/have_/has_/can_
which have a non-boolean return type.
typing.TypeGuard
is accepted as an alternative to a boolean.
Functions with no return type annotation are ignored.
Find cases where the __slot__
attribute is assigned something else than a tuple or dict,
like __slots__ = []
or __slots__ = get_slots()
.
In general, using e.g. a list or single string is fine, but always using a tuple or dict
is more consistent and recommended
Checks for unnecessary use of unpack operators.
Find functions which are decorated with property
, classmethod
or
staticmethod
but are outside of a class.
Find enums without enum.unique
decorator to make sure no duplicate values are assigned.
Checks for usage of multiprocessing.set_start_method
.
A multiprocessing Context should be used instead.
Since python 3.11 the datetime.timezone.utc
constant is also accessible with
datetime.UTC
which is found by this check
Find print("")
which can be simplified to print()
Find unpack operators inside of a dict which can be rewritten with the dict union operator.
E.g. {**a, **b}
can be rewritten to a|b
and {**a, 'b': 2}
to a|{'b': 2}
.
The check ignores unpacks in the middle of the dict, e.g. {'a': 1, **b, 'c': 3}
.
This check is only active when running python 3.9+.
Find Path(".")
of pathlib.Path
which can be simplified to Path()
Find usage of the OS dependent pathlib
classes pathlib.PosixPath
,
pathlib.WindowsPath
, pathlib.PurePosixPath
and
pathlib.PureWindowsPath
.
These classes can be replaced with pathlib.Path
and pathlib.PurePath
,
because they are OS independent and create the correct OS dependent class behind the scenes
Find typing.Never
and typing.NoReturn
in unions. These types are
redundant in unions and can be removed
Find nested typing.Union
types like Union[Union[int, str], float]
.
These can be simplified to Union[int, str, float]
Find typing.Union
with a single element, e.g. Union[int]
. This can be simplified to
int
Find usage of typing.Never
in return annotations.
Instead use typing.NoReturn
Find usage of typing.NoReturn
in non-return annotations (arguments and assignments).
Instead use typing.Never
Checks for unnecessary usage of bytes()
, like bytes(b'abc'')
Find str()
which can be simplified to ""
Find int()
which can be simplified to 0
Find float()
which can be simplified to 0.0
Find bool()
which can be simplified to False
Find bytes()
which can be simplified to b""
Find invisible unicode characters in source code
Find named expressions (walrus operator :=
) in assert statements
Find functions calling warnings.warn
but which are also decorated with
warnings.deprecated
or typing_extensions.deprecated
Find functions calling warnings.warn
but which could use
warnings.deprecated
or typing_extensions.deprecated
Checks for unsorted __slots__
attributes on any level.
The check is only done if the type is a list, tuple or set during parsing.
Only items which are strings are used in the sort check; all others are ignored.
Find assignments to __slots__
outside of a class. The assignment can be wrapped into
constructs like an if
but the first container needs to be a class and not a function or
module
Find calls of soft-deprecated os
functions which should be replaced with
subprocess
calls like os.popen
or os.spawnv
Find methods decorated with both classmethod
and property
.
Through the different python versions the behavior is unstable and should be avoided
Finds usage of typing.Generator
where the last argument in the subscript is None
,
because with PEP696 these can be omitted. The check is only active if
- running python 3.13+
- a
from __future__ import annotations
import is present in the module - the current code is inside a
typing.TYPE_CHECKING
block
Also, the check will only consider type annotations (to prevent invalid syntax) if at least one of the following conditions is true:
- python 3.12 or below is used
- the code is not inside a
typing.TYPE_CHECKING
block
Find assignments to __all__
on non-module level, e.g. in classes or functions
Find calls of flask.abort
and werkzeug.exceptions.abort
.
Instead of calling this helper function raise the appropriate exception directly
Find usage of requests.codes
which should be replaced with http.HTTPStatus