@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.
Files changed (196) hide show
  1. package/bin/kgraph-launcher +15 -3
  2. package/lib/kgraph/scripts/build-bundle.sh +17 -4
  3. package/lib/site-packages/outcome/__init__.py +20 -0
  4. package/lib/site-packages/outcome/_impl.py +239 -0
  5. package/lib/site-packages/outcome/_util.py +33 -0
  6. package/lib/site-packages/outcome/_version.py +7 -0
  7. package/lib/site-packages/outcome/py.typed +0 -0
  8. package/lib/site-packages/outcome-1.3.0.post0.dist-info/INSTALLER +1 -0
  9. package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE +3 -0
  10. package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE.APACHE2 +202 -0
  11. package/lib/site-packages/outcome-1.3.0.post0.dist-info/LICENSE.MIT +20 -0
  12. package/lib/site-packages/outcome-1.3.0.post0.dist-info/METADATA +63 -0
  13. package/lib/site-packages/outcome-1.3.0.post0.dist-info/RECORD +13 -0
  14. package/lib/site-packages/outcome-1.3.0.post0.dist-info/WHEEL +6 -0
  15. package/lib/site-packages/outcome-1.3.0.post0.dist-info/top_level.txt +1 -0
  16. package/lib/site-packages/sniffio/__init__.py +17 -0
  17. package/lib/site-packages/sniffio/_impl.py +95 -0
  18. package/lib/site-packages/sniffio/_tests/__init__.py +0 -0
  19. package/lib/site-packages/sniffio/_tests/test_sniffio.py +84 -0
  20. package/lib/site-packages/sniffio/_version.py +3 -0
  21. package/lib/site-packages/sniffio/py.typed +0 -0
  22. package/lib/site-packages/sniffio-1.3.1.dist-info/INSTALLER +1 -0
  23. package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE +3 -0
  24. package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE.APACHE2 +202 -0
  25. package/lib/site-packages/sniffio-1.3.1.dist-info/LICENSE.MIT +20 -0
  26. package/lib/site-packages/sniffio-1.3.1.dist-info/METADATA +104 -0
  27. package/lib/site-packages/sniffio-1.3.1.dist-info/RECORD +14 -0
  28. package/lib/site-packages/sniffio-1.3.1.dist-info/WHEEL +5 -0
  29. package/lib/site-packages/sniffio-1.3.1.dist-info/top_level.txt +1 -0
  30. package/lib/site-packages/sortedcontainers/__init__.py +74 -0
  31. package/lib/site-packages/sortedcontainers/sorteddict.py +812 -0
  32. package/lib/site-packages/sortedcontainers/sortedlist.py +2646 -0
  33. package/lib/site-packages/sortedcontainers/sortedset.py +733 -0
  34. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/INSTALLER +1 -0
  35. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/LICENSE +13 -0
  36. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/METADATA +264 -0
  37. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/RECORD +10 -0
  38. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/WHEEL +6 -0
  39. package/lib/site-packages/sortedcontainers-2.4.0.dist-info/top_level.txt +1 -0
  40. package/lib/site-packages/trio/__init__.py +133 -0
  41. package/lib/site-packages/trio/__main__.py +3 -0
  42. package/lib/site-packages/trio/_abc.py +714 -0
  43. package/lib/site-packages/trio/_channel.py +610 -0
  44. package/lib/site-packages/trio/_core/__init__.py +94 -0
  45. package/lib/site-packages/trio/_core/_asyncgens.py +243 -0
  46. package/lib/site-packages/trio/_core/_concat_tb.py +26 -0
  47. package/lib/site-packages/trio/_core/_entry_queue.py +223 -0
  48. package/lib/site-packages/trio/_core/_exceptions.py +169 -0
  49. package/lib/site-packages/trio/_core/_generated_instrumentation.py +50 -0
  50. package/lib/site-packages/trio/_core/_generated_io_epoll.py +98 -0
  51. package/lib/site-packages/trio/_core/_generated_io_kqueue.py +153 -0
  52. package/lib/site-packages/trio/_core/_generated_io_windows.py +204 -0
  53. package/lib/site-packages/trio/_core/_generated_run.py +269 -0
  54. package/lib/site-packages/trio/_core/_generated_windows_ffi.py +10 -0
  55. package/lib/site-packages/trio/_core/_instrumentation.py +117 -0
  56. package/lib/site-packages/trio/_core/_io_common.py +31 -0
  57. package/lib/site-packages/trio/_core/_io_epoll.py +385 -0
  58. package/lib/site-packages/trio/_core/_io_kqueue.py +292 -0
  59. package/lib/site-packages/trio/_core/_io_windows.py +1036 -0
  60. package/lib/site-packages/trio/_core/_ki.py +271 -0
  61. package/lib/site-packages/trio/_core/_local.py +104 -0
  62. package/lib/site-packages/trio/_core/_mock_clock.py +165 -0
  63. package/lib/site-packages/trio/_core/_parking_lot.py +317 -0
  64. package/lib/site-packages/trio/_core/_run.py +3148 -0
  65. package/lib/site-packages/trio/_core/_run_context.py +15 -0
  66. package/lib/site-packages/trio/_core/_tests/__init__.py +0 -0
  67. package/lib/site-packages/trio/_core/_tests/test_asyncgen.py +339 -0
  68. package/lib/site-packages/trio/_core/_tests/test_cancelled.py +222 -0
  69. package/lib/site-packages/trio/_core/_tests/test_exceptiongroup_gc.py +103 -0
  70. package/lib/site-packages/trio/_core/_tests/test_guest_mode.py +755 -0
  71. package/lib/site-packages/trio/_core/_tests/test_instrumentation.py +315 -0
  72. package/lib/site-packages/trio/_core/_tests/test_io.py +522 -0
  73. package/lib/site-packages/trio/_core/_tests/test_ki.py +703 -0
  74. package/lib/site-packages/trio/_core/_tests/test_local.py +118 -0
  75. package/lib/site-packages/trio/_core/_tests/test_mock_clock.py +193 -0
  76. package/lib/site-packages/trio/_core/_tests/test_parking_lot.py +389 -0
  77. package/lib/site-packages/trio/_core/_tests/test_run.py +3024 -0
  78. package/lib/site-packages/trio/_core/_tests/test_thread_cache.py +227 -0
  79. package/lib/site-packages/trio/_core/_tests/test_tutil.py +13 -0
  80. package/lib/site-packages/trio/_core/_tests/test_unbounded_queue.py +154 -0
  81. package/lib/site-packages/trio/_core/_tests/test_windows.py +305 -0
  82. package/lib/site-packages/trio/_core/_tests/tutil.py +117 -0
  83. package/lib/site-packages/trio/_core/_tests/type_tests/nursery_start.py +79 -0
  84. package/lib/site-packages/trio/_core/_tests/type_tests/run.py +51 -0
  85. package/lib/site-packages/trio/_core/_thread_cache.py +317 -0
  86. package/lib/site-packages/trio/_core/_traps.py +318 -0
  87. package/lib/site-packages/trio/_core/_unbounded_queue.py +163 -0
  88. package/lib/site-packages/trio/_core/_wakeup_socketpair.py +75 -0
  89. package/lib/site-packages/trio/_core/_windows_cffi.py +313 -0
  90. package/lib/site-packages/trio/_deprecate.py +171 -0
  91. package/lib/site-packages/trio/_dtls.py +1380 -0
  92. package/lib/site-packages/trio/_file_io.py +513 -0
  93. package/lib/site-packages/trio/_highlevel_generic.py +125 -0
  94. package/lib/site-packages/trio/_highlevel_open_tcp_listeners.py +251 -0
  95. package/lib/site-packages/trio/_highlevel_open_tcp_stream.py +397 -0
  96. package/lib/site-packages/trio/_highlevel_open_unix_stream.py +65 -0
  97. package/lib/site-packages/trio/_highlevel_serve_listeners.py +148 -0
  98. package/lib/site-packages/trio/_highlevel_socket.py +423 -0
  99. package/lib/site-packages/trio/_highlevel_ssl_helpers.py +180 -0
  100. package/lib/site-packages/trio/_path.py +289 -0
  101. package/lib/site-packages/trio/_repl.py +159 -0
  102. package/lib/site-packages/trio/_signals.py +185 -0
  103. package/lib/site-packages/trio/_socket.py +1326 -0
  104. package/lib/site-packages/trio/_ssl.py +964 -0
  105. package/lib/site-packages/trio/_subprocess.py +1178 -0
  106. package/lib/site-packages/trio/_subprocess_platform/__init__.py +123 -0
  107. package/lib/site-packages/trio/_subprocess_platform/kqueue.py +48 -0
  108. package/lib/site-packages/trio/_subprocess_platform/waitid.py +113 -0
  109. package/lib/site-packages/trio/_subprocess_platform/windows.py +11 -0
  110. package/lib/site-packages/trio/_sync.py +908 -0
  111. package/lib/site-packages/trio/_tests/__init__.py +0 -0
  112. package/lib/site-packages/trio/_tests/astrill-codesigning-cert.cer +0 -0
  113. package/lib/site-packages/trio/_tests/check_type_completeness.py +247 -0
  114. package/lib/site-packages/trio/_tests/module_with_deprecations.py +22 -0
  115. package/lib/site-packages/trio/_tests/pytest_plugin.py +54 -0
  116. package/lib/site-packages/trio/_tests/test_abc.py +72 -0
  117. package/lib/site-packages/trio/_tests/test_channel.py +750 -0
  118. package/lib/site-packages/trio/_tests/test_contextvars.py +56 -0
  119. package/lib/site-packages/trio/_tests/test_deprecate.py +277 -0
  120. package/lib/site-packages/trio/_tests/test_deprecate_strict_exception_groups_false.py +64 -0
  121. package/lib/site-packages/trio/_tests/test_dtls.py +950 -0
  122. package/lib/site-packages/trio/_tests/test_exports.py +626 -0
  123. package/lib/site-packages/trio/_tests/test_fakenet.py +317 -0
  124. package/lib/site-packages/trio/_tests/test_file_io.py +269 -0
  125. package/lib/site-packages/trio/_tests/test_highlevel_generic.py +98 -0
  126. package/lib/site-packages/trio/_tests/test_highlevel_open_tcp_listeners.py +419 -0
  127. package/lib/site-packages/trio/_tests/test_highlevel_open_tcp_stream.py +693 -0
  128. package/lib/site-packages/trio/_tests/test_highlevel_open_unix_stream.py +86 -0
  129. package/lib/site-packages/trio/_tests/test_highlevel_serve_listeners.py +186 -0
  130. package/lib/site-packages/trio/_tests/test_highlevel_socket.py +336 -0
  131. package/lib/site-packages/trio/_tests/test_highlevel_ssl_helpers.py +169 -0
  132. package/lib/site-packages/trio/_tests/test_path.py +279 -0
  133. package/lib/site-packages/trio/_tests/test_repl.py +428 -0
  134. package/lib/site-packages/trio/_tests/test_scheduler_determinism.py +47 -0
  135. package/lib/site-packages/trio/_tests/test_signals.py +186 -0
  136. package/lib/site-packages/trio/_tests/test_socket.py +1253 -0
  137. package/lib/site-packages/trio/_tests/test_ssl.py +1371 -0
  138. package/lib/site-packages/trio/_tests/test_subprocess.py +767 -0
  139. package/lib/site-packages/trio/_tests/test_sync.py +735 -0
  140. package/lib/site-packages/trio/_tests/test_testing.py +682 -0
  141. package/lib/site-packages/trio/_tests/test_testing_raisesgroup.py +1128 -0
  142. package/lib/site-packages/trio/_tests/test_threads.py +1173 -0
  143. package/lib/site-packages/trio/_tests/test_timeouts.py +281 -0
  144. package/lib/site-packages/trio/_tests/test_tracing.py +88 -0
  145. package/lib/site-packages/trio/_tests/test_trio.py +8 -0
  146. package/lib/site-packages/trio/_tests/test_unix_pipes.py +288 -0
  147. package/lib/site-packages/trio/_tests/test_util.py +349 -0
  148. package/lib/site-packages/trio/_tests/test_wait_for_object.py +225 -0
  149. package/lib/site-packages/trio/_tests/test_windows_pipes.py +112 -0
  150. package/lib/site-packages/trio/_tests/tools/__init__.py +0 -0
  151. package/lib/site-packages/trio/_tests/tools/test_gen_exports.py +179 -0
  152. package/lib/site-packages/trio/_tests/tools/test_mypy_annotate.py +140 -0
  153. package/lib/site-packages/trio/_tests/tools/test_sync_requirements.py +80 -0
  154. package/lib/site-packages/trio/_tests/type_tests/check_wraps.py +9 -0
  155. package/lib/site-packages/trio/_tests/type_tests/open_memory_channel.py +4 -0
  156. package/lib/site-packages/trio/_tests/type_tests/path.py +140 -0
  157. package/lib/site-packages/trio/_tests/type_tests/subprocesses.py +23 -0
  158. package/lib/site-packages/trio/_tests/type_tests/task_status.py +29 -0
  159. package/lib/site-packages/trio/_threads.py +610 -0
  160. package/lib/site-packages/trio/_timeouts.py +197 -0
  161. package/lib/site-packages/trio/_tools/__init__.py +0 -0
  162. package/lib/site-packages/trio/_tools/gen_exports.py +401 -0
  163. package/lib/site-packages/trio/_tools/mypy_annotate.py +126 -0
  164. package/lib/site-packages/trio/_tools/sync_requirements.py +98 -0
  165. package/lib/site-packages/trio/_tools/windows_ffi_build.py +220 -0
  166. package/lib/site-packages/trio/_unix_pipes.py +197 -0
  167. package/lib/site-packages/trio/_util.py +385 -0
  168. package/lib/site-packages/trio/_version.py +3 -0
  169. package/lib/site-packages/trio/_wait_for_object.py +67 -0
  170. package/lib/site-packages/trio/_windows_pipes.py +144 -0
  171. package/lib/site-packages/trio/abc.py +23 -0
  172. package/lib/site-packages/trio/from_thread.py +13 -0
  173. package/lib/site-packages/trio/lowlevel.py +95 -0
  174. package/lib/site-packages/trio/py.typed +0 -0
  175. package/lib/site-packages/trio/socket.py +602 -0
  176. package/lib/site-packages/trio/testing/__init__.py +58 -0
  177. package/lib/site-packages/trio/testing/_check_streams.py +570 -0
  178. package/lib/site-packages/trio/testing/_checkpoints.py +69 -0
  179. package/lib/site-packages/trio/testing/_fake_net.py +584 -0
  180. package/lib/site-packages/trio/testing/_memory_streams.py +633 -0
  181. package/lib/site-packages/trio/testing/_network.py +36 -0
  182. package/lib/site-packages/trio/testing/_raises_group.py +1015 -0
  183. package/lib/site-packages/trio/testing/_sequencer.py +87 -0
  184. package/lib/site-packages/trio/testing/_trio_test.py +50 -0
  185. package/lib/site-packages/trio/to_thread.py +4 -0
  186. package/lib/site-packages/trio-0.33.0.dist-info/INSTALLER +1 -0
  187. package/lib/site-packages/trio-0.33.0.dist-info/METADATA +186 -0
  188. package/lib/site-packages/trio-0.33.0.dist-info/RECORD +156 -0
  189. package/lib/site-packages/trio-0.33.0.dist-info/REQUESTED +0 -0
  190. package/lib/site-packages/trio-0.33.0.dist-info/WHEEL +5 -0
  191. package/lib/site-packages/trio-0.33.0.dist-info/entry_points.txt +2 -0
  192. package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE +3 -0
  193. package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE.APACHE2 +202 -0
  194. package/lib/site-packages/trio-0.33.0.dist-info/licenses/LICENSE.MIT +22 -0
  195. package/lib/site-packages/trio-0.33.0.dist-info/top_level.txt +1 -0
  196. package/package.json +1 -1
@@ -0,0 +1,126 @@
1
+ """Translates Mypy's output into GitHub's error/warning annotation syntax.
2
+
3
+ See: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
4
+
5
+ This first is run with Mypy's output piped in, to collect messages in
6
+ mypy_annotate.dat. After all platforms run, we run this again, which prints the
7
+ messages in GitHub's format but with cross-platform failures deduplicated.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import pickle
14
+ import re
15
+ import sys
16
+
17
+ import attrs
18
+
19
+ # Example: 'package/filename.py:42:1:46:3: error: Type error here [code]'
20
+ report_re = re.compile(
21
+ r"""
22
+ ([^:]+): # Filename (anything but ":")
23
+ ([0-9]+): # Line number (start)
24
+ (?:([0-9]+): # Optional column number
25
+ (?:([0-9]+):([0-9]+):)? # then also optionally, 2 more numbers for end columns
26
+ )?
27
+ \s*(error|warn|note): # Kind, prefixed with space
28
+ (.+) # Message
29
+ """,
30
+ re.VERBOSE,
31
+ )
32
+
33
+ mypy_to_github = {
34
+ "error": "error",
35
+ "warn": "warning",
36
+ "note": "notice",
37
+ }
38
+
39
+
40
+ @attrs.frozen(kw_only=True)
41
+ class Result:
42
+ """Accumulated results, used as a dict key to deduplicate."""
43
+
44
+ filename: str
45
+ start_line: int
46
+ kind: str
47
+ message: str
48
+ start_col: int | None = None
49
+ end_line: int | None = None
50
+ end_col: int | None = None
51
+
52
+
53
+ def process_line(line: str) -> Result | None:
54
+ if match := report_re.fullmatch(line.rstrip()):
55
+ filename, st_line, st_col, end_line, end_col, kind, message = match.groups()
56
+ return Result(
57
+ filename=filename,
58
+ start_line=int(st_line),
59
+ start_col=int(st_col) if st_col is not None else None,
60
+ end_line=int(end_line) if end_line is not None else None,
61
+ end_col=int(end_col) if end_col is not None else None,
62
+ kind=mypy_to_github[kind],
63
+ message=message,
64
+ )
65
+ else:
66
+ return None
67
+
68
+
69
+ def export(results: dict[Result, list[str]]) -> None:
70
+ """Display the collected results."""
71
+ for res, platforms in results.items():
72
+ print(f"::{res.kind} file={res.filename},line={res.start_line},", end="")
73
+ if res.start_col is not None:
74
+ print(f"col={res.start_col},", end="")
75
+ if res.end_col is not None and res.end_line is not None:
76
+ print(f"endLine={res.end_line},endColumn={res.end_col},", end="")
77
+ message = f"({res.start_line}:{res.start_col} - {res.end_line}:{res.end_col}):{res.message}"
78
+ else:
79
+ message = f"({res.start_line}:{res.start_col}):{res.message}"
80
+ else:
81
+ message = f"{res.start_line}:{res.message}"
82
+ print(f"title=Mypy-{'+'.join(platforms)}::{res.filename}:{message}")
83
+
84
+
85
+ def main(argv: list[str]) -> None:
86
+ """Look for error messages, and convert the format."""
87
+ parser = argparse.ArgumentParser(description=__doc__)
88
+ parser.add_argument(
89
+ "--dumpfile",
90
+ help="File to write pickled messages to.",
91
+ required=True,
92
+ )
93
+ parser.add_argument(
94
+ "--platform",
95
+ help="OS name, if set Mypy should be piped to stdin.",
96
+ default=None,
97
+ )
98
+ cmd_line = parser.parse_args(argv)
99
+
100
+ results: dict[Result, list[str]]
101
+ try:
102
+ with open(cmd_line.dumpfile, "rb") as f:
103
+ results = pickle.load(f)
104
+ except (FileNotFoundError, pickle.UnpicklingError):
105
+ # If we fail to load, assume it's an old result.
106
+ results = {}
107
+
108
+ if cmd_line.platform is None:
109
+ # Write out the results.
110
+ export(results)
111
+ else:
112
+ platform: str = cmd_line.platform
113
+ for line in sys.stdin:
114
+ parsed = process_line(line)
115
+ if parsed is not None:
116
+ try:
117
+ results[parsed].append(platform)
118
+ except KeyError:
119
+ results[parsed] = [platform]
120
+ sys.stdout.write(line)
121
+ with open(cmd_line.dumpfile, "wb") as f:
122
+ pickle.dump(results, f)
123
+
124
+
125
+ if __name__ == "__main__":
126
+ main(sys.argv[1:])
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Sync Requirements - Automatically upgrade test requirements pinned
4
+ versions from pre-commit config file."""
5
+
6
+ from __future__ import annotations
7
+
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import TYPE_CHECKING
11
+
12
+ from yaml import load as load_yaml
13
+
14
+ if TYPE_CHECKING:
15
+ from collections.abc import Generator
16
+
17
+ from yaml import CLoader as _CLoader, Loader as _Loader
18
+
19
+ Loader: type[_CLoader | _Loader]
20
+
21
+ try:
22
+ from yaml import CLoader as Loader
23
+ except ImportError:
24
+ from yaml import Loader
25
+
26
+
27
+ def yield_pre_commit_version_data(
28
+ pre_commit_text: str,
29
+ ) -> Generator[tuple[str, str], None, None]:
30
+ """Yield (name, rev) tuples from pre-commit config file."""
31
+ pre_commit_config = load_yaml(pre_commit_text, Loader)
32
+ for repo in pre_commit_config["repos"]:
33
+ if "repo" not in repo or "rev" not in repo:
34
+ continue
35
+ url = repo["repo"]
36
+ name = url.rsplit("/", 1)[-1]
37
+ rev = repo["rev"].removeprefix("v")
38
+ yield name, rev
39
+
40
+
41
+ def update_requirements(
42
+ requirements: Path,
43
+ version_data: dict[str, str],
44
+ ) -> bool:
45
+ """Return if updated requirements file.
46
+
47
+ Update requirements file to match versions in version_data."""
48
+ changed = False
49
+ old_lines = requirements.read_text(encoding="utf-8").splitlines(True)
50
+
51
+ with requirements.open("w", encoding="utf-8") as file:
52
+ for line in old_lines:
53
+ # If comment or not version mark line, ignore.
54
+ if line.startswith("#") or "==" not in line:
55
+ file.write(line)
56
+ continue
57
+ name, rest = line.split("==", 1)
58
+ # Maintain extra markers if they exist
59
+ old_version = rest.strip()
60
+ extra = "\n"
61
+ if ";" in rest:
62
+ old_version, extra = rest.split(";", 1)
63
+ old_version = old_version.strip()
64
+ extra = " ;" + extra
65
+ version = version_data.get(name)
66
+ # If does not exist, skip
67
+ if version is None:
68
+ file.write(line)
69
+ continue
70
+ # Otherwise might have changed
71
+ new_line = f"{name}=={version}{extra}"
72
+ if new_line != line:
73
+ if not changed:
74
+ changed = True
75
+ print("Changed test requirements version to match pre-commit")
76
+ print(f"{name}=={old_version} -> {name}=={version}")
77
+ file.write(new_line)
78
+ return changed
79
+
80
+
81
+ if __name__ == "__main__":
82
+ source_root = Path.cwd().absolute()
83
+
84
+ # Double-check we found the right directory
85
+ assert (source_root / "LICENSE").exists()
86
+ pre_commit = source_root / ".pre-commit-config.yaml"
87
+ test_requirements = source_root / "test-requirements.txt"
88
+
89
+ pre_commit_text = pre_commit.read_text(encoding="utf-8")
90
+
91
+ # Get tool versions from pre-commit
92
+ # Get correct names
93
+ pre_commit_versions = {
94
+ name.removesuffix("-mirror").removesuffix("-pre-commit"): version
95
+ for name, version in yield_pre_commit_version_data(pre_commit_text)
96
+ }
97
+ changed = update_requirements(test_requirements, pre_commit_versions)
98
+ sys.exit(int(changed))
@@ -0,0 +1,220 @@
1
+ # builder for CFFI out-of-line mode, for reduced import time.
2
+ # run this to generate `trio._core._generated_windows_ffi`.
3
+ import re
4
+
5
+ import cffi
6
+
7
+ LIB = """
8
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
9
+ typedef int BOOL;
10
+ typedef unsigned char BYTE;
11
+ typedef unsigned char UCHAR;
12
+ typedef BYTE BOOLEAN;
13
+ typedef void* PVOID;
14
+ typedef PVOID HANDLE;
15
+ typedef unsigned long DWORD;
16
+ typedef unsigned long ULONG;
17
+ typedef unsigned int NTSTATUS;
18
+ typedef unsigned long u_long;
19
+ typedef ULONG *PULONG;
20
+ typedef const void *LPCVOID;
21
+ typedef void *LPVOID;
22
+ typedef const wchar_t *LPCWSTR;
23
+ typedef DWORD* LPDWORD;
24
+
25
+ typedef uintptr_t ULONG_PTR;
26
+ typedef uintptr_t UINT_PTR;
27
+
28
+ typedef UINT_PTR SOCKET;
29
+
30
+ typedef struct _OVERLAPPED {
31
+ ULONG_PTR Internal;
32
+ ULONG_PTR InternalHigh;
33
+ union {
34
+ struct {
35
+ DWORD Offset;
36
+ DWORD OffsetHigh;
37
+ } DUMMYSTRUCTNAME;
38
+ PVOID Pointer;
39
+ } DUMMYUNIONNAME;
40
+
41
+ HANDLE hEvent;
42
+ } OVERLAPPED, *LPOVERLAPPED;
43
+
44
+ typedef OVERLAPPED WSAOVERLAPPED;
45
+ typedef LPOVERLAPPED LPWSAOVERLAPPED;
46
+ typedef PVOID LPSECURITY_ATTRIBUTES;
47
+ typedef PVOID LPCSTR;
48
+
49
+ typedef struct _OVERLAPPED_ENTRY {
50
+ ULONG_PTR lpCompletionKey;
51
+ LPOVERLAPPED lpOverlapped;
52
+ ULONG_PTR Internal;
53
+ DWORD dwNumberOfBytesTransferred;
54
+ } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY;
55
+
56
+ // kernel32.dll
57
+ HANDLE WINAPI CreateIoCompletionPort(
58
+ _In_ HANDLE FileHandle,
59
+ _In_opt_ HANDLE ExistingCompletionPort,
60
+ _In_ ULONG_PTR CompletionKey,
61
+ _In_ DWORD NumberOfConcurrentThreads
62
+ );
63
+
64
+ BOOL SetFileCompletionNotificationModes(
65
+ HANDLE FileHandle,
66
+ UCHAR Flags
67
+ );
68
+
69
+ HANDLE CreateFileW(
70
+ LPCWSTR lpFileName,
71
+ DWORD dwDesiredAccess,
72
+ DWORD dwShareMode,
73
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
74
+ DWORD dwCreationDisposition,
75
+ DWORD dwFlagsAndAttributes,
76
+ HANDLE hTemplateFile
77
+ );
78
+
79
+ BOOL WINAPI CloseHandle(
80
+ _In_ HANDLE hObject
81
+ );
82
+
83
+ BOOL WINAPI PostQueuedCompletionStatus(
84
+ _In_ HANDLE CompletionPort,
85
+ _In_ DWORD dwNumberOfBytesTransferred,
86
+ _In_ ULONG_PTR dwCompletionKey,
87
+ _In_opt_ LPOVERLAPPED lpOverlapped
88
+ );
89
+
90
+ BOOL WINAPI GetQueuedCompletionStatusEx(
91
+ _In_ HANDLE CompletionPort,
92
+ _Out_ LPOVERLAPPED_ENTRY lpCompletionPortEntries,
93
+ _In_ ULONG ulCount,
94
+ _Out_ PULONG ulNumEntriesRemoved,
95
+ _In_ DWORD dwMilliseconds,
96
+ _In_ BOOL fAlertable
97
+ );
98
+
99
+ BOOL WINAPI CancelIoEx(
100
+ _In_ HANDLE hFile,
101
+ _In_opt_ LPOVERLAPPED lpOverlapped
102
+ );
103
+
104
+ BOOL WriteFile(
105
+ HANDLE hFile,
106
+ LPCVOID lpBuffer,
107
+ DWORD nNumberOfBytesToWrite,
108
+ LPDWORD lpNumberOfBytesWritten,
109
+ LPOVERLAPPED lpOverlapped
110
+ );
111
+
112
+ BOOL ReadFile(
113
+ HANDLE hFile,
114
+ LPVOID lpBuffer,
115
+ DWORD nNumberOfBytesToRead,
116
+ LPDWORD lpNumberOfBytesRead,
117
+ LPOVERLAPPED lpOverlapped
118
+ );
119
+
120
+ BOOL WINAPI SetConsoleCtrlHandler(
121
+ _In_opt_ void* HandlerRoutine,
122
+ _In_ BOOL Add
123
+ );
124
+
125
+ HANDLE CreateEventA(
126
+ LPSECURITY_ATTRIBUTES lpEventAttributes,
127
+ BOOL bManualReset,
128
+ BOOL bInitialState,
129
+ LPCSTR lpName
130
+ );
131
+
132
+ BOOL SetEvent(
133
+ HANDLE hEvent
134
+ );
135
+
136
+ BOOL ResetEvent(
137
+ HANDLE hEvent
138
+ );
139
+
140
+ DWORD WaitForSingleObject(
141
+ HANDLE hHandle,
142
+ DWORD dwMilliseconds
143
+ );
144
+
145
+ DWORD WaitForMultipleObjects(
146
+ DWORD nCount,
147
+ HANDLE *lpHandles,
148
+ BOOL bWaitAll,
149
+ DWORD dwMilliseconds
150
+ );
151
+
152
+ ULONG RtlNtStatusToDosError(
153
+ NTSTATUS Status
154
+ );
155
+
156
+ int WSAIoctl(
157
+ SOCKET s,
158
+ DWORD dwIoControlCode,
159
+ LPVOID lpvInBuffer,
160
+ DWORD cbInBuffer,
161
+ LPVOID lpvOutBuffer,
162
+ DWORD cbOutBuffer,
163
+ LPDWORD lpcbBytesReturned,
164
+ LPWSAOVERLAPPED lpOverlapped,
165
+ // actually LPWSAOVERLAPPED_COMPLETION_ROUTINE
166
+ void* lpCompletionRoutine
167
+ );
168
+
169
+ int WSAGetLastError();
170
+
171
+ BOOL DeviceIoControl(
172
+ HANDLE hDevice,
173
+ DWORD dwIoControlCode,
174
+ LPVOID lpInBuffer,
175
+ DWORD nInBufferSize,
176
+ LPVOID lpOutBuffer,
177
+ DWORD nOutBufferSize,
178
+ LPDWORD lpBytesReturned,
179
+ LPOVERLAPPED lpOverlapped
180
+ );
181
+
182
+ // From https://github.com/piscisaureus/wepoll/blob/master/src/afd.h
183
+ typedef struct _AFD_POLL_HANDLE_INFO {
184
+ HANDLE Handle;
185
+ ULONG Events;
186
+ NTSTATUS Status;
187
+ } AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO;
188
+
189
+ // This is really defined as a messy union to allow stuff like
190
+ // i.DUMMYSTRUCTNAME.LowPart, but we don't need those complications.
191
+ // Under all that it's just an int64.
192
+ typedef int64_t LARGE_INTEGER;
193
+
194
+ typedef struct _AFD_POLL_INFO {
195
+ LARGE_INTEGER Timeout;
196
+ ULONG NumberOfHandles;
197
+ ULONG Exclusive;
198
+ AFD_POLL_HANDLE_INFO Handles[1];
199
+ } AFD_POLL_INFO, *PAFD_POLL_INFO;
200
+
201
+ """
202
+
203
+ # cribbed from pywincffi
204
+ # programmatically strips out those annotations MSDN likes, like _In_
205
+ LIB = re.sub(r"\b(_In_|_Inout_|_Out_|_Outptr_|_Reserved_)(opt_)?\b", " ", LIB)
206
+
207
+ # Other fixups:
208
+ # - get rid of FAR, cffi doesn't like it
209
+ LIB = re.sub(r"\bFAR\b", " ", LIB)
210
+ # - PASCAL is apparently an alias for __stdcall (on modern compilers - modern
211
+ # being _MSC_VER >= 800)
212
+ LIB = re.sub(r"\bPASCAL\b", "__stdcall", LIB)
213
+
214
+ ffibuilder = cffi.FFI()
215
+ # a bit hacky but, it works
216
+ ffibuilder.set_source("trio._core._generated_windows_ffi", None)
217
+ ffibuilder.cdef(LIB)
218
+
219
+ if __name__ == "__main__":
220
+ ffibuilder.compile("src")
@@ -0,0 +1,197 @@
1
+ from __future__ import annotations
2
+
3
+ import errno
4
+ import os
5
+ import sys
6
+ from typing import TYPE_CHECKING, Final as FinalType
7
+
8
+ import trio
9
+
10
+ from ._abc import Stream
11
+ from ._util import ConflictDetector, final
12
+
13
+ assert not TYPE_CHECKING or sys.platform != "win32"
14
+
15
+ # XX TODO: is this a good number? who knows... it does match the default Linux
16
+ # pipe capacity though.
17
+ DEFAULT_RECEIVE_SIZE: FinalType = 65536
18
+
19
+
20
+ class _FdHolder:
21
+ # This class holds onto a raw file descriptor, in non-blocking mode, and
22
+ # is responsible for managing its lifecycle. In particular, it's
23
+ # responsible for making sure it gets closed, and also for tracking
24
+ # whether it's been closed.
25
+ #
26
+ # The way we track closure is to set the .fd field to -1, discarding the
27
+ # original value. You might think that this is a strange idea, since it
28
+ # overloads the same field to do two different things. Wouldn't it be more
29
+ # natural to have a dedicated .closed field? But that would be more
30
+ # error-prone. Fds are represented by small integers, and once an fd is
31
+ # closed, its integer value may be reused immediately. If we accidentally
32
+ # used the old fd after being closed, we might end up doing something to
33
+ # another unrelated fd that happened to get assigned the same integer
34
+ # value. By throwing away the integer value immediately, it becomes
35
+ # impossible to make this mistake – we'll just get an EBADF.
36
+ #
37
+ # (This trick was copied from the stdlib socket module.)
38
+ fd: int
39
+
40
+ def __init__(self, fd: int) -> None:
41
+ # make sure self.fd is always initialized to *something*, because even
42
+ # if we error out here then __del__ will run and access it.
43
+ self.fd = -1
44
+ if not isinstance(fd, int):
45
+ raise TypeError("file descriptor must be an int")
46
+ self.fd = fd
47
+ # Store original state, and ensure non-blocking mode is enabled
48
+ self._original_is_blocking = os.get_blocking(fd)
49
+ os.set_blocking(fd, False)
50
+
51
+ @property
52
+ def closed(self) -> bool:
53
+ return self.fd == -1
54
+
55
+ def _raw_close(self) -> None:
56
+ # This doesn't assume it's in a Trio context, so it can be called from
57
+ # __del__. You should never call it from Trio context, because it
58
+ # skips calling notify_fd_close. But from __del__, skipping that is
59
+ # OK, because notify_fd_close just wakes up other tasks that are
60
+ # waiting on this fd, and those tasks hold a reference to this object.
61
+ # So if __del__ is being called, we know there aren't any tasks that
62
+ # need to be woken.
63
+ if self.closed:
64
+ return
65
+ fd = self.fd
66
+ self.fd = -1
67
+ os.set_blocking(fd, self._original_is_blocking)
68
+ os.close(fd)
69
+
70
+ def __del__(self) -> None:
71
+ self._raw_close()
72
+
73
+ def close(self) -> None:
74
+ if not self.closed:
75
+ trio.lowlevel.notify_closing(self.fd)
76
+ self._raw_close()
77
+
78
+
79
+ @final
80
+ class FdStream(Stream):
81
+ """Represents a stream given the file descriptor to a pipe, TTY, etc.
82
+
83
+ *fd* must refer to a file that is open for reading and/or writing and
84
+ supports non-blocking I/O (pipes and TTYs will work, on-disk files probably
85
+ not). The returned stream takes ownership of the fd, so closing the stream
86
+ will close the fd too. As with `os.fdopen`, you should not directly use
87
+ an fd after you have wrapped it in a stream using this function.
88
+
89
+ To be used as a Trio stream, an open file must be placed in non-blocking
90
+ mode. Unfortunately, this impacts all I/O that goes through the
91
+ underlying open file, including I/O that uses a different
92
+ file descriptor than the one that was passed to Trio. If other threads
93
+ or processes are using file descriptors that are related through `os.dup`
94
+ or inheritance across `os.fork` to the one that Trio is using, they are
95
+ unlikely to be prepared to have non-blocking I/O semantics suddenly
96
+ thrust upon them. For example, you can use
97
+ ``FdStream(os.dup(sys.stdin.fileno()))`` to obtain a stream for reading
98
+ from standard input, but it is only safe to do so with heavy caveats: your
99
+ stdin must not be shared by any other processes, and you must not make any
100
+ calls to synchronous methods of `sys.stdin` until the stream returned by
101
+ `FdStream` is closed. See `issue #174
102
+ <https://github.com/python-trio/trio/issues/174>`__ for a discussion of the
103
+ challenges involved in relaxing this restriction.
104
+
105
+ .. warning:: one specific consequence of non-blocking mode
106
+ applying to the entire open file description is that when
107
+ your program is run with multiple standard streams connected to
108
+ a TTY (as in a terminal emulator), all of the streams become
109
+ non-blocking when you construct an `FdStream` for any of them.
110
+ For example, if you construct an `FdStream` for standard input,
111
+ you might observe Python loggers begin to fail with
112
+ `BlockingIOError`.
113
+
114
+ Args:
115
+ fd (int): The fd to be wrapped.
116
+
117
+ Returns:
118
+ A new `FdStream` object.
119
+ """
120
+
121
+ def __init__(self, fd: int) -> None:
122
+ self._fd_holder = _FdHolder(fd)
123
+ self._send_conflict_detector = ConflictDetector(
124
+ "another task is using this stream for send",
125
+ )
126
+ self._receive_conflict_detector = ConflictDetector(
127
+ "another task is using this stream for receive",
128
+ )
129
+
130
+ async def send_all(self, data: bytes) -> None:
131
+ with self._send_conflict_detector:
132
+ # have to check up front, because send_all(b"") on a closed pipe
133
+ # should raise
134
+ if self._fd_holder.closed:
135
+ raise trio.ClosedResourceError("file was already closed")
136
+ await trio.lowlevel.checkpoint()
137
+ length = len(data)
138
+ # adapted from the SocketStream code
139
+ with memoryview(data) as view:
140
+ sent = 0
141
+ while sent < length:
142
+ with view[sent:] as remaining:
143
+ try:
144
+ sent += os.write(self._fd_holder.fd, remaining)
145
+ except BlockingIOError:
146
+ await trio.lowlevel.wait_writable(self._fd_holder.fd)
147
+ except OSError as e:
148
+ if e.errno == errno.EBADF:
149
+ raise trio.ClosedResourceError(
150
+ "file was already closed",
151
+ ) from None
152
+ else:
153
+ raise trio.BrokenResourceError from e
154
+
155
+ async def wait_send_all_might_not_block(self) -> None:
156
+ with self._send_conflict_detector:
157
+ if self._fd_holder.closed:
158
+ raise trio.ClosedResourceError("file was already closed")
159
+ await trio.lowlevel.wait_writable(self._fd_holder.fd)
160
+
161
+ async def receive_some(self, max_bytes: int | None = None) -> bytes:
162
+ with self._receive_conflict_detector:
163
+ if max_bytes is None:
164
+ max_bytes = DEFAULT_RECEIVE_SIZE
165
+ else:
166
+ if not isinstance(max_bytes, int):
167
+ raise TypeError("max_bytes must be integer >= 1")
168
+ if max_bytes < 1:
169
+ raise ValueError("max_bytes must be integer >= 1")
170
+
171
+ await trio.lowlevel.checkpoint()
172
+ while True:
173
+ try:
174
+ data = os.read(self._fd_holder.fd, max_bytes)
175
+ except BlockingIOError:
176
+ await trio.lowlevel.wait_readable(self._fd_holder.fd)
177
+ except OSError as exc:
178
+ if exc.errno == errno.EBADF:
179
+ raise trio.ClosedResourceError(
180
+ "file was already closed",
181
+ ) from None
182
+ else:
183
+ raise trio.BrokenResourceError from exc
184
+ else:
185
+ break
186
+
187
+ return data
188
+
189
+ def close(self) -> None:
190
+ self._fd_holder.close()
191
+
192
+ async def aclose(self) -> None:
193
+ self.close()
194
+ await trio.lowlevel.checkpoint()
195
+
196
+ def fileno(self) -> int:
197
+ return self._fd_holder.fd