104 b = b.data 105 type_b = type(b) 106 107 assert type_b == list108 return _val_eq(a.data, b) 109 elif type_b == SubPattern: 110 return _val_eq(b, a)
133 return False 134 return True 135 136 assert type_a == tuple, type_a137 138 if length == 2: 139 tok, val = a
assert statement in application logic is discouraged.
assert is removed with compiling to optimized byte code. Consider raising an exception instead. Ideally,
assert statement should be used only in tests.
Python has an option to compile the optimized bytecode and create the respective
.pyo files by using the options
-OO. When used, these basic optimizations are done:
__debug__built-in variable is set to
It is recommended not to use
assert in non-test files. A better way for internal self-checks is to check explicitly and raise respective error using an if statement.
Tip: Make sure
test_patterns are defined in
.deepsource.toml to avoid false-positives. Please check the documentation to know more.
Consider this code snippet:
def read_secret(self): assert self.is_admin, "You are unauthorized to read this" return self._secret
python is run with the
-O flag, the check for
completely ignored, which can cause secrets to be leaked.
This is how you can ensure the code always works:
def read_secret(self): if not self.is_admin: raise AssertionError("You are unauthorized to read this") return self._secret
Here's a more detailed example. Consider the following script
import sys def run(): assert len(sys.argv) == 5 # Insecure, statement will be removed when compiled to optimized byte code print("Argument variables are: ", sys.argv) run()
When optimization is disabled:
$ python foo.py 1 2 3 4 5 Traceback (most recent call last): File "foo.py", line 7, in <module> run() File "foo.py", line 4, in run assert len(sys.argv) == 5 # Insecure, statement will be removed when compiled to optimized byte code AssertionError
When optimization is enabled:
$ python -O foo.pyo 1 2 3 4 5 6 Argument variables are: ['foo.pyo', '1', '2', '3', '4', '5', '6']
Here, all the internal self-checks using the assert statements are removed, as we can see. Therefore, there's a chance for an application to behave strangely in this case. It is better do raise the Exception explicitly:
import sys def run(): if not len(sys.argv) == 5: raise ValueError print("Argument variables are: ", sys.argv) run()
Note: During autofix, DeepSource will change the
assert statements to
if statements raising
This is done to replicate the existing behavior.