From dfa01aabe3465f5e261c68bb86a2c60d2947f236 Mon Sep 17 00:00:00 2001 From: jakkdl Date: Mon, 27 Mar 2023 16:09:58 +0200 Subject: [PATCH] unescape html characters in templates, hide error codes so tests work, run CI in 3.11 --- .github/workflows/test.yml | 2 +- pytest_mypy_plugins/collect.py | 2 +- pytest_mypy_plugins/item.py | 3 +-- pytest_mypy_plugins/tests/test-parametrized.yml | 2 ++ pytest_mypy_plugins/tests/test-paths-from-env.yml | 2 ++ pytest_mypy_plugins/tests/test-simple-cases.yml | 6 +++++- .../tests/test_parametrized_html_escape.yml | 11 +++++++++++ pytest_mypy_plugins/utils.py | 5 ++++- setup.py | 1 + 9 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 pytest_mypy_plugins/tests/test_parametrized_html_escape.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1368b72..5a1c30c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] # TODO: remove `7.1` in the next release pytest-version: ["~=6.2", "~=7.1", "~=7.2"] diff --git a/pytest_mypy_plugins/collect.py b/pytest_mypy_plugins/collect.py index ea1c653..265db91 100644 --- a/pytest_mypy_plugins/collect.py +++ b/pytest_mypy_plugins/collect.py @@ -77,7 +77,7 @@ def construct_mapping(self, node: yaml.MappingNode, deep: bool = False) -> Dict[ mapping = super().construct_mapping(node, deep=deep) # Add 1 so line numbering starts at 1 starting_line = node.start_mark.line + 1 - for (title_node, contents_node) in node.value: + for title_node, contents_node in node.value: if title_node.value == "main": starting_line = title_node.start_mark.line + 1 mapping["__line__"] = starting_line diff --git a/pytest_mypy_plugins/item.py b/pytest_mypy_plugins/item.py index 1ffd091..47c714b 100644 --- a/pytest_mypy_plugins/item.py +++ b/pytest_mypy_plugins/item.py @@ -107,7 +107,7 @@ def flush_errors(new_messages: List[str], serious: bool) -> None: build.build(sources, options, flush_errors=flush_errors, fscache=fscache) except SystemExit as sysexit: - return sysexit.code + return sysexit.code if isinstance(sysexit.code, int) else 1 finally: fscache.flush() @@ -241,7 +241,6 @@ def runtest(self) -> None: temp_dir = tempfile.TemporaryDirectory(prefix="pytest-mypy-", dir=self.root_directory) except (FileNotFoundError, PermissionError, NotADirectoryError) as e: - raise TypecheckAssertionError( error_message=f"Testing base directory {self.root_directory} must exist and be writable" ) from e diff --git a/pytest_mypy_plugins/tests/test-parametrized.yml b/pytest_mypy_plugins/tests/test-parametrized.yml index 4df19e2..3947dda 100644 --- a/pytest_mypy_plugins/tests/test-parametrized.yml +++ b/pytest_mypy_plugins/tests/test-parametrized.yml @@ -45,3 +45,5 @@ out: | main:2: note: Revealed type is "{{ rt }}" main:4: error: Unsupported operand types for / ("str" and "int") + mypy_config: | + hide_error_codes = True diff --git a/pytest_mypy_plugins/tests/test-paths-from-env.yml b/pytest_mypy_plugins/tests/test-paths-from-env.yml index 62ef522..739cbb1 100644 --- a/pytest_mypy_plugins/tests/test-paths-from-env.yml +++ b/pytest_mypy_plugins/tests/test-paths-from-env.yml @@ -11,3 +11,5 @@ content: | def extra_fn() -> None: pass + mypy_config: | + hide_error_codes = True diff --git a/pytest_mypy_plugins/tests/test-simple-cases.yml b/pytest_mypy_plugins/tests/test-simple-cases.yml index e324f46..aacc6a8 100644 --- a/pytest_mypy_plugins/tests/test-simple-cases.yml +++ b/pytest_mypy_plugins/tests/test-simple-cases.yml @@ -58,6 +58,8 @@ main: | a = 1 a.lower() # E: "int" has no attribute "lower" + mypy_config: | + hide_error_codes = True - case: custom_mypy_config_strict_optional_true_set @@ -88,6 +90,8 @@ main: | a = 1 a.lower() # E: "int" has no attribute "lower" + mypy_config: | + hide_error_codes = True - case: fail_if_message_does_not_match expect_fail: yes @@ -101,4 +105,4 @@ a = 'abc' reveal_type(a) out: | - main:2: note: Some other message \ No newline at end of file + main:2: note: Some other message diff --git a/pytest_mypy_plugins/tests/test_parametrized_html_escape.yml b/pytest_mypy_plugins/tests/test_parametrized_html_escape.yml new file mode 100644 index 0000000..3d0e2a1 --- /dev/null +++ b/pytest_mypy_plugins/tests/test_parametrized_html_escape.yml @@ -0,0 +1,11 @@ +- case: gt_in_rt + parametrized: + - val: bool + rt: def (builtins.object =) -> builtins.bool + main: | + reveal_type({{ val }}) # N: Revealed type is "{{ rt }}" + + +- case: gt_in_comment + main: | + reveal_type(bool) # N: Revealed type is "def (builtins.object =) -> builtins.bool" diff --git a/pytest_mypy_plugins/utils.py b/pytest_mypy_plugins/utils.py index 837b3d7..2844ce0 100644 --- a/pytest_mypy_plugins/utils.py +++ b/pytest_mypy_plugins/utils.py @@ -1,6 +1,7 @@ # Borrowed from Pew. # See https://github.com/berdario/pew/blob/master/pew/_utils.py#L82 import contextlib +import html import inspect import io import os @@ -352,7 +353,9 @@ def extract_output_matchers_from_out(out: str, params: Mapping[str, Any], regex: def render_template(template: str, data: Mapping[str, Any]) -> str: - return chevron.render(template=template, data={k: v if v is not None else "None" for k, v in data.items()}) + return html.unescape( + chevron.render(template=template, data={k: v if v is not None else "None" for k, v in data.items()}) + ) def get_func_first_lnum(attr: Callable[..., None]) -> Optional[Tuple[int, List[str]]]: diff --git a/setup.py b/setup.py index 0d59571..2175fd4 100644 --- a/setup.py +++ b/setup.py @@ -39,6 +39,7 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Typing :: Typed", ], )