From deb08a30e054eef7fb18a23ef666319c3d5a51a6 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 19 Oct 2024 15:41:17 +0900 Subject: [PATCH 01/30] Pyright wants aliases everywhere --- src/trio/_core/_local.py | 4 +- src/trio/_core/_run.py | 10 +++-- src/trio/_tests/test_exports.py | 70 +++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/src/trio/_core/_local.py b/src/trio/_core/_local.py index 53cbfc135..141a30b52 100644 --- a/src/trio/_core/_local.py +++ b/src/trio/_core/_local.py @@ -38,8 +38,8 @@ class RunVar(Generic[T]): """ - _name: str - _default: T | type[_NoValue] = _NoValue + _name: str = attrs.field(alias="name") + _default: T | type[_NoValue] = attrs.field(default=_NoValue, alias="default") def get(self, default: T | type[_NoValue] = _NoValue) -> T: """Gets the value of this :class:`RunVar` for the current run call.""" diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index cba7a8dec..f141685eb 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -544,9 +544,13 @@ class CancelScope: cancelled_caught: bool = attrs.field(default=False, init=False) # Constructor arguments: - _relative_deadline: float = attrs.field(default=inf, kw_only=True) - _deadline: float = attrs.field(default=inf, kw_only=True) - _shield: bool = attrs.field(default=False, kw_only=True) + _relative_deadline: float = attrs.field( + default=inf, + kw_only=True, + alias="relative_deadline", + ) + _deadline: float = attrs.field(default=inf, kw_only=True, alias="deadline") + _shield: bool = attrs.field(default=False, kw_only=True, alias="shield") def __attrs_post_init__(self) -> None: if isnan(self._deadline): diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index a463b778f..036ad93cb 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -9,6 +9,7 @@ import json import socket as stdlib_socket import sys +import tokenize import types from pathlib import Path, PurePath from types import ModuleType @@ -572,3 +573,72 @@ def test_classes_are_final() -> None: continue assert class_is_final(class_) + + +def test_pyright_recognizes_init_attributes() -> None: + # Obviously, this isn't completely accurate. + # It should still be good enough. Hopefully. + # (attrs updates fields before we can access them) + files = [] + + for path in (Path(inspect.getfile(trio)) / "..").glob("**/*.py"): + with open(path, "rb") as f: + files.append(list(tokenize.tokenize(f.readline))) + + for module in PUBLIC_MODULES: + for name, class_ in module.__dict__.items(): + if not attrs.has(class_): + continue + if isinstance(class_, _util.NoPublicConstructor): + continue + + file = None + start = None + for contents in files: + last_was_class = False + for i, token in enumerate(contents): + if ( + token.type == tokenize.NAME + and token.string == name + and last_was_class + ): + assert file is None + file = contents + start = i - 1 + + if token.type == tokenize.NAME and token.string == "class": + last_was_class = True + else: + last_was_class = False + + assert file is not None + + count = -1 + # linters don't like my not using the index, go figure. + for end_offset, token in enumerate(file[start:]): # noqa: B007 + if token.type == tokenize.INDENT: + count += 1 + if token.type == tokenize.DEDENT and count: + count -= 1 + elif token.type == tokenize.DEDENT: + break + + assert token.type == tokenize.DEDENT + class_source = ( + tokenize.untokenize(file[start : start + end_offset]) + .replace("\\", "") + .strip() + ) + + attributes = list(attrs.fields(class_)) + attributes = [attr for attr in attributes if attr.name.startswith("_")] + attributes = [attr for attr in attributes if attr.init] + + attributes = [ + # could this be improved by parsing AST? yes. this is simpler though. + attr + for attr in attributes + if f'alias="{attr.alias}"' not in class_source + ] + + assert attributes == [], class_ From 1e65f6880b3a16180ace95c7e2e20bee9f003cc1 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 19 Oct 2024 15:46:14 +0900 Subject: [PATCH 02/30] Changelog --- newsfragments/3114.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 newsfragments/3114.bugfix.rst diff --git a/newsfragments/3114.bugfix.rst b/newsfragments/3114.bugfix.rst new file mode 100644 index 000000000..2f0771219 --- /dev/null +++ b/newsfragments/3114.bugfix.rst @@ -0,0 +1 @@ +Ensure that Pyright recognizes our underscore prefixed attributes for attrs classes. From 59abcf880851138b26249e16e713ca43d132479b Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 19 Oct 2024 15:49:36 +0900 Subject: [PATCH 03/30] Make backslash replacement more correct --- src/trio/_tests/test_exports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 036ad93cb..fde1943a5 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -626,7 +626,7 @@ def test_pyright_recognizes_init_attributes() -> None: assert token.type == tokenize.DEDENT class_source = ( tokenize.untokenize(file[start : start + end_offset]) - .replace("\\", "") + .replace("\\\n", "") .strip() ) From cbb08fb142563952616ebb0e05794160732760d0 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 19 Oct 2024 03:14:46 -0400 Subject: [PATCH 04/30] Debug which class doesn't exist --- src/trio/_tests/test_exports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index fde1943a5..1e5541932 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -611,7 +611,7 @@ def test_pyright_recognizes_init_attributes() -> None: else: last_was_class = False - assert file is not None + assert file is not None, class_ count = -1 # linters don't like my not using the index, go figure. From 9c97bad2c0aa6cff47526540e3a1be38c7c82c9f Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 19 Oct 2024 03:19:09 -0400 Subject: [PATCH 05/30] Debug a bit better --- src/trio/_tests/test_exports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 1e5541932..46f419b62 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -611,7 +611,7 @@ def test_pyright_recognizes_init_attributes() -> None: else: last_was_class = False - assert file is not None, class_ + assert file is not None, f"{name}: {class_!r}" count = -1 # linters don't like my not using the index, go figure. From 35609d403abf644d78e289e9749625037841d1d6 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 19 Oct 2024 16:32:28 +0900 Subject: [PATCH 06/30] Fix weirdness around PosixPath needing to be resolved --- src/trio/_tests/test_exports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 46f419b62..446a9550c 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -581,7 +581,7 @@ def test_pyright_recognizes_init_attributes() -> None: # (attrs updates fields before we can access them) files = [] - for path in (Path(inspect.getfile(trio)) / "..").glob("**/*.py"): + for path in (Path(inspect.getfile(trio)) / "..").resolve().glob("**/*.py"): with open(path, "rb") as f: files.append(list(tokenize.tokenize(f.readline))) From 4bc3e588f9c65be7aa52043da0ab2fb845e268bc Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sat, 19 Oct 2024 16:35:29 +0900 Subject: [PATCH 07/30] Appease type checker --- src/trio/_tests/test_exports.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 446a9550c..5f6d3d59f 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -612,6 +612,7 @@ def test_pyright_recognizes_init_attributes() -> None: last_was_class = False assert file is not None, f"{name}: {class_!r}" + assert start is not None count = -1 # linters don't like my not using the index, go figure. From 37b9c38f3ec07c7eb60745967b2720d784bad815 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 20 Oct 2024 19:30:55 +0900 Subject: [PATCH 08/30] Don't even consider tests in the alias test --- src/trio/_tests/test_exports.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 5f6d3d59f..a3992a8d6 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -581,7 +581,11 @@ def test_pyright_recognizes_init_attributes() -> None: # (attrs updates fields before we can access them) files = [] - for path in (Path(inspect.getfile(trio)) / "..").resolve().glob("**/*.py"): + parent = (Path(inspect.getfile(trio)) / "..").resolve() + for path in parent.glob("**/*.py"): + if "_tests" in path[len(parent) :]: + continue + with open(path, "rb") as f: files.append(list(tokenize.tokenize(f.readline))) From 3cda304e17a2593a9152f72bd9cc05bee6ca8a5d Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 20 Oct 2024 19:33:56 +0900 Subject: [PATCH 09/30] Turn paths into strings before indexing --- src/trio/_tests/test_exports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index a3992a8d6..a4b2f0fab 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -583,7 +583,7 @@ def test_pyright_recognizes_init_attributes() -> None: parent = (Path(inspect.getfile(trio)) / "..").resolve() for path in parent.glob("**/*.py"): - if "_tests" in path[len(parent) :]: + if "_tests" in str(path)[len(str(parent)) :]: continue with open(path, "rb") as f: From 9eca8515be8e86b60dae42984ef2916ac5f01ca0 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sun, 20 Oct 2024 19:38:28 -0400 Subject: [PATCH 10/30] Explain the test better --- src/trio/_tests/test_exports.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index a4b2f0fab..7dad2a676 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -576,9 +576,26 @@ def test_classes_are_final() -> None: def test_pyright_recognizes_init_attributes() -> None: - # Obviously, this isn't completely accurate. - # It should still be good enough. Hopefully. - # (attrs updates fields before we can access them) + """Check whether we provide `alias` for all underscore prefixed attributes + + We cannot check this at runtime, as attrs sets the `alias` attribute on + fields, but instead we can reconstruct the source code of the class and + check that. Unfortunately, `inspect.getsourcelines` does not work so we + need to build up this source code ourself. + + The approach taken here is: + 1. read every file that could contain the classes in question + 2. tokenize them, for a couple reasons: + - tokenization unlike ast parsing can be 1-1 undone + - tokenization allows us to get the whole class block + - tokenization allows us to find ``class {name}`` without prefix + matches + 3. for every exported class: + 1. find the file + 2. isolate the class block + 3. undo tokenization + 4. find the string ``alias="{what it should be}"`` + """ files = [] parent = (Path(inspect.getfile(trio)) / "..").resolve() @@ -619,8 +636,8 @@ def test_pyright_recognizes_init_attributes() -> None: assert start is not None count = -1 - # linters don't like my not using the index, go figure. - for end_offset, token in enumerate(file[start:]): # noqa: B007 + end_offset = 0 + for end_offset, token in enumerate(file[start:]): # pragma: no branch if token.type == tokenize.INDENT: count += 1 if token.type == tokenize.DEDENT and count: From ba67f7e6df7bebb12a4da41b7a5f02d08ad2988a Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sun, 20 Oct 2024 19:42:21 -0400 Subject: [PATCH 11/30] Fixes for pre-commit --- src/trio/_tests/test_exports.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 7dad2a676..2b32b0eb7 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -577,12 +577,12 @@ def test_classes_are_final() -> None: def test_pyright_recognizes_init_attributes() -> None: """Check whether we provide `alias` for all underscore prefixed attributes - + We cannot check this at runtime, as attrs sets the `alias` attribute on fields, but instead we can reconstruct the source code of the class and check that. Unfortunately, `inspect.getsourcelines` does not work so we need to build up this source code ourself. - + The approach taken here is: 1. read every file that could contain the classes in question 2. tokenize them, for a couple reasons: @@ -637,7 +637,7 @@ def test_pyright_recognizes_init_attributes() -> None: count = -1 end_offset = 0 - for end_offset, token in enumerate(file[start:]): # pragma: no branch + for end_offset, token in enumerate(file[start:]): # pragma: no branch # noqa: B007 if token.type == tokenize.INDENT: count += 1 if token.type == tokenize.DEDENT and count: From 88cf458e6d36b0acfa7e2343b40900bb05cebf21 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sun, 20 Oct 2024 19:45:38 -0400 Subject: [PATCH 12/30] Reformat according to black --- src/trio/_tests/test_exports.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 2b32b0eb7..b777684c6 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -637,7 +637,9 @@ def test_pyright_recognizes_init_attributes() -> None: count = -1 end_offset = 0 - for end_offset, token in enumerate(file[start:]): # pragma: no branch # noqa: B007 + for end_offset, token in enumerate( # noqa: B007 + file[start:] + ): # pragma: no branch if token.type == tokenize.INDENT: count += 1 if token.type == tokenize.DEDENT and count: From 819797afaf12c5af73357ac17897a389710efed4 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sun, 20 Oct 2024 19:46:41 -0400 Subject: [PATCH 13/30] One last pre-commit fix --- src/trio/_tests/test_exports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index b777684c6..6ed879fde 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -638,7 +638,7 @@ def test_pyright_recognizes_init_attributes() -> None: count = -1 end_offset = 0 for end_offset, token in enumerate( # noqa: B007 - file[start:] + file[start:], ): # pragma: no branch if token.type == tokenize.INDENT: count += 1 From f21cbb01567fcb36bc9e29c8be033394408cc4c9 Mon Sep 17 00:00:00 2001 From: Spencer Brown Date: Tue, 22 Oct 2024 11:43:40 +1000 Subject: [PATCH 14/30] Simplify alias test by monkeypatching attrs. --- pyproject.toml | 2 +- src/_trio_check_attrs_aliases.py | 21 ++++++++ src/trio/_tests/test_exports.py | 90 ++++---------------------------- 3 files changed, 33 insertions(+), 80 deletions(-) create mode 100644 src/_trio_check_attrs_aliases.py diff --git a/pyproject.toml b/pyproject.toml index ff4aa3460..9d57d2b2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -189,7 +189,7 @@ reportUnnecessaryTypeIgnoreComment = true typeCheckingMode = "strict" [tool.pytest.ini_options] -addopts = ["--strict-markers", "--strict-config", "-p trio._tests.pytest_plugin"] +addopts = ["--strict-markers", "--strict-config", "-p _trio_check_attrs_aliases", "-p trio._tests.pytest_plugin"] faulthandler_timeout = 60 filterwarnings = [ "error", diff --git a/src/_trio_check_attrs_aliases.py b/src/_trio_check_attrs_aliases.py new file mode 100644 index 000000000..d716949d8 --- /dev/null +++ b/src/_trio_check_attrs_aliases.py @@ -0,0 +1,21 @@ +"""Conftest is executed by Pytest before test modules. + +We use this to monkeypatch attrs.field(), so that we can detect if aliases are used for test_exports. +""" + +from typing import Any + +import attrs + +orig_field = attrs.field + + +def field(**kwargs: Any) -> Any: + if "alias" in kwargs: + metadata = kwargs.setdefault("metadata", {}) + metadata["trio_test_has_alias"] = True + return orig_field(**kwargs) + + +field.trio_modded = True # type: ignore +attrs.field = field diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 6ed879fde..8c5f33505 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -9,7 +9,6 @@ import json import socket as stdlib_socket import sys -import tokenize import types from pathlib import Path, PurePath from types import ModuleType @@ -576,93 +575,26 @@ def test_classes_are_final() -> None: def test_pyright_recognizes_init_attributes() -> None: - """Check whether we provide `alias` for all underscore prefixed attributes - - We cannot check this at runtime, as attrs sets the `alias` attribute on - fields, but instead we can reconstruct the source code of the class and - check that. Unfortunately, `inspect.getsourcelines` does not work so we - need to build up this source code ourself. - - The approach taken here is: - 1. read every file that could contain the classes in question - 2. tokenize them, for a couple reasons: - - tokenization unlike ast parsing can be 1-1 undone - - tokenization allows us to get the whole class block - - tokenization allows us to find ``class {name}`` without prefix - matches - 3. for every exported class: - 1. find the file - 2. isolate the class block - 3. undo tokenization - 4. find the string ``alias="{what it should be}"`` - """ - files = [] - - parent = (Path(inspect.getfile(trio)) / "..").resolve() - for path in parent.glob("**/*.py"): - if "_tests" in str(path)[len(str(parent)) :]: - continue - - with open(path, "rb") as f: - files.append(list(tokenize.tokenize(f.readline))) + """Check whether we provide `alias` for all underscore prefixed attributes. + Attrs always sets the `alias` attribute on fields, so a pytest plugin is used + to monkeypatch `field()` to record whether an alias was defined in the metadata. + See `_trio_check_attrs_aliases`. + """ + assert hasattr(attrs.field, "trio_modded") for module in PUBLIC_MODULES: - for name, class_ in module.__dict__.items(): + for class_ in module.__dict__.values(): if not attrs.has(class_): continue if isinstance(class_, _util.NoPublicConstructor): continue - file = None - start = None - for contents in files: - last_was_class = False - for i, token in enumerate(contents): - if ( - token.type == tokenize.NAME - and token.string == name - and last_was_class - ): - assert file is None - file = contents - start = i - 1 - - if token.type == tokenize.NAME and token.string == "class": - last_was_class = True - else: - last_was_class = False - - assert file is not None, f"{name}: {class_!r}" - assert start is not None - - count = -1 - end_offset = 0 - for end_offset, token in enumerate( # noqa: B007 - file[start:], - ): # pragma: no branch - if token.type == tokenize.INDENT: - count += 1 - if token.type == tokenize.DEDENT and count: - count -= 1 - elif token.type == tokenize.DEDENT: - break - - assert token.type == tokenize.DEDENT - class_source = ( - tokenize.untokenize(file[start : start + end_offset]) - .replace("\\\n", "") - .strip() - ) - - attributes = list(attrs.fields(class_)) - attributes = [attr for attr in attributes if attr.name.startswith("_")] - attributes = [attr for attr in attributes if attr.init] - attributes = [ - # could this be improved by parsing AST? yes. this is simpler though. attr - for attr in attributes - if f'alias="{attr.alias}"' not in class_source + for attr in attrs.fields(class_) + if attr.name.startswith("_") + if attr.init + if "trio_test_has_alias" not in attr.metadata ] assert attributes == [], class_ From 30befc904928bb7210d53f54e1de339888ea8449 Mon Sep 17 00:00:00 2001 From: Spencer Brown Date: Sun, 10 Nov 2024 10:02:13 +1000 Subject: [PATCH 15/30] Skip pyright init attributes test if plugin has not run --- src/_trio_check_attrs_aliases.py | 1 + src/trio/_tests/test_exports.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/_trio_check_attrs_aliases.py b/src/_trio_check_attrs_aliases.py index d716949d8..256160832 100644 --- a/src/_trio_check_attrs_aliases.py +++ b/src/_trio_check_attrs_aliases.py @@ -17,5 +17,6 @@ def field(**kwargs: Any) -> Any: return orig_field(**kwargs) +# Mark it as being ours, so the test knows it can actually run. field.trio_modded = True # type: ignore attrs.field = field diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 8c5f33505..90ece79e9 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -574,6 +574,11 @@ def test_classes_are_final() -> None: assert class_is_final(class_) +# Plugin might not be running, especially if running from an installed version. +@pytest.mark.skipif( + not hasattr(attrs.field, "trio_modded"), + reason="Pytest plugin not installed.", +) def test_pyright_recognizes_init_attributes() -> None: """Check whether we provide `alias` for all underscore prefixed attributes. @@ -581,7 +586,6 @@ def test_pyright_recognizes_init_attributes() -> None: to monkeypatch `field()` to record whether an alias was defined in the metadata. See `_trio_check_attrs_aliases`. """ - assert hasattr(attrs.field, "trio_modded") for module in PUBLIC_MODULES: for class_ in module.__dict__.values(): if not attrs.has(class_): From a23712c657cac955f391963bbce8647e16a48dcc Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sat, 9 Nov 2024 19:59:30 -0500 Subject: [PATCH 16/30] Catch any other renaming too --- src/_trio_check_attrs_aliases.py | 6 +++--- src/trio/_tests/test_exports.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/_trio_check_attrs_aliases.py b/src/_trio_check_attrs_aliases.py index 256160832..0454c8da5 100644 --- a/src/_trio_check_attrs_aliases.py +++ b/src/_trio_check_attrs_aliases.py @@ -11,9 +11,9 @@ def field(**kwargs: Any) -> Any: - if "alias" in kwargs: - metadata = kwargs.setdefault("metadata", {}) - metadata["trio_test_has_alias"] = True + original_args = kwargs.copy() + metadata = kwargs.setdefault("metadata", {}) + metadata["original_args"] = original_args return orig_field(**kwargs) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 90ece79e9..8dc13f1fd 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -596,9 +596,8 @@ def test_pyright_recognizes_init_attributes() -> None: attributes = [ attr for attr in attrs.fields(class_) - if attr.name.startswith("_") if attr.init - if "trio_test_has_alias" not in attr.metadata + if attr.alias not in (attr.name, attr.metadata["original_args"].get("alias")) ] assert attributes == [], class_ From 74e67f16096b7675d6c06d20b6f4a4e4a7df0f91 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 10 Nov 2024 00:59:42 +0000 Subject: [PATCH 17/30] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/trio/_tests/test_exports.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 8dc13f1fd..92b9a500a 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -597,7 +597,8 @@ def test_pyright_recognizes_init_attributes() -> None: attr for attr in attrs.fields(class_) if attr.init - if attr.alias not in (attr.name, attr.metadata["original_args"].get("alias")) + if attr.alias + not in (attr.name, attr.metadata["original_args"].get("alias")) ] assert attributes == [], class_ From 593701be3e79cd103b4269b7a1b3ab406947bf1a Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 10 Nov 2024 10:39:13 +0900 Subject: [PATCH 18/30] Handle autoattribs --- src/trio/_tests/test_exports.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 92b9a500a..640db7a9e 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -598,7 +598,11 @@ def test_pyright_recognizes_init_attributes() -> None: for attr in attrs.fields(class_) if attr.init if attr.alias - not in (attr.name, attr.metadata["original_args"].get("alias")) + not in ( + attr.name, + # original_args may not be present in autoattribs + attr.metadata.get("original_args", {}).get("alias"), + ) ] assert attributes == [], class_ From ff487e2816998d38e45a03ccf9683cf058f95633 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 10 Nov 2024 11:59:01 +0900 Subject: [PATCH 19/30] Disambiguate --- src/trio/_tests/test_exports.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index 640db7a9e..d105f9918 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -600,8 +600,8 @@ def test_pyright_recognizes_init_attributes() -> None: if attr.alias not in ( attr.name, - # original_args may not be present in autoattribs - attr.metadata.get("original_args", {}).get("alias"), + # trio_original_args may not be present in autoattribs + attr.metadata.get("trio_original_args", {}).get("alias"), ) ] From a6ea1487da4a83eabddd973b4bc80e4bf34c1427 Mon Sep 17 00:00:00 2001 From: Spencer Brown Date: Sun, 10 Nov 2024 15:05:42 +1000 Subject: [PATCH 20/30] Synchronise name --- src/_trio_check_attrs_aliases.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_trio_check_attrs_aliases.py b/src/_trio_check_attrs_aliases.py index 0454c8da5..3b8e518c0 100644 --- a/src/_trio_check_attrs_aliases.py +++ b/src/_trio_check_attrs_aliases.py @@ -13,7 +13,7 @@ def field(**kwargs: Any) -> Any: original_args = kwargs.copy() metadata = kwargs.setdefault("metadata", {}) - metadata["original_args"] = original_args + metadata["trio_original_args"] = original_args return orig_field(**kwargs) From 637cc5f42928655e4c02f74679c91ff88dd2c034 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 15:50:50 +0900 Subject: [PATCH 21/30] Update import mode because it worked locally --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9d57d2b2d..58d58f369 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -189,7 +189,7 @@ reportUnnecessaryTypeIgnoreComment = true typeCheckingMode = "strict" [tool.pytest.ini_options] -addopts = ["--strict-markers", "--strict-config", "-p _trio_check_attrs_aliases", "-p trio._tests.pytest_plugin"] +addopts = ["--strict-markers", "--strict-config", "-p _trio_check_attrs_aliases", "-p trio._tests.pytest_plugin", "--import-mode=importlib"] faulthandler_timeout = 60 filterwarnings = [ "error", From d8c0983ca070c2baf277d5c3aa209eda61316244 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 16:20:55 +0900 Subject: [PATCH 22/30] Check suspicions --- ci.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci.sh b/ci.sh index ef3dee55c..a19e2fb26 100755 --- a/ci.sh +++ b/ci.sh @@ -130,6 +130,11 @@ else # support subprocess spawning with coverage.py echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py" + # confirm or deny suspicions (this *should* fail.) + # we are currently in `.../empty` and we only installed the built wheel from trio + # ... I suspect this will pass, because it's in the wheel. that would be bad! + python -c "import _trio_check_attrs_aliases" + echo "::endgroup::" echo "::group:: Run Tests" if COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml coverage run --rcfile=../pyproject.toml -m pytest -ra --junitxml=../test-results.xml --run-slow "${INSTALLDIR}" --verbose --durations=10 $flags; then From f32b8fba243f1de6c455aaa7b4a014981d6637b2 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 16:23:45 +0900 Subject: [PATCH 23/30] Double check --- ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index a19e2fb26..6c37d33e3 100755 --- a/ci.sh +++ b/ci.sh @@ -133,7 +133,7 @@ else # confirm or deny suspicions (this *should* fail.) # we are currently in `.../empty` and we only installed the built wheel from trio # ... I suspect this will pass, because it's in the wheel. that would be bad! - python -c "import _trio_check_attrs_aliases" + ls "$INSTALLDIR/../" echo "::endgroup::" echo "::group:: Run Tests" From 7ccead5d29eaa29c0d0314eb1867668909cdee69 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 16:39:42 +0900 Subject: [PATCH 24/30] Don't rely on installing `_trio_check_attrs_aliases.py` as a module --- ci.sh | 10 ++++------ pyproject.toml | 2 +- {src => tests}/_trio_check_attrs_aliases.py | 0 3 files changed, 5 insertions(+), 7 deletions(-) rename {src => tests}/_trio_check_attrs_aliases.py (100%) diff --git a/ci.sh b/ci.sh index 6c37d33e3..f43e1b515 100755 --- a/ci.sh +++ b/ci.sh @@ -130,14 +130,12 @@ else # support subprocess spawning with coverage.py echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py" - # confirm or deny suspicions (this *should* fail.) - # we are currently in `.../empty` and we only installed the built wheel from trio - # ... I suspect this will pass, because it's in the wheel. that would be bad! - ls "$INSTALLDIR/../" - echo "::endgroup::" echo "::group:: Run Tests" - if COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml coverage run --rcfile=../pyproject.toml -m pytest -ra --junitxml=../test-results.xml --run-slow "${INSTALLDIR}" --verbose --durations=10 $flags; then + if PYTHONPATH=../tests COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml \ + coverage run --rcfile=../pyproject.toml -m \ + pytest -ra --junitxml=../test-results.xml --run-slow --verbose --durations=10 $flags \ + -p _trio_check_attrs_aliases "${INSTALLDIR}"; then PASSED=true else PASSED=false diff --git a/pyproject.toml b/pyproject.toml index 58d58f369..b0a8ad5ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -189,7 +189,7 @@ reportUnnecessaryTypeIgnoreComment = true typeCheckingMode = "strict" [tool.pytest.ini_options] -addopts = ["--strict-markers", "--strict-config", "-p _trio_check_attrs_aliases", "-p trio._tests.pytest_plugin", "--import-mode=importlib"] +addopts = ["--strict-markers", "--strict-config", "-p trio._tests.pytest_plugin", "--import-mode=importlib"] faulthandler_timeout = 60 filterwarnings = [ "error", diff --git a/src/_trio_check_attrs_aliases.py b/tests/_trio_check_attrs_aliases.py similarity index 100% rename from src/_trio_check_attrs_aliases.py rename to tests/_trio_check_attrs_aliases.py From 9b4c585e31b4e7c36ad370d3d619966a2751f7de Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 16:47:48 +0900 Subject: [PATCH 25/30] importlib import mode means we can use conftest again! --- ci.sh | 2 +- pyproject.toml | 2 +- src/trio/_core/_tests/tutil.py | 2 +- src/trio/_tests/{pytest_plugin.py => conftest.py} | 0 src/trio/_tests/test_dtls.py | 2 +- src/trio/_tests/test_exports.py | 3 +-- src/trio/_tests/test_ssl.py | 2 +- src/trio/_tests/tools/test_gen_exports.py | 2 +- tests/_trio_check_attrs_aliases.py | 2 +- 9 files changed, 8 insertions(+), 9 deletions(-) rename src/trio/_tests/{pytest_plugin.py => conftest.py} (100%) diff --git a/ci.sh b/ci.sh index f43e1b515..c807520d6 100755 --- a/ci.sh +++ b/ci.sh @@ -135,7 +135,7 @@ else if PYTHONPATH=../tests COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml \ coverage run --rcfile=../pyproject.toml -m \ pytest -ra --junitxml=../test-results.xml --run-slow --verbose --durations=10 $flags \ - -p _trio_check_attrs_aliases "${INSTALLDIR}"; then + -Wall -p _trio_check_attrs_aliases "${INSTALLDIR}"; then PASSED=true else PASSED=false diff --git a/pyproject.toml b/pyproject.toml index b0a8ad5ba..1c5378844 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -189,7 +189,7 @@ reportUnnecessaryTypeIgnoreComment = true typeCheckingMode = "strict" [tool.pytest.ini_options] -addopts = ["--strict-markers", "--strict-config", "-p trio._tests.pytest_plugin", "--import-mode=importlib"] +addopts = ["--strict-markers", "--strict-config", "--import-mode=importlib"] faulthandler_timeout = 60 filterwarnings = [ "error", diff --git a/src/trio/_core/_tests/tutil.py b/src/trio/_core/_tests/tutil.py index 81370ed76..19c3e3650 100644 --- a/src/trio/_core/_tests/tutil.py +++ b/src/trio/_core/_tests/tutil.py @@ -13,7 +13,7 @@ import pytest # See trio/_tests/conftest.py for the other half of this -from trio._tests.pytest_plugin import RUN_SLOW +from trio._tests.conftest import RUN_SLOW if TYPE_CHECKING: from collections.abc import Generator, Iterable, Sequence diff --git a/src/trio/_tests/pytest_plugin.py b/src/trio/_tests/conftest.py similarity index 100% rename from src/trio/_tests/pytest_plugin.py rename to src/trio/_tests/conftest.py diff --git a/src/trio/_tests/test_dtls.py b/src/trio/_tests/test_dtls.py index 43ad273e5..20fac6275 100644 --- a/src/trio/_tests/test_dtls.py +++ b/src/trio/_tests/test_dtls.py @@ -8,7 +8,7 @@ import attrs import pytest -from trio._tests.pytest_plugin import skip_if_optional_else_raise +from trio._tests.conftest import skip_if_optional_else_raise try: import trustme diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index d105f9918..b1a480f5b 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -19,11 +19,10 @@ import trio import trio.testing -from trio._tests.pytest_plugin import skip_if_optional_else_raise +from trio._tests.conftest import RUN_SLOW, skip_if_optional_else_raise from .. import _core, _util from .._core._tests.tutil import slow -from .pytest_plugin import RUN_SLOW if TYPE_CHECKING: from collections.abc import Iterable, Iterator diff --git a/src/trio/_tests/test_ssl.py b/src/trio/_tests/test_ssl.py index 7197a47cc..0cec70911 100644 --- a/src/trio/_tests/test_ssl.py +++ b/src/trio/_tests/test_ssl.py @@ -21,7 +21,7 @@ import pytest from trio import StapledStream -from trio._tests.pytest_plugin import skip_if_optional_else_raise +from trio._tests.conftest import skip_if_optional_else_raise from trio.abc import ReceiveStream, SendStream from trio.testing import ( Matcher, diff --git a/src/trio/_tests/tools/test_gen_exports.py b/src/trio/_tests/tools/test_gen_exports.py index 669df968e..7b122daf4 100644 --- a/src/trio/_tests/tools/test_gen_exports.py +++ b/src/trio/_tests/tools/test_gen_exports.py @@ -4,7 +4,7 @@ import pytest -from trio._tests.pytest_plugin import skip_if_optional_else_raise +from trio._tests.conftest import skip_if_optional_else_raise # imports in gen_exports that are not in `install_requires` in setup.py try: diff --git a/tests/_trio_check_attrs_aliases.py b/tests/_trio_check_attrs_aliases.py index 3b8e518c0..b4a339dab 100644 --- a/tests/_trio_check_attrs_aliases.py +++ b/tests/_trio_check_attrs_aliases.py @@ -1,4 +1,4 @@ -"""Conftest is executed by Pytest before test modules. +"""Plugins are executed by Pytest before test modules. We use this to monkeypatch attrs.field(), so that we can detect if aliases are used for test_exports. """ From 0c1ca17b51191ac0acb3d65dcb9ea9a8d81e3827 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 16:58:13 +0900 Subject: [PATCH 26/30] Just do something hacky instead --- ci.sh | 1 + pyproject.toml | 2 +- src/trio/_core/_tests/tutil.py | 4 ++-- src/trio/_tests/{conftest.py => pytest_plugin.py} | 0 src/trio/_tests/test_dtls.py | 2 +- src/trio/_tests/test_exports.py | 2 +- src/trio/_tests/test_ssl.py | 2 +- src/trio/_tests/tools/test_gen_exports.py | 2 +- 8 files changed, 8 insertions(+), 7 deletions(-) rename src/trio/_tests/{conftest.py => pytest_plugin.py} (100%) diff --git a/ci.sh b/ci.sh index c807520d6..193a4c262 100755 --- a/ci.sh +++ b/ci.sh @@ -130,6 +130,7 @@ else # support subprocess spawning with coverage.py echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py" + sed -i 's/-p trio\._tests\.pytest_plugin//' "$(pwd)/../pyproject.toml" echo "::endgroup::" echo "::group:: Run Tests" if PYTHONPATH=../tests COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml \ diff --git a/pyproject.toml b/pyproject.toml index 1c5378844..b0a8ad5ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -189,7 +189,7 @@ reportUnnecessaryTypeIgnoreComment = true typeCheckingMode = "strict" [tool.pytest.ini_options] -addopts = ["--strict-markers", "--strict-config", "--import-mode=importlib"] +addopts = ["--strict-markers", "--strict-config", "-p trio._tests.pytest_plugin", "--import-mode=importlib"] faulthandler_timeout = 60 filterwarnings = [ "error", diff --git a/src/trio/_core/_tests/tutil.py b/src/trio/_core/_tests/tutil.py index 19c3e3650..063fa1dd8 100644 --- a/src/trio/_core/_tests/tutil.py +++ b/src/trio/_core/_tests/tutil.py @@ -12,8 +12,8 @@ import pytest -# See trio/_tests/conftest.py for the other half of this -from trio._tests.conftest import RUN_SLOW +# See trio/_tests/pytest_plugin.py for the other half of this +from trio._tests.pytest_plugin import RUN_SLOW if TYPE_CHECKING: from collections.abc import Generator, Iterable, Sequence diff --git a/src/trio/_tests/conftest.py b/src/trio/_tests/pytest_plugin.py similarity index 100% rename from src/trio/_tests/conftest.py rename to src/trio/_tests/pytest_plugin.py diff --git a/src/trio/_tests/test_dtls.py b/src/trio/_tests/test_dtls.py index 20fac6275..43ad273e5 100644 --- a/src/trio/_tests/test_dtls.py +++ b/src/trio/_tests/test_dtls.py @@ -8,7 +8,7 @@ import attrs import pytest -from trio._tests.conftest import skip_if_optional_else_raise +from trio._tests.pytest_plugin import skip_if_optional_else_raise try: import trustme diff --git a/src/trio/_tests/test_exports.py b/src/trio/_tests/test_exports.py index b1a480f5b..cf34dc8a2 100644 --- a/src/trio/_tests/test_exports.py +++ b/src/trio/_tests/test_exports.py @@ -19,7 +19,7 @@ import trio import trio.testing -from trio._tests.conftest import RUN_SLOW, skip_if_optional_else_raise +from trio._tests.pytest_plugin import RUN_SLOW, skip_if_optional_else_raise from .. import _core, _util from .._core._tests.tutil import slow diff --git a/src/trio/_tests/test_ssl.py b/src/trio/_tests/test_ssl.py index 0cec70911..7197a47cc 100644 --- a/src/trio/_tests/test_ssl.py +++ b/src/trio/_tests/test_ssl.py @@ -21,7 +21,7 @@ import pytest from trio import StapledStream -from trio._tests.conftest import skip_if_optional_else_raise +from trio._tests.pytest_plugin import skip_if_optional_else_raise from trio.abc import ReceiveStream, SendStream from trio.testing import ( Matcher, diff --git a/src/trio/_tests/tools/test_gen_exports.py b/src/trio/_tests/tools/test_gen_exports.py index 7b122daf4..669df968e 100644 --- a/src/trio/_tests/tools/test_gen_exports.py +++ b/src/trio/_tests/tools/test_gen_exports.py @@ -4,7 +4,7 @@ import pytest -from trio._tests.conftest import skip_if_optional_else_raise +from trio._tests.pytest_plugin import skip_if_optional_else_raise # imports in gen_exports that are not in `install_requires` in setup.py try: From f0294da20ac6d7f6fcf06dccc7bcab451e42f20f Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 17:03:40 +0900 Subject: [PATCH 27/30] Debug and remove `-Wall` for later PR --- ci.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ci.sh b/ci.sh index 193a4c262..7e41c2fe7 100755 --- a/ci.sh +++ b/ci.sh @@ -130,13 +130,15 @@ else # support subprocess spawning with coverage.py echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py" - sed -i 's/-p trio\._tests\.pytest_plugin//' "$(pwd)/../pyproject.toml" + sed -i '' 's/-p trio\._tests\.pytest_plugin//' "../pyproject.toml" + cat ../pyproject.toml + echo "::endgroup::" echo "::group:: Run Tests" if PYTHONPATH=../tests COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml \ coverage run --rcfile=../pyproject.toml -m \ pytest -ra --junitxml=../test-results.xml --run-slow --verbose --durations=10 $flags \ - -Wall -p _trio_check_attrs_aliases "${INSTALLDIR}"; then + -p _trio_check_attrs_aliases "${INSTALLDIR}"; then PASSED=true else PASSED=false From cb5913dcb6c41f4aa9a723e9b4272dfa5fa6cdf7 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 17:17:49 +0900 Subject: [PATCH 28/30] Hopefully fix some things --- ci.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ci.sh b/ci.sh index 7e41c2fe7..77d01dfb1 100755 --- a/ci.sh +++ b/ci.sh @@ -116,13 +116,13 @@ else echo "::group::Setup for tests" # We run the tests from inside an empty directory, to make sure Python - # doesn't pick up any .py files from our working dir. Might have been - # pre-created by some of the code above. + # doesn't pick up any .py files from our working dir. Might have already + # been created by a previous run. mkdir empty || true cd empty INSTALLDIR=$(python -c "import os, trio; print(os.path.dirname(trio.__file__))") - cp ../pyproject.toml "$INSTALLDIR" + cp ../pyproject.toml "$INSTALLDIR" # TODO: remove this # get mypy tests a nice cache MYPYPATH=".." mypy --config-file= --cache-dir=./.mypy_cache -c "import trio" >/dev/null 2>/dev/null || true @@ -130,15 +130,15 @@ else # support subprocess spawning with coverage.py echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py" - sed -i '' 's/-p trio\._tests\.pytest_plugin//' "../pyproject.toml" - cat ../pyproject.toml + sed -i'' 's/-p trio\._tests\.pytest_plugin//' "$INSTALLDIR/pyproject.toml" echo "::endgroup::" echo "::group:: Run Tests" if PYTHONPATH=../tests COVERAGE_PROCESS_START=$(pwd)/../pyproject.toml \ coverage run --rcfile=../pyproject.toml -m \ - pytest -ra --junitxml=../test-results.xml --run-slow --verbose --durations=10 $flags \ - -p _trio_check_attrs_aliases "${INSTALLDIR}"; then + pytest -ra --junitxml=../test-results.xml \ + -p _trio_check_attrs_aliases --verbose --durations=10 \ + -p trio._tests.pytest_plugin --run-slow $flags "${INSTALLDIR}"; then PASSED=true else PASSED=false From 942b371e8bc4f290a833a7c20d12d487ce240459 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 17:23:31 +0900 Subject: [PATCH 29/30] Give into perl --- ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index 77d01dfb1..83ec65748 100755 --- a/ci.sh +++ b/ci.sh @@ -130,7 +130,7 @@ else # support subprocess spawning with coverage.py echo "import coverage; coverage.process_startup()" | tee -a "$INSTALLDIR/../sitecustomize.py" - sed -i'' 's/-p trio\._tests\.pytest_plugin//' "$INSTALLDIR/pyproject.toml" + perl -i -pe 's/-p trio\._tests\.pytest_plugin//' "$INSTALLDIR/pyproject.toml" echo "::endgroup::" echo "::group:: Run Tests" From ce806e911e4a940eb92cf7d172b6325c0923fb49 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Sun, 24 Nov 2024 17:29:31 +0900 Subject: [PATCH 30/30] Add perl to alpine (should work now) --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 074943ec6..3cdc72e67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -184,7 +184,8 @@ jobs: # can't use setup-python because that python doesn't seem to work; # `python3-dev` (rather than `python:alpine`) for some ctypes reason, # `nodejs` for pyright (`node-env` pulls in nodejs but that takes a while and can time out the test). - run: apk update && apk add python3-dev bash nodejs + # `perl` for a platform independent `sed -i` alternative + run: apk update && apk add python3-dev bash nodejs perl - name: Enter virtual environment run: python -m venv .venv - name: Run tests