149 matrix2 = d2[key]
150 np.testing.assert_equal(matrix1, matrix2)
151 else:
152 assert key not in d2153
154
155def check_orthonormal(mo_coeffs: NDArray[float], ao_overlap: NDArray[float], atol: float = 1e-5):
142 d2 = getattr(mol2, attrname)
143 for key in keys:
144 if key in d1:
145 assert key in d2146 matrix1 = d1[key]
147 matrix1 = matrix1[perm] * sgn.reshape(-1, 1)
148 matrix1 = matrix1[:, perm] * sgn
126 assert mol2.obasis is None
127 # wfn
128 perm, sgn = convert_conventions(mol1.obasis, mol2.obasis.conventions)
129 assert mol1.mo.kind == mol2.mo.kind130 assert_allclose(mol1.mo.occs, mol2.mo.occs, atol=atol, rtol=rtol)
131 assert_allclose(mol1.mo.coeffs[perm] * sgn.reshape(-1, 1), mol2.mo.coeffs, atol=atol, rtol=rtol)
132 assert_allclose(mol1.mo.energies, mol2.mo.energies, atol=atol, rtol=rtol)
117 assert_equal(shell1.kinds, shell2.kinds)
118 assert_allclose(shell1.exponents, shell2.exponents, atol=atol, rtol=rtol)
119 assert_allclose(shell1.coeffs, shell2.coeffs, atol=atol, rtol=rtol)
120 assert mol1.obasis.primitive_normalization == mol2.obasis.primitive_normalization121 # compute and compare Mulliken charges
122 charges1 = compute_mulliken_charges(mol1)
123 charges2 = compute_mulliken_charges(mol2)
112 # compare dictionaries
113 assert len(mol1.obasis.shells) == len(mol2.obasis.shells)
114 for shell1, shell2 in zip(mol1.obasis.shells, mol2.obasis.shells):
115 assert shell1.icenter == shell2.icenter116 assert_equal(shell1.angmoms, shell2.angmoms)
117 assert_equal(shell1.kinds, shell2.kinds)
118 assert_allclose(shell1.exponents, shell2.exponents, atol=atol, rtol=rtol)
Usage of 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 -O
and -OO
. When used, these basic optimizations are done:
__debug__
built-in variable is set to False
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
If python
is run with the -O
flag, the check for self.is_admin
is
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 foo.py
:
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 AssertionError
.
This is done to replicate the existing behavior.