pytest-markdown-docs 0.4.3__tar.gz → 0.5.1__tar.gz

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.
@@ -1,20 +1,21 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytest-markdown-docs
3
- Version: 0.4.3
3
+ Version: 0.5.1
4
4
  Summary: Run markdown code fences through pytest
5
5
  Home-page: https://github.com/modal-com/pytest-markdown-docs
6
6
  License: MIT
7
7
  Author: Modal Labs
8
- Requires-Python: >=3.7,<4.0
8
+ Requires-Python: >=3.8,<4.0
9
9
  Classifier: Framework :: Pytest
10
10
  Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.7
13
12
  Classifier: Programming Language :: Python :: 3.8
14
13
  Classifier: Programming Language :: Python :: 3.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
- Requires-Dist: markdown-it-py (>=2.2.0,<2.3.0)
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Dist: markdown-it-py (>=2.2.0,<4.0)
18
+ Requires-Dist: pytest (>=7.0.0)
18
19
  Project-URL: Repository, https://github.com/modal-com/pytest-markdown-docs
19
20
  Description-Content-Type: text/markdown
20
21
 
@@ -171,10 +172,9 @@ Or for fun, you can use this plugin to include testing of the validity of snippe
171
172
  ```
172
173
 
173
174
  ## Known issues
174
-
175
- * Only tested with pytest 6.2.5. There seem to be some minor issue with pytest >7 due to changes of some internal functions in pytest, but that should be relatively easy to fix. Contributions are welcome :)
176
175
  * Code for docstring-inlined test discovery can probably be done better (similar to how doctest does it). Currently, seems to sometimes traverse into Python's standard library which isn't great...
177
176
  * Traceback logic is extremely hacky, wouldn't be surprised if the tracebacks look weird sometimes
178
177
  * Line numbers are "wrong" for docstring-inlined snippets (since we don't know where in the file the docstring starts)
179
178
  * Line numbers are "wrong" for continuation blocks even in pure markdown files (can be worked out with some refactoring)
180
-
179
+ * There are probably more appropriate ways to use pytest internal APIs to get more features "for free" - current state of the code is a bit "patch it til' it works".
180
+ * Assertions are not rewritten w/ pretty data structure inspection like they are with regular pytest tests by default
@@ -151,9 +151,9 @@ Or for fun, you can use this plugin to include testing of the validity of snippe
151
151
  ```
152
152
 
153
153
  ## Known issues
154
-
155
- * Only tested with pytest 6.2.5. There seem to be some minor issue with pytest >7 due to changes of some internal functions in pytest, but that should be relatively easy to fix. Contributions are welcome :)
156
154
  * Code for docstring-inlined test discovery can probably be done better (similar to how doctest does it). Currently, seems to sometimes traverse into Python's standard library which isn't great...
157
155
  * Traceback logic is extremely hacky, wouldn't be surprised if the tracebacks look weird sometimes
158
156
  * Line numbers are "wrong" for docstring-inlined snippets (since we don't know where in the file the docstring starts)
159
157
  * Line numbers are "wrong" for continuation blocks even in pure markdown files (can be worked out with some refactoring)
158
+ * There are probably more appropriate ways to use pytest internal APIs to get more features "for free" - current state of the code is a bit "patch it til' it works".
159
+ * Assertions are not rewritten w/ pretty data structure inspection like they are with regular pytest tests by default
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pytest-markdown-docs"
3
- version = "0.4.3"
3
+ version = "0.5.1"
4
4
  description = "Run markdown code fences through pytest"
5
5
  readme = "README.md"
6
6
  authors = ["Modal Labs", "Elias Freider <elias@modal.com>"]
@@ -10,8 +10,9 @@ repository = "https://github.com/modal-com/pytest-markdown-docs"
10
10
  include = ["LICENSE"]
11
11
 
12
12
  [tool.poetry.dependencies]
13
- python = "^3.7"
14
- markdown-it-py = "~=2.2.0"
13
+ python = "^3.8"
14
+ markdown-it-py = ">=2.2.0, <4.0"
15
+ pytest = ">=7.0.0"
15
16
 
16
17
  [tool.poetry.plugins]
17
18
 
@@ -19,9 +20,12 @@ markdown-it-py = "~=2.2.0"
19
20
  "pytest_markdown_docs" = "pytest_markdown_docs.plugin"
20
21
 
21
22
  [tool.poetry.group.dev.dependencies]
22
- pytest = "^7.1.2"
23
- mypy = "^0.971"
24
- black = "^22.8.0"
23
+ ruff = "^0.2.1"
24
+ mypy = "^1.8.0"
25
+ pre-commit = [
26
+ {version="*", python=">=3.9.0"} # pre-commit only available for Python >= 3.9
27
+ ]
28
+ pytest = "8.1.0"
25
29
 
26
30
  [build-system]
27
31
  requires = ["poetry-core>=1.1.0"]
@@ -2,4 +2,4 @@ import typing
2
2
 
3
3
 
4
4
  def pytest_markdown_docs_globals() -> typing.Dict[str, typing.Any]:
5
- pass
5
+ return {}
@@ -9,9 +9,15 @@ import typing
9
9
  from _pytest._code import ExceptionInfo
10
10
  from _pytest.config.argparsing import Parser
11
11
  from _pytest.pathlib import import_path
12
-
13
12
  from pytest_markdown_docs import hooks
14
- from _pytest.fixtures import FixtureRequest
13
+
14
+
15
+ if pytest.version_tuple >= (8, 0, 0):
16
+ from _pytest.fixtures import TopRequest
17
+ else:
18
+ # pytest 7 compatible
19
+ from _pytest.fixtures import FixtureRequest as TopRequest # type: ignore
20
+
15
21
 
16
22
  MARKER_NAME = "markdown-docs"
17
23
 
@@ -22,19 +28,19 @@ class MarkdownInlinePythonItem(pytest.Item):
22
28
  name: str,
23
29
  parent: typing.Union["MarkdownDocstringCodeModule", "MarkdownTextFile"],
24
30
  code: str,
25
- usefixtures: typing.List[str],
31
+ fixture_names: typing.List[str],
26
32
  start_line: int,
27
33
  fake_line_numbers: bool,
28
34
  ) -> None:
29
35
  super().__init__(name, parent)
30
36
  self.add_marker(MARKER_NAME)
31
37
  self.code = code
38
+ self.obj = None
32
39
  self.user_properties.append(("code", code))
33
40
  self.start_line = start_line
34
41
  self.fake_line_numbers = fake_line_numbers
35
-
36
- self.usefixtures = usefixtures
37
- self.add_marker(pytest.mark.usefixtures(*usefixtures))
42
+ self.fixturenames = fixture_names
43
+ self.nofuncargs = True
38
44
 
39
45
  def setup(self):
40
46
  def func() -> None:
@@ -42,9 +48,9 @@ class MarkdownInlinePythonItem(pytest.Item):
42
48
 
43
49
  self.funcargs = {}
44
50
  self._fixtureinfo = self.session._fixturemanager.getfixtureinfo(
45
- node=self, func=func, cls=None, funcargs=False
51
+ node=self, func=func, cls=None
46
52
  )
47
- self.fixture_request = FixtureRequest(self, _ispytest=True)
53
+ self.fixture_request = TopRequest(self, _ispytest=True)
48
54
  self.fixture_request._fillfixtures()
49
55
 
50
56
  def runtest(self):
@@ -55,21 +61,28 @@ class MarkdownInlinePythonItem(pytest.Item):
55
61
  for global_set in global_sets:
56
62
  all_globals.update(global_set)
57
63
 
58
- for fixture_name in self.usefixtures:
59
- fixture_value = self.fixture_request.getfixturevalue(fixture_name)
60
- all_globals[fixture_name] = fixture_value
64
+ # make sure to evaluate fixtures
65
+ # this will insert named fixtures into self.funcargs
66
+ for fixture_name in self._fixtureinfo.names_closure:
67
+ self.fixture_request.getfixturevalue(fixture_name)
68
+
69
+ # Since these are not actual functions with arguments, the only
70
+ # arguments that should appear in self.funcargs are the filled fixtures
71
+ for argname, value in self.funcargs.items():
72
+ if argname not in all_globals:
73
+ all_globals[argname] = value
61
74
 
62
75
  try:
63
76
  tree = ast.parse(self.code)
64
77
  except SyntaxError:
65
- return
78
+ raise
66
79
 
67
80
  try:
68
- # if we don't compile the code, it seems we gate name lookup errors
81
+ # if we don't compile the code, it seems we get name lookup errors
69
82
  # for functions etc. when doing cross-calls across inline functions
70
83
  compiled = compile(tree, self.name, "exec", dont_inherit=True)
71
84
  except SyntaxError:
72
- return
85
+ raise
73
86
 
74
87
  exec(compiled, all_globals)
75
88
 
@@ -155,14 +168,12 @@ def extract_code_blocks(
155
168
 
156
169
  lang = code_info[0] if code_info else None
157
170
 
158
- if lang in ("py", "python", "python3") and not "notest" in code_info:
171
+ if lang in ("py", "python", "python3") and "notest" not in code_info:
159
172
  code_block = block.content
160
173
 
161
174
  if "continuation" in code_info:
162
175
  code_block = prev + code_block
163
- startline = (
164
- -1
165
- ) # this disables proper line numbers, TODO: adjust line numbers *per snippet*
176
+ startline = -1 # this disables proper line numbers, TODO: adjust line numbers *per snippet*
166
177
 
167
178
  fixture_names = [
168
179
  f[len("fixture:") :] for f in code_info if f.startswith("fixture:")
@@ -193,7 +204,15 @@ def find_object_tests_recursive(
193
204
 
194
205
  class MarkdownDocstringCodeModule(pytest.Module):
195
206
  def collect(self):
196
- module = import_path(self.path, root=self.config.rootpath)
207
+ if pytest.version_tuple >= (8, 1, 0):
208
+ # consider_namespace_packages is a required keyword argument in pytest 8.1.0
209
+ module = import_path(
210
+ self.path, root=self.config.rootpath, consider_namespace_packages=True
211
+ )
212
+ else:
213
+ # but unsupported before 8.1...
214
+ module = import_path(self.path, root=self.config.rootpath)
215
+
197
216
  for i, (test_code, fixture_names, start_line) in enumerate(
198
217
  find_object_tests_recursive(module.__name__, module.__name__, module)
199
218
  ):
@@ -201,7 +220,7 @@ class MarkdownDocstringCodeModule(pytest.Module):
201
220
  self,
202
221
  name=f"{self.path}#{i+1}",
203
222
  code=test_code,
204
- usefixtures=fixture_names,
223
+ fixture_names=fixture_names,
205
224
  start_line=start_line,
206
225
  fake_line_numbers=True, # TODO: figure out where docstrings are in file to offset line numbers properly
207
226
  )
@@ -218,18 +237,18 @@ class MarkdownTextFile(pytest.File):
218
237
  self,
219
238
  name=str(self.path),
220
239
  code=code_block,
221
- usefixtures=fixture_names,
240
+ fixture_names=fixture_names,
222
241
  start_line=start_line,
223
242
  fake_line_numbers=start_line == -1,
224
243
  )
225
244
 
226
245
 
227
246
  def pytest_collect_file(
228
- path,
247
+ file_path,
229
248
  parent,
230
249
  ):
231
250
  if parent.config.option.markdowndocs:
232
- pathlib_path = pathlib.Path(str(path)) # pytest 7/8 compat
251
+ pathlib_path = pathlib.Path(str(file_path)) # pytest 7/8 compat
233
252
  if pathlib_path.suffix == ".py":
234
253
  return MarkdownDocstringCodeModule.from_parent(parent, path=pathlib_path)
235
254
  elif pathlib_path.suffix in (".md", ".mdx", ".svx"):