angr/tests/broken_x.py
, angr/tests/broken_y.py
, etcbroken_x.py
to test_x.py
and the testcase will run in our internal CI at every push, ensuring that we do not break this feature again.@property
decorator) instead of getters and setters wherever you can. This isn't Java, and attributes enable tab completion in iPython. That being said, be reasonable: attributes should be fast. A rule of thumb is that if something could require a constraint solve, it should not be an attribute..pylintrc
from the angr-dev repo. It's fairly permissive, but our CI server will fail your builds if pylint complains under those settings.raise Exception
or assert False
. Use the right exception type. If there isn't a correct exception type, subclass the core exception of the module that you're working in (i.e., AngrError
in angr, SimError
in SimuVEX, etc) and raise that. We catch, and properly handle, the right types of errors in the right places, but AssertionError
and Exception
are not handled anywhere and force-terminate analyses._
instead of __
for private members (so that we can access them when debugging). You might not think that anyone has a need to call a given function, but trust us, you're wrong.test_*.py
in the tests
folder of the appropriate repository. A test file can contain any number of functions of the form def test_*():
or classes of the form class Test*(unittest.TestCase):
. Each of them will be run as a test, and if they raise any exceptions or assertions, the test fails. Do not use the nose.tools.assert_*
functions, as we are presently trying to migrate to nose2
. Use assert
statements with descriptive messages or the unittest.TestCase
assert methods.test_*
function is actually a generator that yields tuples of functions to call and their arguments, for easy parametrization of tests.