Skip to content

Commit 2b58b11

Browse files
authored
Merge pull request #80 from nschloe/importorskip
Importorskip
2 parents a749494 + c109ded commit 2b58b11

File tree

6 files changed

+64
-2
lines changed

6 files changed

+64
-2
lines changed

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2020-2021 Nico Schlömer
3+
Copyright (c) 2020-2022 Nico Schlömer
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest-codeblocks/)
99
[![GitHub stars](https://img.shields.io/github/stars/nschloe/pytest-codeblocks.svg?style=flat-square&logo=github&label=Stars&logoColor=white)](https://github.com/nschloe/pytest-codeblocks)
1010
[![Downloads](https://pepy.tech/badge/pytest-codeblocks/month?style=flat-square)](https://pepy.tech/project/pytest-codeblocks)
11+
1112
<!--[![PyPi downloads](https://img.shields.io/pypi/dm/pytest-codeblocks.svg?style=flat-square)](https://pypistats.org/packages/pytest-codeblocks)-->
1213

1314
[![gh-actions](https://img.shields.io/github/workflow/status/nschloe/pytest-codeblocks/ci?style=flat-square)](https://github.com/nschloe/pytest-codeblocks/actions?query=workflow%3Aci)
@@ -63,14 +64,23 @@ dolor sit amet.
6364
````
6465

6566
Conditionally skipping code blocks works with `skipif`, e.g.,
67+
6668
```markdown
6769
<!--pytest-codeblocks:skipif(sys.version_info <= (3, 7))-->
6870
```
6971

72+
You can skip code blocks on import errors with
73+
74+
```markdown
75+
<!--pytest-codeblocks:importorskip(sympy)-->
76+
```
77+
7078
Skip the entire file by putting
79+
7180
```markdown
7281
<!--pytest-codeblocks:skipfile-->
7382
```
83+
7484
in the first line.
7585

7686
#### Merging code blocks

src/pytest_codeblocks/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.14.0"
1+
__version__ = "0.15.0"

src/pytest_codeblocks/main.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class CodeBlock:
2020
expect_exception: bool = False
2121
skip: bool = False
2222
skipif: str | None = None
23+
importorskip: str | None = None
2324

2425

2526
def extract_from_file(
@@ -99,6 +100,7 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
99100
+ "but block already has expected_output."
100101
)
101102
out[-1].expected_output = "".join(code_block)
103+
102104
elif keyword == "cont":
103105
if len(out) == 0:
104106
raise RuntimeError(
@@ -111,8 +113,10 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
111113
out[-1].expected_output,
112114
out[-1].expect_exception,
113115
)
116+
114117
elif keyword == "skip":
115118
out.append(CodeBlock("".join(code_block), lineno, syntax, skip=True))
119+
116120
elif keyword.startswith("skipif"):
117121
m = re.match(r"skipif\((.*)\)", keyword)
118122
if m is None:
@@ -122,12 +126,26 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
122126
out.append(
123127
CodeBlock("".join(code_block), lineno, syntax, skipif=m.group(1))
124128
)
129+
130+
elif keyword.startswith("importorskip"):
131+
m = re.match(r"importorskip\((.*)\)", keyword)
132+
if m is None:
133+
raise RuntimeError(
134+
"pytest-codeblocks: Expected importorskip(some-module)"
135+
)
136+
out.append(
137+
CodeBlock(
138+
"".join(code_block), lineno, syntax, importorskip=m.group(1)
139+
)
140+
)
141+
125142
elif keyword in ["expect-exception", "expect-error"]:
126143
out.append(
127144
CodeBlock(
128145
"".join(code_block), lineno, syntax, expect_exception=True
129146
)
130147
)
148+
131149
else:
132150
raise RuntimeError(f'Unknown pytest-codeblocks keyword "{keyword}."')
133151

src/pytest_codeblocks/plugin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ def runtest(self):
6161
if eval(self.obj.skipif):
6262
pytest.skip()
6363

64+
if self.obj.importorskip is not None:
65+
try:
66+
__import__(self.obj.importorskip)
67+
except (ImportError, ModuleNotFoundError):
68+
pytest.skip()
69+
6470
if self.obj.syntax == "python":
6571
if self.obj.expect_exception:
6672
with pytest.raises(Exception):

tests/test_skipif.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,31 @@ def test_skipif_expected_output(testdir):
103103
testdir.makefile(".md", string)
104104
result = testdir.runpytest("--codeblocks")
105105
result.assert_outcomes(passed=1)
106+
107+
108+
def test_importorskip(testdir):
109+
string = """
110+
Lorem ipsum
111+
112+
<!--pytest-codeblocks:importorskip(some_nonexistent_module)-->
113+
114+
```python
115+
print(1 + 3)
116+
```
117+
"""
118+
testdir.makefile(".md", string)
119+
result = testdir.runpytest("--codeblocks")
120+
result.assert_outcomes(skipped=1)
121+
122+
string = """
123+
Lorem ipsum
124+
125+
<!--pytest-codeblocks:importorskip(sys)-->
126+
127+
```python
128+
print(1 + 3)
129+
```
130+
"""
131+
testdir.makefile(".md", string)
132+
result = testdir.runpytest("--codeblocks")
133+
result.assert_outcomes(passed=1)

0 commit comments

Comments
 (0)