From 0e24f74b0fd458170237eea62d0eff5ed0493a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 24 Jan 2022 11:01:59 +0100 Subject: [PATCH] Fix handling missing hypothesmith gracefully Fix test_mccabe not to fail to import if hypothesmith is not available. While the original code seems to attempt to handle missing hypothesmith, the file fails with NameError without it. This is because hypothesis decorators are used in global scope. Guard the whole test function to be defined only when hypothesmith is available. --- test_mccabe.py | 70 ++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/test_mccabe.py b/test_mccabe.py index fe6e8d3..5f07d32 100644 --- a/test_mccabe.py +++ b/test_mccabe.py @@ -239,41 +239,43 @@ def test_get_module_complexity(self): self.assertEqual(0, mccabe.get_module_complexity("mccabe.py")) -# This test uses the Hypothesis and Hypothesmith libraries to generate random -# syntatically-valid Python source code and applies McCabe on it. -@settings( - max_examples=1000, # roughly 1k tests/minute, or half that under coverage - derandomize=False, # deterministic mode to avoid CI flakiness - deadline=None, # ignore Hypothesis' health checks; we already know that - suppress_health_check=HealthCheck.all(), # this is slow and filter-heavy. -) -@given( - # Note that while Hypothesmith might generate code unlike that written by - # humans, it's a general test that should pass for any *valid* source code. - # (so e.g. running it against code scraped of the internet might also help) - src_contents=hypothesmith.from_grammar() | hypothesmith.from_node(), - max_complexity=st.integers(min_value=1), -) -@pytest.mark.skipif(not hypothesmith, reason="hypothesmith could not be imported") -def test_idempotent_any_syntatically_valid_python( - src_contents: str, max_complexity: int -) -> None: - """Property-based tests for mccabe. - - This test case is based on a similar test for Black, the code formatter. - Black's test was written by Zac Hatfield-Dodds, the author of Hypothesis - and the Hypothesmith tool for source code generation. You can run this - file with `python`, `pytest`, or (soon) a coverage-guided fuzzer Zac is - working on. - """ - - # Before starting, let's confirm that the input string is valid Python: - compile(src_contents, "", "exec") # else bug is in hypothesmith - - # Then try to apply get_complexity_number to the code... - get_code_complexity(src_contents, max_complexity) +if hypothesmith is not None: + # This test uses the Hypothesis and Hypothesmith libraries to generate random + # syntatically-valid Python source code and applies McCabe on it. + @settings( + max_examples=1000, # roughly 1k tests/minute, or half that under coverage + derandomize=False, # deterministic mode to avoid CI flakiness + deadline=None, # ignore Hypothesis' health checks; we already know that + suppress_health_check=HealthCheck.all(), # this is slow and filter-heavy. + ) + @given( + # Note that while Hypothesmith might generate code unlike that written by + # humans, it's a general test that should pass for any *valid* source code. + # (so e.g. running it against code scraped of the internet might also help) + src_contents=hypothesmith.from_grammar() | hypothesmith.from_node(), + max_complexity=st.integers(min_value=1), + ) + @pytest.mark.skipif(not hypothesmith, reason="hypothesmith could not be imported") + def test_idempotent_any_syntatically_valid_python( + src_contents: str, max_complexity: int + ) -> None: + """Property-based tests for mccabe. + + This test case is based on a similar test for Black, the code formatter. + Black's test was written by Zac Hatfield-Dodds, the author of Hypothesis + and the Hypothesmith tool for source code generation. You can run this + file with `python`, `pytest`, or (soon) a coverage-guided fuzzer Zac is + working on. + """ + + # Before starting, let's confirm that the input string is valid Python: + compile(src_contents, "", "exec") # else bug is in hypothesmith + + # Then try to apply get_complexity_number to the code... + get_code_complexity(src_contents, max_complexity) if __name__ == "__main__": - test_idempotent_any_syntatically_valid_python() + if hypothesmith is not None: + test_idempotent_any_syntatically_valid_python() unittest.main()