From 6d1b157d03ef36cccca5339157f2f9b7deb84daf Mon Sep 17 00:00:00 2001 From: liqimai Date: Wed, 30 Mar 2022 12:11:05 +0800 Subject: [PATCH 1/3] Support python console REPL. --- src/pytest_codeblocks/main.py | 13 ++++++++ src/pytest_codeblocks/plugin.py | 4 +-- tests/test_repl.py | 56 +++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 tests/test_repl.py diff --git a/src/pytest_codeblocks/main.py b/src/pytest_codeblocks/main.py index c7debae..9d494fa 100644 --- a/src/pytest_codeblocks/main.py +++ b/src/pytest_codeblocks/main.py @@ -11,6 +11,12 @@ from pathlib import Path +from doctest import DocTestFinder, DebugRunner + +finder = DocTestFinder() +runner = DebugRunner() + + @dataclass class CodeBlock: code: str @@ -21,6 +27,13 @@ class CodeBlock: skip: bool = False skipif: str | None = None + def exec(self, globs: dict) -> None: + if self.code.startswith(">>>"): + for test in finder.find(self.code, name=f"line {self.lineno}", globs=globs): + runner.run(test) + else: + exec(self.code, globs) + def extract_from_file( f: str | bytes | Path, encoding: str | None = "utf-8", *args, **kwargs diff --git a/src/pytest_codeblocks/plugin.py b/src/pytest_codeblocks/plugin.py index a140dcb..fd67b88 100644 --- a/src/pytest_codeblocks/plugin.py +++ b/src/pytest_codeblocks/plugin.py @@ -64,12 +64,12 @@ def runtest(self): if self.obj.syntax == "python": if self.obj.expect_exception: with pytest.raises(Exception): - exec(self.obj.code, {"__MODULE__": "__main__"}) + self.obj.exec({"__MODULE__": "__main__"}) else: with stdout_io() as s: try: # https://stackoverflow.com/a/62851176/353337 - exec(self.obj.code, {"__MODULE__": "__main__"}) + self.obj.exec({"__MODULE__": "__main__"}) except Exception as e: raise RuntimeError( f"{self.name}, line {self.obj.lineno}:\n```\n" diff --git a/tests/test_repl.py b/tests/test_repl.py new file mode 100644 index 0000000..09bc05f --- /dev/null +++ b/tests/test_repl.py @@ -0,0 +1,56 @@ +import pathlib + +from pytest import skip + +import pytest_codeblocks + + +def test_repr(testdir): + string1 = """ + ```python + >>> print("Hello World!") + Hello World! + ``` + """ + testdir.makefile(".md", string1) + result = testdir.runpytest("--codeblocks") + result.assert_outcomes(passed=1) + + +def test_cont(testdir): + string1 = """ + ```python + >>> def add(a, b): + ... return a + b + ``` + + + ```python + >>> add(2,7) + 9 + ``` + """ + testdir.makefile(".md", string1) + result = testdir.runpytest("--codeblocks") + result.assert_outcomes(passed=1) + + +def test_exception(testdir): + string1 = """ + Handle the exception by doctest: + ```python + >>> raise Exception("This should fail") + Traceback (most recent call last): + File "", line 1, in + Exception: This should fail + ``` + + Handle the exception by pytest: + + ```python + >>> raise Exception("This should fail") + ``` + """ + testdir.makefile(".md", string1) + result = testdir.runpytest("--codeblocks") + result.assert_outcomes(passed=2) From 44c5a87a96a6e570996c117f957e865c77e0aaf5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 04:14:23 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/pytest_codeblocks/main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pytest_codeblocks/main.py b/src/pytest_codeblocks/main.py index 9d494fa..8a26920 100644 --- a/src/pytest_codeblocks/main.py +++ b/src/pytest_codeblocks/main.py @@ -7,12 +7,10 @@ # namedtuple with default arguments # from dataclasses import dataclass +from doctest import DebugRunner, DocTestFinder from io import StringIO from pathlib import Path - -from doctest import DocTestFinder, DebugRunner - finder = DocTestFinder() runner = DebugRunner() From 9bb447f08bbfaaa96115968cd9422eea9f2d27f6 Mon Sep 17 00:00:00 2001 From: liqimai Date: Thu, 31 Mar 2022 09:57:11 +0800 Subject: [PATCH 3/3] Update readme for REPL code blocks. --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 32eeb1a..eef2c6a 100644 --- a/README.md +++ b/README.md @@ -154,3 +154,35 @@ The following gives an error: ```` The keyword `expect-exception` is also possible. + +#### Doctest-style code blocks + +Code blocks starting with `">>>"` will be treated as interactive Python shell code, and tested by [doctest](https://docs.python.org/3/library/doctest.html). + +````markdown +```python +>>> print("Hello") +Hello +>>> 2+3 +5 +``` +```` +You can concatenate multiple doctest-style code blocks with ``, but cannot mix doctest-style ones with normal python code blocks, or vice versa. + +There are two ways to indicate expected exceptions in doctest-style code blocks. One is to include the expected exception into you code block, and let doctest handle it. + +````markdown +```python +>>> raise Exception("This should fail") +Traceback (most recent call last): + File "", line 1, in +Exception: This should fail +``` +```` +The other way is to use the ``, and let pytest handle it. +````markdown + +```python +>>> raise Exception("This should fail") +``` +```` \ No newline at end of file