mktestdocs 0.1.2__py2.py3-none-any.whl → 0.2.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
mktestdocs/__init__.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from mktestdocs.__main__ import (
2
+ register_executor,
2
3
  check_codeblock,
3
4
  grab_code_blocks,
4
5
  check_docstring,
@@ -6,10 +7,11 @@ from mktestdocs.__main__ import (
6
7
  get_codeblock_members,
7
8
  )
8
9
 
9
- __version__ = "0.1.2"
10
+ __version__ = "0.2.1"
10
11
 
11
12
  __all__ = [
12
13
  "__version__",
14
+ "register_executor",
13
15
  "check_codeblock",
14
16
  "grab_code_blocks",
15
17
  "check_docstring",
mktestdocs/__main__.py CHANGED
@@ -1,8 +1,56 @@
1
1
  import inspect
2
2
  import pathlib
3
+ import subprocess
3
4
  import textwrap
4
5
 
5
6
 
7
+ _executors = {}
8
+
9
+
10
+ def register_executor(lang, executor):
11
+ """Add a new executor for markdown code blocks
12
+
13
+ lang should be the tag used after the opening ```
14
+ executor should be a callable that takes one argument:
15
+ the code block found
16
+ """
17
+ _executors[lang] = executor
18
+
19
+
20
+ def exec_bash(source):
21
+ """Exec the bash source given in a new subshell
22
+
23
+ Does not return anything, but if any command returns not-0 an error
24
+ will be raised
25
+ """
26
+ command = ["bash", "-e", "-u", "-c", source]
27
+ try:
28
+ subprocess.run(command, check=True)
29
+ except Exception:
30
+ print(source)
31
+ raise
32
+
33
+
34
+ register_executor("bash", exec_bash)
35
+
36
+
37
+ def exec_python(source):
38
+ """Exec the python source given in a new module namespace
39
+
40
+ Does not return anything, but exceptions raised by the source
41
+ will propagate out unmodified
42
+ """
43
+ try:
44
+ exec(source, {"__MODULE__": "__main__"})
45
+ except Exception:
46
+ print(source)
47
+ raise
48
+
49
+
50
+ register_executor("", exec_python)
51
+ register_executor("python", exec_python)
52
+
53
+
6
54
  def get_codeblock_members(*classes):
7
55
  """
8
56
  Grabs the docstrings of any methods of any classes that are passed in.
@@ -61,49 +109,54 @@ def check_docstring(obj, lang=""):
61
109
  """
62
110
  Given a function, test the contents of the docstring.
63
111
  """
112
+ if lang not in _executors:
113
+ raise LookupError(
114
+ f"{lang} is not a supported language to check\n"
115
+ "\tHint: you can add support for any language by using register_executor"
116
+ )
117
+ executor = _executors[lang]
64
118
  for b in grab_code_blocks(obj.__doc__, lang=lang):
65
- try:
66
- exec(b, {"__MODULE__": "__main__"})
67
- except Exception:
68
- print(f"Error Encountered in `{obj.__name__}`. Caused by:\n")
69
- print(b)
70
- raise
119
+ executor(b)
71
120
 
72
121
 
73
122
  def check_raw_string(raw, lang="python"):
74
123
  """
75
124
  Given a raw string, test the contents.
76
125
  """
126
+ if lang not in _executors:
127
+ raise LookupError(
128
+ f"{lang} is not a supported language to check\n"
129
+ "\tHint: you can add support for any language by using register_executor"
130
+ )
131
+ executor = _executors[lang]
77
132
  for b in grab_code_blocks(raw, lang=lang):
78
- try:
79
- exec(b, {"__MODULE__": "__main__"})
80
- except Exception:
81
- print(b)
82
- raise
133
+ executor(b)
83
134
 
84
135
 
85
136
  def check_raw_file_full(raw, lang="python"):
137
+ if lang not in _executors:
138
+ raise LookupError(
139
+ f"{lang} is not a supported language to check\n"
140
+ "\tHint: you can add support for any language by using register_executor"
141
+ )
142
+ executor = _executors[lang]
86
143
  all_code = ""
87
144
  for b in grab_code_blocks(raw, lang=lang):
88
145
  all_code = f"{all_code}\n{b}"
89
- try:
90
- exec(all_code, {"__MODULE__": "__main__"})
91
- except Exception:
92
- print(all_code)
93
- raise
94
-
146
+ executor(all_code)
147
+
95
148
 
96
- def check_md_file(fpath, memory=False):
149
+ def check_md_file(fpath, memory=False, lang="python"):
97
150
  """
98
151
  Given a markdown file, parse the contents for python code blocks
99
- and check that each independant block does not cause an error.
152
+ and check that each independent block does not cause an error.
100
153
 
101
154
  Arguments:
102
155
  fpath: path to markdown file
103
- memory: wheather or not previous code-blocks should be remembered
156
+ memory: whether or not previous code-blocks should be remembered
104
157
  """
105
158
  text = pathlib.Path(fpath).read_text()
106
159
  if not memory:
107
- check_raw_string(text, lang="python")
160
+ check_raw_string(text, lang=lang)
108
161
  else:
109
- check_raw_file_full(text, lang="python")
162
+ check_raw_file_full(text, lang=lang)
@@ -1,13 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mktestdocs
3
- Version: 0.1.2
4
- Summary: UNKNOWN
5
- Home-page: UNKNOWN
6
- License: UNKNOWN
7
- Platform: UNKNOWN
3
+ Version: 0.2.1
4
+ License-File: LICENSE
8
5
  Provides-Extra: test
9
6
  Requires-Dist: pytest (>=4.0.2) ; extra == 'test'
10
7
 
11
- UNKNOWN
12
-
13
-
@@ -0,0 +1,7 @@
1
+ mktestdocs/__init__.py,sha256=_iVQPmcuxkjOr-bEOP4DEygx6mnG_6fP4wJBhbc2G8E,371
2
+ mktestdocs/__main__.py,sha256=BO5LopXLAeKFFuKcT0KaeErUeFXt8ekjIiyrTymBG3k,4508
3
+ mktestdocs-0.2.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
4
+ mktestdocs-0.2.1.dist-info/METADATA,sha256=67xAXa_sIfpXAHDaOiKJPxRUqXQekbdMhZDqXQzL5Ec,148
5
+ mktestdocs-0.2.1.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110
6
+ mktestdocs-0.2.1.dist-info/top_level.txt,sha256=1XGYsQSl3FsAtilWThIet3WOJQSuzQXXn6sQA7hxlho,11
7
+ mktestdocs-0.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.36.2)
2
+ Generator: bdist_wheel (0.40.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -1,12 +0,0 @@
1
- mktestdocs/__init__.py,sha256=OFT05l99yabbzwBSEyoxcy6EOeQ8OJZ-Aj42-6DaB2U,323
2
- mktestdocs/__main__.py,sha256=xZoRTfWCTJltef-katbq9XY_OK0GDaFggwhcXIBfMTk,3069
3
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- tests/test_actual_docstrings.py,sha256=N1yIuHOBNhv2qR2yO1DkqiBNvHK3_o_pbLJCHLKUa68,940
5
- tests/test_class.py,sha256=lkZ73We8Hb4IvPbQVn8w5LX5zMHptFHkUcJ3xfBJqgc,1220
6
- tests/test_codeblock.py,sha256=FxyPZZw1lVLFWXB1BErciHP6h-kFNBLLPU9UX_6uBfE,903
7
- tests/test_markdown.py,sha256=ndriPDsL5rI0mPhDJDeTRwmDWod6DXXlm05CRNKhDdk,827
8
- mktestdocs-0.1.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
9
- mktestdocs-0.1.2.dist-info/METADATA,sha256=e0ET9ESs91i_AtXs_TifyTbZa0aGledTBv_TTzXO-ss,207
10
- mktestdocs-0.1.2.dist-info/WHEEL,sha256=Z-nyYpwrcSqxfdux5Mbn_DQ525iP7J2DG3JgGvOYyTQ,110
11
- mktestdocs-0.1.2.dist-info/top_level.txt,sha256=Wh9mCrbRZsALS8VKzSi8ifKBj95gf-BHeWQCoTTNBKc,17
12
- mktestdocs-0.1.2.dist-info/RECORD,,
tests/__init__.py DELETED
File without changes
@@ -1,60 +0,0 @@
1
- import pytest
2
- from mktestdocs import check_docstring
3
-
4
-
5
- def foobar_good(a, b):
6
- """
7
- Returns a + b.
8
-
9
- Examples:
10
-
11
- ```python
12
- import random
13
-
14
- random.random()
15
- assert 'a' + 'b' == 'ab'
16
- assert 1 + 2 == 3
17
- ```
18
- """
19
- return a + b
20
-
21
-
22
- def foobar_also_good(a, b):
23
- """
24
- Returns a + b.
25
-
26
- Examples:
27
-
28
- ```python
29
- import random
30
-
31
- assert random.random() < 10
32
- ```
33
- """
34
- return a + b
35
-
36
-
37
- def foobar_bad(a, b):
38
- """
39
- Returns a + b.
40
-
41
- Examples:
42
-
43
- ```python
44
- assert foobar(1, 2) == 4
45
- ```
46
- """
47
- return a + b
48
-
49
-
50
- @pytest.mark.parametrize("func", [foobar_good, foobar_also_good])
51
- def test_base_docstrings(func):
52
- check_docstring(func)
53
-
54
-
55
- @pytest.mark.parametrize("func", [foobar_bad])
56
- def test_base_docstrings_bad(func, capsys):
57
- with pytest.raises(Exception):
58
- check_docstring(func)
59
- capsys.readouterr()
60
- assert func.__name__ in capsys.readouterr().out
tests/test_class.py DELETED
@@ -1,73 +0,0 @@
1
- import pytest
2
-
3
- from mktestdocs import get_codeblock_members, check_docstring
4
-
5
-
6
- class Dinosaur:
7
- """
8
- This is a dino.
9
-
10
- ```python
11
- from dinosaur import Dinosaur
12
-
13
- assert Dinosaur().name == 'trex'
14
- ```
15
- """
16
-
17
- def __init__(self):
18
- self.name = "trex"
19
-
20
- @staticmethod
21
- def a(value):
22
- """
23
- Returns value
24
-
25
- Example:
26
-
27
- ```python
28
- from dinosaur import Dinosaur
29
-
30
- dino = Dinosaur()
31
- assert dino.a(1) == 1
32
- ```
33
- """
34
- return value
35
-
36
- @classmethod
37
- def b(cls, value):
38
- """
39
- Returns value
40
-
41
- Example:
42
-
43
- ```python
44
- from dinosaur import Dinosaur
45
- assert Dinosaur.b(1) == 1
46
- ```
47
- """
48
- return value
49
-
50
- def hello(self):
51
- """
52
- Returns value
53
-
54
- Example:
55
-
56
- ```python
57
- from dinosaur import Dinosaur
58
- assert Dinosaur().name == 'trex'
59
- ```
60
- """
61
- return self.name
62
-
63
-
64
- members = get_codeblock_members(Dinosaur)
65
-
66
-
67
- def test_grab_methods():
68
- assert len(get_codeblock_members(Dinosaur)) == 4
69
-
70
-
71
- @pytest.mark.parametrize("obj", members, ids=lambda d: d.__qualname__)
72
- def test_member(obj):
73
- check_docstring(obj)
tests/test_codeblock.py DELETED
@@ -1,56 +0,0 @@
1
- import pytest
2
-
3
- from mktestdocs import check_codeblock, grab_code_blocks
4
-
5
- exibit_a = """
6
- This is an example docstring.
7
-
8
- Arguments:
9
- a: a parameter
10
-
11
- There is no example
12
- """
13
-
14
- exibit_b = """
15
- This is an example docstring.
16
-
17
- Arguments:
18
- a: a parameter
19
-
20
- ```python
21
- assert 1 == 1
22
- ```
23
- """
24
-
25
- exibit_c = """
26
- This is an example docstring.
27
-
28
- Arguments:
29
- a: a parameter
30
-
31
- ```
32
- assert 1 == 1
33
- ```
34
-
35
- ```python
36
- assert 1 == 1
37
- ```
38
- """
39
-
40
-
41
- @pytest.mark.parametrize(
42
- "doc, n",
43
- [(exibit_a, 0), (exibit_b, 1), (exibit_c, 1)],
44
- ids=["exibit_a", "exibit_b", "exibit_c"],
45
- )
46
- def test_number_of_codeblocks(doc, n):
47
- assert len(grab_code_blocks(doc, lang="python")) == n
48
-
49
-
50
- @pytest.mark.parametrize(
51
- "doc, n",
52
- [(exibit_a, 0), (exibit_b, 1), (exibit_c, 2)],
53
- ids=["exibit_a", "exibit_b", "exibit_c"],
54
- )
55
- def test_number_of_codeblocks_any(doc, n):
56
- assert len(grab_code_blocks(doc, lang=None)) == n
tests/test_markdown.py DELETED
@@ -1,27 +0,0 @@
1
- import pathlib
2
- import pytest
3
-
4
- from mktestdocs import check_md_file
5
-
6
-
7
- @pytest.mark.parametrize("fpath", pathlib.Path("tests/data/good").glob("*.md"), ids=str)
8
- def test_files_good(fpath):
9
- check_md_file(fpath=fpath)
10
-
11
-
12
- @pytest.mark.parametrize("fpath", pathlib.Path("tests/data/bad").glob("*.md"), ids=str)
13
- def test_files_bad(fpath):
14
- with pytest.raises(Exception):
15
- check_md_file(fpath=fpath)
16
-
17
-
18
- def test_big_files_good():
19
- """Confirm that we can deal with multi-cell markdown cells."""
20
- check_md_file(fpath="tests/data/big-good.md", memory=True)
21
-
22
-
23
- def test_big_file_independant():
24
- """Confirm that different files don't influence eachother."""
25
- check_md_file(fpath="tests/data/big-good.md", memory=True)
26
- with pytest.raises(Exception):
27
- check_md_file(fpath="tests/data/big-bad.md", memory=True)