@ajksunkang-aios/kgraph-linux-x64 0.1.2 → 0.1.3
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.
- package/bin/kgraph-launcher +15 -3
- package/lib/kgraph/scripts/build-bundle.sh +17 -4
- package/lib/site-packages/outcome/__init__.py +20 -0
- package/lib/site-packages/outcome/_impl.py +239 -0
- package/lib/site-packages/outcome/_util.py +33 -0
- package/lib/site-packages/outcome/_version.py +7 -0
- package/lib/site-packages/outcome/py.typed +0 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/INSTALLER +1 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE +3 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE.APACHE2 +202 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE.MIT +20 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/METADATA +63 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/RECORD +13 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/WHEEL +6 -0
- package/lib/site-packages/outcome-1.3.0.post0.dist-info/top_level.txt +1 -0
- package/lib/site-packages/sniffio/__init__.py +17 -0
- package/lib/site-packages/sniffio/_impl.py +95 -0
- package/lib/site-packages/sniffio/_tests/__init__.py +0 -0
- package/lib/site-packages/sniffio/_tests/test_sniffio.py +84 -0
- package/lib/site-packages/sniffio/_version.py +3 -0
- package/lib/site-packages/sniffio/py.typed +0 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/INSTALLER +1 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE +3 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE.APACHE2 +202 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE.MIT +20 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/METADATA +104 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/RECORD +14 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/WHEEL +5 -0
- package/lib/site-packages/sniffio-1.3.1.dist-info/top_level.txt +1 -0
- package/lib/site-packages/sortedcontainers/__init__.py +74 -0
- package/lib/site-packages/sortedcontainers/sorteddict.py +812 -0
- package/lib/site-packages/sortedcontainers/sortedlist.py +2646 -0
- package/lib/site-packages/sortedcontainers/sortedset.py +733 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/INSTALLER +1 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/LICENSE +13 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/METADATA +264 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/RECORD +10 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/WHEEL +6 -0
- package/lib/site-packages/sortedcontainers-2.4.0.dist-info/top_level.txt +1 -0
- package/lib/site-packages/trio/__init__.py +133 -0
- package/lib/site-packages/trio/__main__.py +3 -0
- package/lib/site-packages/trio/_abc.py +714 -0
- package/lib/site-packages/trio/_channel.py +610 -0
- package/lib/site-packages/trio/_core/__init__.py +94 -0
- package/lib/site-packages/trio/_core/_asyncgens.py +243 -0
- package/lib/site-packages/trio/_core/_concat_tb.py +26 -0
- package/lib/site-packages/trio/_core/_entry_queue.py +223 -0
- package/lib/site-packages/trio/_core/_exceptions.py +169 -0
- package/lib/site-packages/trio/_core/_generated_instrumentation.py +50 -0
- package/lib/site-packages/trio/_core/_generated_io_epoll.py +98 -0
- package/lib/site-packages/trio/_core/_generated_io_kqueue.py +153 -0
- package/lib/site-packages/trio/_core/_generated_io_windows.py +204 -0
- package/lib/site-packages/trio/_core/_generated_run.py +269 -0
- package/lib/site-packages/trio/_core/_generated_windows_ffi.py +10 -0
- package/lib/site-packages/trio/_core/_instrumentation.py +117 -0
- package/lib/site-packages/trio/_core/_io_common.py +31 -0
- package/lib/site-packages/trio/_core/_io_epoll.py +385 -0
- package/lib/site-packages/trio/_core/_io_kqueue.py +292 -0
- package/lib/site-packages/trio/_core/_io_windows.py +1036 -0
- package/lib/site-packages/trio/_core/_ki.py +271 -0
- package/lib/site-packages/trio/_core/_local.py +104 -0
- package/lib/site-packages/trio/_core/_mock_clock.py +165 -0
- package/lib/site-packages/trio/_core/_parking_lot.py +317 -0
- package/lib/site-packages/trio/_core/_run.py +3148 -0
- package/lib/site-packages/trio/_core/_run_context.py +15 -0
- package/lib/site-packages/trio/_core/_tests/__init__.py +0 -0
- package/lib/site-packages/trio/_core/_tests/test_asyncgen.py +339 -0
- package/lib/site-packages/trio/_core/_tests/test_cancelled.py +222 -0
- package/lib/site-packages/trio/_core/_tests/test_exceptiongroup_gc.py +103 -0
- package/lib/site-packages/trio/_core/_tests/test_guest_mode.py +755 -0
- package/lib/site-packages/trio/_core/_tests/test_instrumentation.py +315 -0
- package/lib/site-packages/trio/_core/_tests/test_io.py +522 -0
- package/lib/site-packages/trio/_core/_tests/test_ki.py +703 -0
- package/lib/site-packages/trio/_core/_tests/test_local.py +118 -0
- package/lib/site-packages/trio/_core/_tests/test_mock_clock.py +193 -0
- package/lib/site-packages/trio/_core/_tests/test_parking_lot.py +389 -0
- package/lib/site-packages/trio/_core/_tests/test_run.py +3024 -0
- package/lib/site-packages/trio/_core/_tests/test_thread_cache.py +227 -0
- package/lib/site-packages/trio/_core/_tests/test_tutil.py +13 -0
- package/lib/site-packages/trio/_core/_tests/test_unbounded_queue.py +154 -0
- package/lib/site-packages/trio/_core/_tests/test_windows.py +305 -0
- package/lib/site-packages/trio/_core/_tests/tutil.py +117 -0
- package/lib/site-packages/trio/_core/_tests/type_tests/nursery_start.py +79 -0
- package/lib/site-packages/trio/_core/_tests/type_tests/run.py +51 -0
- package/lib/site-packages/trio/_core/_thread_cache.py +317 -0
- package/lib/site-packages/trio/_core/_traps.py +318 -0
- package/lib/site-packages/trio/_core/_unbounded_queue.py +163 -0
- package/lib/site-packages/trio/_core/_wakeup_socketpair.py +75 -0
- package/lib/site-packages/trio/_core/_windows_cffi.py +313 -0
- package/lib/site-packages/trio/_deprecate.py +171 -0
- package/lib/site-packages/trio/_dtls.py +1380 -0
- package/lib/site-packages/trio/_file_io.py +513 -0
- package/lib/site-packages/trio/_highlevel_generic.py +125 -0
- package/lib/site-packages/trio/_highlevel_open_tcp_listeners.py +251 -0
- package/lib/site-packages/trio/_highlevel_open_tcp_stream.py +397 -0
- package/lib/site-packages/trio/_highlevel_open_unix_stream.py +65 -0
- package/lib/site-packages/trio/_highlevel_serve_listeners.py +148 -0
- package/lib/site-packages/trio/_highlevel_socket.py +423 -0
- package/lib/site-packages/trio/_highlevel_ssl_helpers.py +180 -0
- package/lib/site-packages/trio/_path.py +289 -0
- package/lib/site-packages/trio/_repl.py +159 -0
- package/lib/site-packages/trio/_signals.py +185 -0
- package/lib/site-packages/trio/_socket.py +1326 -0
- package/lib/site-packages/trio/_ssl.py +964 -0
- package/lib/site-packages/trio/_subprocess.py +1178 -0
- package/lib/site-packages/trio/_subprocess_platform/__init__.py +123 -0
- package/lib/site-packages/trio/_subprocess_platform/kqueue.py +48 -0
- package/lib/site-packages/trio/_subprocess_platform/waitid.py +113 -0
- package/lib/site-packages/trio/_subprocess_platform/windows.py +11 -0
- package/lib/site-packages/trio/_sync.py +908 -0
- package/lib/site-packages/trio/_tests/__init__.py +0 -0
- package/lib/site-packages/trio/_tests/astrill-codesigning-cert.cer +0 -0
- package/lib/site-packages/trio/_tests/check_type_completeness.py +247 -0
- package/lib/site-packages/trio/_tests/module_with_deprecations.py +22 -0
- package/lib/site-packages/trio/_tests/pytest_plugin.py +54 -0
- package/lib/site-packages/trio/_tests/test_abc.py +72 -0
- package/lib/site-packages/trio/_tests/test_channel.py +750 -0
- package/lib/site-packages/trio/_tests/test_contextvars.py +56 -0
- package/lib/site-packages/trio/_tests/test_deprecate.py +277 -0
- package/lib/site-packages/trio/_tests/test_deprecate_strict_exception_groups_false.py +64 -0
- package/lib/site-packages/trio/_tests/test_dtls.py +950 -0
- package/lib/site-packages/trio/_tests/test_exports.py +626 -0
- package/lib/site-packages/trio/_tests/test_fakenet.py +317 -0
- package/lib/site-packages/trio/_tests/test_file_io.py +269 -0
- package/lib/site-packages/trio/_tests/test_highlevel_generic.py +98 -0
- package/lib/site-packages/trio/_tests/test_highlevel_open_tcp_listeners.py +419 -0
- package/lib/site-packages/trio/_tests/test_highlevel_open_tcp_stream.py +693 -0
- package/lib/site-packages/trio/_tests/test_highlevel_open_unix_stream.py +86 -0
- package/lib/site-packages/trio/_tests/test_highlevel_serve_listeners.py +186 -0
- package/lib/site-packages/trio/_tests/test_highlevel_socket.py +336 -0
- package/lib/site-packages/trio/_tests/test_highlevel_ssl_helpers.py +169 -0
- package/lib/site-packages/trio/_tests/test_path.py +279 -0
- package/lib/site-packages/trio/_tests/test_repl.py +428 -0
- package/lib/site-packages/trio/_tests/test_scheduler_determinism.py +47 -0
- package/lib/site-packages/trio/_tests/test_signals.py +186 -0
- package/lib/site-packages/trio/_tests/test_socket.py +1253 -0
- package/lib/site-packages/trio/_tests/test_ssl.py +1371 -0
- package/lib/site-packages/trio/_tests/test_subprocess.py +767 -0
- package/lib/site-packages/trio/_tests/test_sync.py +735 -0
- package/lib/site-packages/trio/_tests/test_testing.py +682 -0
- package/lib/site-packages/trio/_tests/test_testing_raisesgroup.py +1128 -0
- package/lib/site-packages/trio/_tests/test_threads.py +1173 -0
- package/lib/site-packages/trio/_tests/test_timeouts.py +281 -0
- package/lib/site-packages/trio/_tests/test_tracing.py +88 -0
- package/lib/site-packages/trio/_tests/test_trio.py +8 -0
- package/lib/site-packages/trio/_tests/test_unix_pipes.py +288 -0
- package/lib/site-packages/trio/_tests/test_util.py +349 -0
- package/lib/site-packages/trio/_tests/test_wait_for_object.py +225 -0
- package/lib/site-packages/trio/_tests/test_windows_pipes.py +112 -0
- package/lib/site-packages/trio/_tests/tools/__init__.py +0 -0
- package/lib/site-packages/trio/_tests/tools/test_gen_exports.py +179 -0
- package/lib/site-packages/trio/_tests/tools/test_mypy_annotate.py +140 -0
- package/lib/site-packages/trio/_tests/tools/test_sync_requirements.py +80 -0
- package/lib/site-packages/trio/_tests/type_tests/check_wraps.py +9 -0
- package/lib/site-packages/trio/_tests/type_tests/open_memory_channel.py +4 -0
- package/lib/site-packages/trio/_tests/type_tests/path.py +140 -0
- package/lib/site-packages/trio/_tests/type_tests/subprocesses.py +23 -0
- package/lib/site-packages/trio/_tests/type_tests/task_status.py +29 -0
- package/lib/site-packages/trio/_threads.py +610 -0
- package/lib/site-packages/trio/_timeouts.py +197 -0
- package/lib/site-packages/trio/_tools/__init__.py +0 -0
- package/lib/site-packages/trio/_tools/gen_exports.py +401 -0
- package/lib/site-packages/trio/_tools/mypy_annotate.py +126 -0
- package/lib/site-packages/trio/_tools/sync_requirements.py +98 -0
- package/lib/site-packages/trio/_tools/windows_ffi_build.py +220 -0
- package/lib/site-packages/trio/_unix_pipes.py +197 -0
- package/lib/site-packages/trio/_util.py +385 -0
- package/lib/site-packages/trio/_version.py +3 -0
- package/lib/site-packages/trio/_wait_for_object.py +67 -0
- package/lib/site-packages/trio/_windows_pipes.py +144 -0
- package/lib/site-packages/trio/abc.py +23 -0
- package/lib/site-packages/trio/from_thread.py +13 -0
- package/lib/site-packages/trio/lowlevel.py +95 -0
- package/lib/site-packages/trio/py.typed +0 -0
- package/lib/site-packages/trio/socket.py +602 -0
- package/lib/site-packages/trio/testing/__init__.py +58 -0
- package/lib/site-packages/trio/testing/_check_streams.py +570 -0
- package/lib/site-packages/trio/testing/_checkpoints.py +69 -0
- package/lib/site-packages/trio/testing/_fake_net.py +584 -0
- package/lib/site-packages/trio/testing/_memory_streams.py +633 -0
- package/lib/site-packages/trio/testing/_network.py +36 -0
- package/lib/site-packages/trio/testing/_raises_group.py +1015 -0
- package/lib/site-packages/trio/testing/_sequencer.py +87 -0
- package/lib/site-packages/trio/testing/_trio_test.py +50 -0
- package/lib/site-packages/trio/to_thread.py +4 -0
- package/lib/site-packages/trio-0.33.0.dist-info/INSTALLER +1 -0
- package/lib/site-packages/trio-0.33.0.dist-info/METADATA +186 -0
- package/lib/site-packages/trio-0.33.0.dist-info/RECORD +156 -0
- package/lib/site-packages/trio-0.33.0.dist-info/REQUESTED +0 -0
- package/lib/site-packages/trio-0.33.0.dist-info/WHEEL +5 -0
- package/lib/site-packages/trio-0.33.0.dist-info/entry_points.txt +2 -0
- package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE +3 -0
- package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE.APACHE2 +202 -0
- package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE.MIT +22 -0
- package/lib/site-packages/trio-0.33.0.dist-info/top_level.txt +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from trio._tests.pytest_plugin import skip_if_optional_else_raise
|
|
8
|
+
|
|
9
|
+
# imports in gen_exports that are not in `install_requires` in setup.py
|
|
10
|
+
try:
|
|
11
|
+
import astor # noqa: F401
|
|
12
|
+
import isort # noqa: F401
|
|
13
|
+
except ImportError as error:
|
|
14
|
+
skip_if_optional_else_raise(error)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
from trio._tools.gen_exports import (
|
|
18
|
+
File,
|
|
19
|
+
create_passthrough_args,
|
|
20
|
+
get_public_methods,
|
|
21
|
+
process,
|
|
22
|
+
run_linters,
|
|
23
|
+
run_ruff,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
from ..._core._tests.tutil import slow
|
|
27
|
+
|
|
28
|
+
SOURCE = '''from _run import _public
|
|
29
|
+
from collections import Counter
|
|
30
|
+
|
|
31
|
+
class Test:
|
|
32
|
+
@_public
|
|
33
|
+
def public_func(self):
|
|
34
|
+
"""With doc string"""
|
|
35
|
+
|
|
36
|
+
@ignore_this
|
|
37
|
+
@_public
|
|
38
|
+
@another_decorator
|
|
39
|
+
async def public_async_func(self) -> Counter:
|
|
40
|
+
pass # no doc string
|
|
41
|
+
|
|
42
|
+
def not_public(self):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
async def not_public_async(self):
|
|
46
|
+
pass
|
|
47
|
+
'''
|
|
48
|
+
|
|
49
|
+
IMPORT_1 = """\
|
|
50
|
+
from collections import Counter
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
IMPORT_2 = """\
|
|
54
|
+
from collections import Counter
|
|
55
|
+
import os
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
IMPORT_3 = """\
|
|
59
|
+
from typing import TYPE_CHECKING
|
|
60
|
+
if TYPE_CHECKING:
|
|
61
|
+
from collections import Counter
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_get_public_methods() -> None:
|
|
66
|
+
methods = list(get_public_methods(ast.parse(SOURCE)))
|
|
67
|
+
assert {m.name for m in methods} == {"public_func", "public_async_func"}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_create_pass_through_args() -> None:
|
|
71
|
+
testcases = [
|
|
72
|
+
("def f()", "()"),
|
|
73
|
+
("def f(one)", "(one)"),
|
|
74
|
+
("def f(one, two)", "(one, two)"),
|
|
75
|
+
("def f(one, *args)", "(one, *args)"),
|
|
76
|
+
(
|
|
77
|
+
"def f(one, *args, kw1, kw2=None, **kwargs)",
|
|
78
|
+
"(one, *args, kw1=kw1, kw2=kw2, **kwargs)",
|
|
79
|
+
),
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
for funcdef, expected in testcases:
|
|
83
|
+
func_node = ast.parse(funcdef + ":\n pass").body[0]
|
|
84
|
+
assert isinstance(func_node, ast.FunctionDef)
|
|
85
|
+
assert create_passthrough_args(func_node) == expected
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
skip_lints = pytest.mark.skipif(
|
|
89
|
+
sys.implementation.name != "cpython",
|
|
90
|
+
reason="gen_exports is internal, black/isort only runs on CPython",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@slow
|
|
95
|
+
@skip_lints
|
|
96
|
+
@pytest.mark.parametrize("imports", [IMPORT_1, IMPORT_2, IMPORT_3])
|
|
97
|
+
def test_process(
|
|
98
|
+
tmp_path: Path,
|
|
99
|
+
imports: str,
|
|
100
|
+
capsys: pytest.CaptureFixture[str],
|
|
101
|
+
) -> None:
|
|
102
|
+
try:
|
|
103
|
+
import black # noqa: F401
|
|
104
|
+
# there's no dedicated CI run that has astor+isort, but lacks black.
|
|
105
|
+
except ImportError as error: # pragma: no cover
|
|
106
|
+
skip_if_optional_else_raise(error)
|
|
107
|
+
|
|
108
|
+
modpath = tmp_path / "_module.py"
|
|
109
|
+
genpath = tmp_path / "_generated_module.py"
|
|
110
|
+
modpath.write_text(SOURCE, encoding="utf-8")
|
|
111
|
+
file = File(modpath, "runner", platform="linux", imports=imports)
|
|
112
|
+
assert not genpath.exists()
|
|
113
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
114
|
+
process([file], do_test=True)
|
|
115
|
+
assert excinfo.value.code == 1
|
|
116
|
+
captured = capsys.readouterr()
|
|
117
|
+
assert "Generated sources are outdated. Please regenerate." in captured.out
|
|
118
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
119
|
+
process([file], do_test=False)
|
|
120
|
+
assert excinfo.value.code == 1
|
|
121
|
+
captured = capsys.readouterr()
|
|
122
|
+
assert "Regenerated sources successfully." in captured.out
|
|
123
|
+
assert genpath.exists()
|
|
124
|
+
process([file], do_test=True)
|
|
125
|
+
# But if we change the lookup path it notices
|
|
126
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
127
|
+
process(
|
|
128
|
+
[File(modpath, "runner.io_manager", platform="linux", imports=imports)],
|
|
129
|
+
do_test=True,
|
|
130
|
+
)
|
|
131
|
+
assert excinfo.value.code == 1
|
|
132
|
+
# Also if the platform is changed.
|
|
133
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
134
|
+
process([File(modpath, "runner", imports=imports)], do_test=True)
|
|
135
|
+
assert excinfo.value.code == 1
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@skip_lints
|
|
139
|
+
def test_run_ruff(tmp_path: Path) -> None:
|
|
140
|
+
"""Test that processing properly fails if ruff does."""
|
|
141
|
+
try:
|
|
142
|
+
import ruff # noqa: F401
|
|
143
|
+
except ImportError as error: # pragma: no cover
|
|
144
|
+
skip_if_optional_else_raise(error)
|
|
145
|
+
|
|
146
|
+
file = File(tmp_path / "module.py", "module")
|
|
147
|
+
|
|
148
|
+
success, _ = run_ruff(file, "class not valid code ><")
|
|
149
|
+
assert not success
|
|
150
|
+
|
|
151
|
+
test_function = '''def combine_and(data: list[str]) -> str:
|
|
152
|
+
"""Join values of text, and have 'and' with the last one properly."""
|
|
153
|
+
if len(data) >= 2:
|
|
154
|
+
data[-1] = 'and ' + data[-1]
|
|
155
|
+
if len(data) > 2:
|
|
156
|
+
return ', '.join(data)
|
|
157
|
+
return ' '.join(data)'''
|
|
158
|
+
|
|
159
|
+
success, response = run_ruff(file, test_function)
|
|
160
|
+
assert success
|
|
161
|
+
assert response == test_function
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@skip_lints
|
|
165
|
+
def test_lint_failure(tmp_path: Path) -> None:
|
|
166
|
+
"""Test that processing properly fails if black or ruff does."""
|
|
167
|
+
try:
|
|
168
|
+
import black # noqa: F401
|
|
169
|
+
import ruff # noqa: F401
|
|
170
|
+
except ImportError as error: # pragma: no cover
|
|
171
|
+
skip_if_optional_else_raise(error)
|
|
172
|
+
|
|
173
|
+
file = File(tmp_path / "module.py", "module")
|
|
174
|
+
|
|
175
|
+
with pytest.raises(SystemExit):
|
|
176
|
+
run_linters(file, "class not valid code ><")
|
|
177
|
+
|
|
178
|
+
with pytest.raises(SystemExit):
|
|
179
|
+
run_linters(file, "import waffle\n;import trio")
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import io
|
|
4
|
+
import sys
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from trio._tools.mypy_annotate import Result, export, main, process_line
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.mark.parametrize(
|
|
16
|
+
("src", "expected"),
|
|
17
|
+
[
|
|
18
|
+
("", None),
|
|
19
|
+
("a regular line\n", None),
|
|
20
|
+
(
|
|
21
|
+
"package\\filename.py:42:8: note: Some info\n",
|
|
22
|
+
Result(
|
|
23
|
+
kind="notice",
|
|
24
|
+
filename="package\\filename.py",
|
|
25
|
+
start_line=42,
|
|
26
|
+
start_col=8,
|
|
27
|
+
end_line=None,
|
|
28
|
+
end_col=None,
|
|
29
|
+
message=" Some info",
|
|
30
|
+
),
|
|
31
|
+
),
|
|
32
|
+
(
|
|
33
|
+
"package/filename.py:42:1:46:3: error: Type error here [code]\n",
|
|
34
|
+
Result(
|
|
35
|
+
kind="error",
|
|
36
|
+
filename="package/filename.py",
|
|
37
|
+
start_line=42,
|
|
38
|
+
start_col=1,
|
|
39
|
+
end_line=46,
|
|
40
|
+
end_col=3,
|
|
41
|
+
message=" Type error here [code]",
|
|
42
|
+
),
|
|
43
|
+
),
|
|
44
|
+
(
|
|
45
|
+
"package/module.py:87: warn: Bad code\n",
|
|
46
|
+
Result(
|
|
47
|
+
kind="warning",
|
|
48
|
+
filename="package/module.py",
|
|
49
|
+
start_line=87,
|
|
50
|
+
message=" Bad code",
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
],
|
|
54
|
+
ids=["blank", "normal", "note-wcol", "error-wend", "warn-lineonly"],
|
|
55
|
+
)
|
|
56
|
+
def test_processing(src: str, expected: Result | None) -> None:
|
|
57
|
+
result = process_line(src)
|
|
58
|
+
assert result == expected
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_export(capsys: pytest.CaptureFixture[str]) -> None:
|
|
62
|
+
results = {
|
|
63
|
+
Result(
|
|
64
|
+
kind="notice",
|
|
65
|
+
filename="package\\filename.py",
|
|
66
|
+
start_line=42,
|
|
67
|
+
start_col=8,
|
|
68
|
+
end_line=None,
|
|
69
|
+
end_col=None,
|
|
70
|
+
message=" Some info",
|
|
71
|
+
): ["Windows", "Mac"],
|
|
72
|
+
Result(
|
|
73
|
+
kind="error",
|
|
74
|
+
filename="package/filename.py",
|
|
75
|
+
start_line=42,
|
|
76
|
+
start_col=1,
|
|
77
|
+
end_line=46,
|
|
78
|
+
end_col=3,
|
|
79
|
+
message=" Type error here [code]",
|
|
80
|
+
): ["Linux", "Mac"],
|
|
81
|
+
Result(
|
|
82
|
+
kind="warning",
|
|
83
|
+
filename="package/module.py",
|
|
84
|
+
start_line=87,
|
|
85
|
+
message=" Bad code",
|
|
86
|
+
): ["Linux"],
|
|
87
|
+
}
|
|
88
|
+
export(results)
|
|
89
|
+
std = capsys.readouterr()
|
|
90
|
+
assert std.err == ""
|
|
91
|
+
assert std.out == (
|
|
92
|
+
"::notice file=package\\filename.py,line=42,col=8,"
|
|
93
|
+
"title=Mypy-Windows+Mac::package\\filename.py:(42:8): Some info"
|
|
94
|
+
"\n"
|
|
95
|
+
"::error file=package/filename.py,line=42,col=1,endLine=46,endColumn=3,"
|
|
96
|
+
"title=Mypy-Linux+Mac::package/filename.py:(42:1 - 46:3): Type error here [code]"
|
|
97
|
+
"\n"
|
|
98
|
+
"::warning file=package/module.py,line=87,"
|
|
99
|
+
"title=Mypy-Linux::package/module.py:87: Bad code\n"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_endtoend(
|
|
104
|
+
tmp_path: Path,
|
|
105
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
106
|
+
capsys: pytest.CaptureFixture[str],
|
|
107
|
+
) -> None:
|
|
108
|
+
import trio._tools.mypy_annotate as mypy_annotate
|
|
109
|
+
|
|
110
|
+
inp_text = """\
|
|
111
|
+
Mypy begun
|
|
112
|
+
trio/core.py:15: error: Bad types here [misc]
|
|
113
|
+
trio/package/module.py:48:4:56:18: warn: Missing annotations [no-untyped-def]
|
|
114
|
+
Found 3 errors in 29 files
|
|
115
|
+
"""
|
|
116
|
+
result_file = tmp_path / "dump.dat"
|
|
117
|
+
assert not result_file.exists()
|
|
118
|
+
with monkeypatch.context():
|
|
119
|
+
monkeypatch.setattr(sys, "stdin", io.StringIO(inp_text))
|
|
120
|
+
|
|
121
|
+
mypy_annotate.main(
|
|
122
|
+
["--dumpfile", str(result_file), "--platform", "SomePlatform"],
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
std = capsys.readouterr()
|
|
126
|
+
assert std.err == ""
|
|
127
|
+
assert std.out == inp_text # Echos the original.
|
|
128
|
+
|
|
129
|
+
assert result_file.exists()
|
|
130
|
+
|
|
131
|
+
main(["--dumpfile", str(result_file)])
|
|
132
|
+
|
|
133
|
+
std = capsys.readouterr()
|
|
134
|
+
assert std.err == ""
|
|
135
|
+
assert std.out == (
|
|
136
|
+
"::error file=trio/core.py,line=15,title=Mypy-SomePlatform::trio/core.py:15: Bad types here [misc]\n"
|
|
137
|
+
"::warning file=trio/package/module.py,line=48,col=4,endLine=56,endColumn=18,"
|
|
138
|
+
"title=Mypy-SomePlatform::trio/package/module.py:(48:4 - 56:18): Missing "
|
|
139
|
+
"annotations [no-untyped-def]\n"
|
|
140
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from trio._tests.pytest_plugin import skip_if_optional_else_raise
|
|
7
|
+
|
|
8
|
+
# imports in gen_exports that are not in `install_requires` in requirements
|
|
9
|
+
try:
|
|
10
|
+
import yaml # noqa: F401
|
|
11
|
+
except ImportError as error:
|
|
12
|
+
skip_if_optional_else_raise(error)
|
|
13
|
+
|
|
14
|
+
from trio._tools.sync_requirements import (
|
|
15
|
+
update_requirements,
|
|
16
|
+
yield_pre_commit_version_data,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_yield_pre_commit_version_data() -> None:
|
|
24
|
+
text = """
|
|
25
|
+
repos:
|
|
26
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
27
|
+
rev: v0.11.0
|
|
28
|
+
- repo: https://github.com/psf/black-pre-commit-mirror
|
|
29
|
+
rev: 25.1.0
|
|
30
|
+
- bad: data
|
|
31
|
+
"""
|
|
32
|
+
results = tuple(yield_pre_commit_version_data(text))
|
|
33
|
+
assert results == (
|
|
34
|
+
("ruff-pre-commit", "0.11.0"),
|
|
35
|
+
("black-pre-commit-mirror", "25.1.0"),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_update_requirements(
|
|
40
|
+
tmp_path: Path,
|
|
41
|
+
) -> None:
|
|
42
|
+
requirements_file = tmp_path / "requirements.txt"
|
|
43
|
+
assert not requirements_file.exists()
|
|
44
|
+
requirements_file.write_text(
|
|
45
|
+
"""# comment
|
|
46
|
+
# also comment but spaces line start
|
|
47
|
+
waffles are delicious no equals
|
|
48
|
+
black==3.1.4 ; specific version thingy
|
|
49
|
+
mypy==1.15.0
|
|
50
|
+
ruff==1.2.5
|
|
51
|
+
# required by soupy cat""",
|
|
52
|
+
encoding="utf-8",
|
|
53
|
+
)
|
|
54
|
+
assert update_requirements(requirements_file, {"black": "3.1.5", "ruff": "1.2.7"})
|
|
55
|
+
assert requirements_file.read_text(encoding="utf-8") == """# comment
|
|
56
|
+
# also comment but spaces line start
|
|
57
|
+
waffles are delicious no equals
|
|
58
|
+
black==3.1.5 ; specific version thingy
|
|
59
|
+
mypy==1.15.0
|
|
60
|
+
ruff==1.2.7
|
|
61
|
+
# required by soupy cat"""
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_update_requirements_no_changes(
|
|
65
|
+
tmp_path: Path,
|
|
66
|
+
) -> None:
|
|
67
|
+
requirements_file = tmp_path / "requirements.txt"
|
|
68
|
+
assert not requirements_file.exists()
|
|
69
|
+
original = """# comment
|
|
70
|
+
# also comment but spaces line start
|
|
71
|
+
waffles are delicious no equals
|
|
72
|
+
black==3.1.4 ; specific version thingy
|
|
73
|
+
mypy==1.15.0
|
|
74
|
+
ruff==1.2.5
|
|
75
|
+
# required by soupy cat"""
|
|
76
|
+
requirements_file.write_text(original, encoding="utf-8")
|
|
77
|
+
assert not update_requirements(
|
|
78
|
+
requirements_file, {"black": "3.1.4", "ruff": "1.2.5"}
|
|
79
|
+
)
|
|
80
|
+
assert requirements_file.read_text(encoding="utf-8") == original
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# https://github.com/python-trio/trio/issues/2775#issuecomment-1702267589
|
|
2
|
+
# (except platform independent...)
|
|
3
|
+
import trio
|
|
4
|
+
from typing_extensions import assert_type
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
async def fn(s: trio.SocketStream) -> None:
|
|
8
|
+
result = await s.socket.sendto(b"a", "h")
|
|
9
|
+
assert_type(result, int)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Path wrapping is quite complex, ensure all methods are understood as wrapped correctly."""
|
|
2
|
+
|
|
3
|
+
import io
|
|
4
|
+
import os
|
|
5
|
+
import pathlib
|
|
6
|
+
import sys
|
|
7
|
+
from typing import IO, Any, BinaryIO
|
|
8
|
+
|
|
9
|
+
import trio
|
|
10
|
+
from trio._file_io import AsyncIOWrapper
|
|
11
|
+
from typing_extensions import assert_type
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def operator_checks(text: str, tpath: trio.Path, ppath: pathlib.Path) -> None:
|
|
15
|
+
"""Verify operators produce the right results."""
|
|
16
|
+
assert_type(tpath / ppath, trio.Path)
|
|
17
|
+
assert_type(tpath / tpath, trio.Path)
|
|
18
|
+
assert_type(tpath / text, trio.Path)
|
|
19
|
+
assert_type(text / tpath, trio.Path)
|
|
20
|
+
|
|
21
|
+
assert_type(tpath > tpath, bool)
|
|
22
|
+
assert_type(tpath >= tpath, bool)
|
|
23
|
+
assert_type(tpath < tpath, bool)
|
|
24
|
+
assert_type(tpath <= tpath, bool)
|
|
25
|
+
|
|
26
|
+
assert_type(tpath > ppath, bool)
|
|
27
|
+
assert_type(tpath >= ppath, bool)
|
|
28
|
+
assert_type(tpath < ppath, bool)
|
|
29
|
+
assert_type(tpath <= ppath, bool)
|
|
30
|
+
|
|
31
|
+
assert_type(ppath > tpath, bool)
|
|
32
|
+
assert_type(ppath >= tpath, bool)
|
|
33
|
+
assert_type(ppath < tpath, bool)
|
|
34
|
+
assert_type(ppath <= tpath, bool)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def sync_attrs(path: trio.Path) -> None:
|
|
38
|
+
assert_type(path.parts, tuple[str, ...])
|
|
39
|
+
assert_type(path.drive, str)
|
|
40
|
+
assert_type(path.root, str)
|
|
41
|
+
assert_type(path.anchor, str)
|
|
42
|
+
assert_type(path.parents[3], trio.Path)
|
|
43
|
+
assert_type(path.parent, trio.Path)
|
|
44
|
+
assert_type(path.name, str)
|
|
45
|
+
assert_type(path.suffix, str)
|
|
46
|
+
assert_type(path.suffixes, list[str])
|
|
47
|
+
assert_type(path.stem, str)
|
|
48
|
+
assert_type(path.as_posix(), str)
|
|
49
|
+
assert_type(path.as_uri(), str)
|
|
50
|
+
assert_type(path.is_absolute(), bool)
|
|
51
|
+
assert_type(path.is_relative_to(path), bool)
|
|
52
|
+
assert_type(path.is_reserved(), bool)
|
|
53
|
+
assert_type(path.joinpath(path, "folder"), trio.Path)
|
|
54
|
+
assert_type(path.match("*.py"), bool)
|
|
55
|
+
assert_type(path.relative_to("/usr"), trio.Path)
|
|
56
|
+
if sys.version_info >= (3, 12):
|
|
57
|
+
assert_type(path.relative_to("/", walk_up=True), trio.Path)
|
|
58
|
+
assert_type(path.with_name("filename.txt"), trio.Path)
|
|
59
|
+
assert_type(path.with_stem("readme"), trio.Path)
|
|
60
|
+
assert_type(path.with_suffix(".log"), trio.Path)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
async def async_attrs(path: trio.Path) -> None:
|
|
64
|
+
assert_type(await trio.Path.cwd(), trio.Path)
|
|
65
|
+
assert_type(await trio.Path.home(), trio.Path)
|
|
66
|
+
assert_type(await path.stat(), os.stat_result)
|
|
67
|
+
assert_type(await path.chmod(0o777), None)
|
|
68
|
+
assert_type(await path.exists(), bool)
|
|
69
|
+
assert_type(await path.expanduser(), trio.Path)
|
|
70
|
+
for result in await path.glob("*.py"):
|
|
71
|
+
assert_type(result, trio.Path)
|
|
72
|
+
if sys.platform != "win32":
|
|
73
|
+
assert_type(await path.group(), str)
|
|
74
|
+
assert_type(await path.is_dir(), bool)
|
|
75
|
+
assert_type(await path.is_file(), bool)
|
|
76
|
+
if sys.version_info >= (3, 12):
|
|
77
|
+
assert_type(await path.is_junction(), bool)
|
|
78
|
+
if sys.platform != "win32":
|
|
79
|
+
assert_type(await path.is_mount(), bool)
|
|
80
|
+
assert_type(await path.is_symlink(), bool)
|
|
81
|
+
assert_type(await path.is_socket(), bool)
|
|
82
|
+
assert_type(await path.is_fifo(), bool)
|
|
83
|
+
assert_type(await path.is_block_device(), bool)
|
|
84
|
+
assert_type(await path.is_char_device(), bool)
|
|
85
|
+
for child_iter in await path.iterdir():
|
|
86
|
+
assert_type(child_iter, trio.Path)
|
|
87
|
+
# TODO: Path.walk() in 3.12
|
|
88
|
+
assert_type(await path.lchmod(0o111), None)
|
|
89
|
+
assert_type(await path.lstat(), os.stat_result)
|
|
90
|
+
assert_type(await path.mkdir(mode=0o777, parents=True, exist_ok=False), None)
|
|
91
|
+
# Open done separately.
|
|
92
|
+
if sys.platform != "win32":
|
|
93
|
+
assert_type(await path.owner(), str)
|
|
94
|
+
assert_type(await path.read_bytes(), bytes)
|
|
95
|
+
assert_type(await path.read_text(encoding="utf16", errors="replace"), str)
|
|
96
|
+
assert_type(await path.readlink(), trio.Path)
|
|
97
|
+
assert_type(await path.rename("another"), trio.Path)
|
|
98
|
+
assert_type(await path.replace(path), trio.Path)
|
|
99
|
+
assert_type(await path.resolve(), trio.Path)
|
|
100
|
+
for child_glob in await path.glob("*.py"):
|
|
101
|
+
assert_type(child_glob, trio.Path)
|
|
102
|
+
for child_rglob in await path.rglob("*.py"):
|
|
103
|
+
assert_type(child_rglob, trio.Path)
|
|
104
|
+
assert_type(await path.rmdir(), None)
|
|
105
|
+
assert_type(await path.samefile("something_else"), bool)
|
|
106
|
+
assert_type(await path.symlink_to("somewhere"), None)
|
|
107
|
+
assert_type(await path.hardlink_to("elsewhere"), None)
|
|
108
|
+
assert_type(await path.touch(), None)
|
|
109
|
+
assert_type(await path.unlink(missing_ok=True), None)
|
|
110
|
+
assert_type(await path.write_bytes(b"123"), int)
|
|
111
|
+
assert_type(
|
|
112
|
+
await path.write_text("hello", encoding="utf32le", errors="ignore"),
|
|
113
|
+
int,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
async def open_results(path: trio.Path, some_int: int, some_str: str) -> None:
|
|
118
|
+
# Check the overloads.
|
|
119
|
+
assert_type(await path.open(), AsyncIOWrapper[io.TextIOWrapper])
|
|
120
|
+
assert_type(await path.open("r"), AsyncIOWrapper[io.TextIOWrapper])
|
|
121
|
+
assert_type(await path.open("r+"), AsyncIOWrapper[io.TextIOWrapper])
|
|
122
|
+
assert_type(await path.open("w"), AsyncIOWrapper[io.TextIOWrapper])
|
|
123
|
+
assert_type(await path.open("rb", buffering=0), AsyncIOWrapper[io.FileIO])
|
|
124
|
+
assert_type(await path.open("rb+"), AsyncIOWrapper[io.BufferedRandom])
|
|
125
|
+
assert_type(await path.open("wb"), AsyncIOWrapper[io.BufferedWriter])
|
|
126
|
+
assert_type(await path.open("rb"), AsyncIOWrapper[io.BufferedReader])
|
|
127
|
+
assert_type(await path.open("rb", buffering=some_int), AsyncIOWrapper[BinaryIO])
|
|
128
|
+
assert_type(await path.open(some_str), AsyncIOWrapper[IO[Any]])
|
|
129
|
+
|
|
130
|
+
# Check they produce the right types.
|
|
131
|
+
file_bin = await path.open("rb+")
|
|
132
|
+
assert_type(await file_bin.read(), bytes)
|
|
133
|
+
assert_type(await file_bin.write(b"test"), int)
|
|
134
|
+
assert_type(await file_bin.seek(32), int)
|
|
135
|
+
|
|
136
|
+
file_text = await path.open("r+t")
|
|
137
|
+
assert_type(await file_text.read(), str)
|
|
138
|
+
assert_type(await file_text.write("test"), int)
|
|
139
|
+
# TODO: report mypy bug: equiv to https://github.com/microsoft/pyright/issues/6833
|
|
140
|
+
assert_type(await file_text.readlines(), list[str])
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
import trio
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async def test() -> None:
|
|
7
|
+
# this could test more by using platform checks, but currently this
|
|
8
|
+
# is just regression tests + sanity checks.
|
|
9
|
+
await trio.run_process("python", executable="ls")
|
|
10
|
+
await trio.lowlevel.open_process("python", executable="ls")
|
|
11
|
+
|
|
12
|
+
# note: there's no error code on the type ignore as it varies
|
|
13
|
+
# between platforms.
|
|
14
|
+
await trio.run_process("python", capture_stdout=True)
|
|
15
|
+
await trio.lowlevel.open_process("python", capture_stdout=True) # type: ignore
|
|
16
|
+
|
|
17
|
+
if sys.platform != "win32" and sys.version_info >= (3, 9):
|
|
18
|
+
await trio.run_process("python", extra_groups=[5])
|
|
19
|
+
await trio.lowlevel.open_process("python", extra_groups=[5])
|
|
20
|
+
|
|
21
|
+
# 3.11+:
|
|
22
|
+
await trio.run_process("python", process_group=5) # type: ignore
|
|
23
|
+
await trio.lowlevel.open_process("python", process_group=5) # type: ignore
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Check that started() can only be called for TaskStatus[None]."""
|
|
2
|
+
|
|
3
|
+
from trio import TaskStatus
|
|
4
|
+
from typing_extensions import assert_type
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def check_status(
|
|
8
|
+
none_status_explicit: TaskStatus[None],
|
|
9
|
+
none_status_implicit: TaskStatus,
|
|
10
|
+
int_status: TaskStatus[int],
|
|
11
|
+
) -> None:
|
|
12
|
+
assert_type(none_status_explicit, TaskStatus[None])
|
|
13
|
+
assert_type(none_status_implicit, TaskStatus[None]) # Default typevar
|
|
14
|
+
assert_type(int_status, TaskStatus[int])
|
|
15
|
+
|
|
16
|
+
# Omitting the parameter is only allowed for None.
|
|
17
|
+
none_status_explicit.started()
|
|
18
|
+
none_status_implicit.started()
|
|
19
|
+
int_status.started() # type: ignore
|
|
20
|
+
|
|
21
|
+
# Explicit None is allowed.
|
|
22
|
+
none_status_explicit.started(None)
|
|
23
|
+
none_status_implicit.started(None)
|
|
24
|
+
int_status.started(None) # type: ignore
|
|
25
|
+
|
|
26
|
+
none_status_explicit.started(42) # type: ignore
|
|
27
|
+
none_status_implicit.started(42) # type: ignore
|
|
28
|
+
int_status.started(42)
|
|
29
|
+
int_status.started(True)
|