Coverage for tests/test_readme.py: 100%

36 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-30 23:02 +0000

1"""Tests that every example in the README works as documented. 

2 

3Code blocks in the README show results as trailing comments (for example, 

4`colors.get('purple') # 0`). This test runs each block and checks that every 

5expression with such a comment evaluates to the value shown. 

6""" 

7 

8from __future__ import annotations 

9 

10import ast 

11import pathlib 

12import re 

13import sys 

14import types 

15 

16README = pathlib.Path(__file__).parents[1] / 'README.md' 

17_RESULT = re.compile(r'\s{2}# (?P<expected>.+)$') 

18 

19 

20def test_readme_examples() -> None: 

21 """Runs all of the python code blocks in the README.""" 

22 text = README.read_text(encoding = 'utf-8') 

23 blocks = re.findall(r'```python\n(.*?)```', text, flags = re.DOTALL) 

24 assert blocks 

25 module = types.ModuleType('readme') 

26 sys.modules['readme'] = module 

27 namespace = module.__dict__ 

28 checked = 0 

29 try: 

30 checked = _run(blocks, namespace) 

31 finally: 

32 del sys.modules['readme'] 

33 assert checked > 20 

34 

35 

36def _run(blocks: list[str], namespace: dict[str, object]) -> int: 

37 """Runs code blocks and checks results shown in comments. 

38 

39 Args: 

40 blocks: source code of the README code blocks. 

41 namespace: namespace shared by all of the blocks. 

42 

43 Returns: 

44 Number of results checked. 

45 

46 """ 

47 checked = 0 

48 for block in blocks: 

49 lines = block.splitlines() 

50 for node in ast.parse(block).body: 

51 if isinstance(node, ast.Expr): 

52 match = _RESULT.search(lines[node.end_lineno - 1]) 

53 if match: 

54 code = compile(ast.Expression(node.value), 'README', 'eval') 

55 result = eval(code, namespace) # noqa: S307 

56 assert repr(result) == match['expected'] 

57 checked += 1 

58 continue 

59 module = ast.Module(body = [node], type_ignores = []) 

60 exec(compile(module, 'README', 'exec'), namespace) # noqa: S102 

61 return checked