@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,169 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+ from typing import TYPE_CHECKING, NoReturn, cast
5
+
6
+ import attrs
7
+ import pytest
8
+
9
+ import trio
10
+ from trio.socket import AF_INET, IPPROTO_TCP, SOCK_STREAM
11
+
12
+ from .._highlevel_ssl_helpers import (
13
+ open_ssl_over_tcp_listeners,
14
+ open_ssl_over_tcp_stream,
15
+ serve_ssl_over_tcp,
16
+ )
17
+
18
+ # using noqa because linters don't understand how pytest fixtures work.
19
+ from .test_ssl import SERVER_CTX, client_ctx # noqa: F401
20
+
21
+ if TYPE_CHECKING:
22
+ from socket import AddressFamily, SocketKind
23
+ from ssl import SSLContext
24
+
25
+ from trio.abc import Stream
26
+
27
+ from .._highlevel_socket import SocketListener
28
+ from .._ssl import SSLListener
29
+
30
+
31
+ async def echo_handler(stream: Stream) -> None:
32
+ async with stream:
33
+ try:
34
+ while True:
35
+ data = await stream.receive_some(10000)
36
+ if not data:
37
+ break
38
+ await stream.send_all(data)
39
+ except trio.BrokenResourceError:
40
+ pass
41
+
42
+
43
+ # Resolver that always returns the given sockaddr, no matter what host/port
44
+ # you ask for.
45
+ @attrs.define(slots=False)
46
+ class FakeHostnameResolver(trio.abc.HostnameResolver):
47
+ sockaddr: tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes]
48
+
49
+ async def getaddrinfo(
50
+ self,
51
+ host: bytes | None,
52
+ port: bytes | str | int | None,
53
+ family: int = 0,
54
+ type: int = 0,
55
+ proto: int = 0,
56
+ flags: int = 0,
57
+ ) -> list[
58
+ tuple[
59
+ AddressFamily,
60
+ SocketKind,
61
+ int,
62
+ str,
63
+ tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes],
64
+ ]
65
+ ]:
66
+ return [(AF_INET, SOCK_STREAM, IPPROTO_TCP, "", self.sockaddr)]
67
+
68
+ async def getnameinfo(
69
+ self,
70
+ sockaddr: tuple[str, int] | tuple[str, int, int, int],
71
+ flags: int,
72
+ ) -> NoReturn: # pragma: no cover
73
+ raise NotImplementedError
74
+
75
+
76
+ # This uses serve_ssl_over_tcp, which uses open_ssl_over_tcp_listeners...
77
+ # using noqa because linters don't understand how pytest fixtures work.
78
+ async def test_open_ssl_over_tcp_stream_and_everything_else(
79
+ client_ctx: SSLContext, # noqa: F811 # linters doesn't understand fixture
80
+ ) -> None:
81
+ async with trio.open_nursery() as nursery:
82
+ # TODO: this function wraps an SSLListener around a SocketListener, this is illegal
83
+ # according to current type hints, and probably for good reason. But there should
84
+ # maybe be a different wrapper class/function that could be used instead?
85
+ value = await nursery.start(
86
+ partial(
87
+ serve_ssl_over_tcp,
88
+ echo_handler,
89
+ 0,
90
+ SERVER_CTX,
91
+ host="127.0.0.1",
92
+ ),
93
+ )
94
+ assert isinstance(value, list)
95
+ res = cast("list[SSLListener[SocketListener]]", value) # type: ignore[type-var]
96
+ (listener,) = res
97
+ async with listener:
98
+ # listener.transport_listener is of type Listener[Stream]
99
+ tp_listener: SocketListener = listener.transport_listener # type: ignore[assignment]
100
+
101
+ sockaddr = tp_listener.socket.getsockname()
102
+ hostname_resolver = FakeHostnameResolver(sockaddr)
103
+ trio.socket.set_custom_hostname_resolver(hostname_resolver)
104
+
105
+ # We don't have the right trust set up
106
+ # (checks that ssl_context=None is doing some validation)
107
+ stream = await open_ssl_over_tcp_stream("trio-test-1.example.org", 80)
108
+ async with stream:
109
+ with pytest.raises(trio.BrokenResourceError):
110
+ await stream.do_handshake()
111
+
112
+ # We have the trust but not the hostname
113
+ # (checks custom ssl_context + hostname checking)
114
+ stream = await open_ssl_over_tcp_stream(
115
+ "xyzzy.example.org",
116
+ 80,
117
+ ssl_context=client_ctx,
118
+ )
119
+ async with stream:
120
+ with pytest.raises(trio.BrokenResourceError):
121
+ await stream.do_handshake()
122
+
123
+ # This one should work!
124
+ stream = await open_ssl_over_tcp_stream(
125
+ "trio-test-1.example.org",
126
+ 80,
127
+ ssl_context=client_ctx,
128
+ )
129
+ async with stream:
130
+ assert isinstance(stream, trio.SSLStream)
131
+ assert stream.server_hostname == "trio-test-1.example.org"
132
+ await stream.send_all(b"x")
133
+ assert await stream.receive_some(1) == b"x"
134
+
135
+ # Check https_compatible settings are being passed through
136
+ assert not stream._https_compatible
137
+ stream = await open_ssl_over_tcp_stream(
138
+ "trio-test-1.example.org",
139
+ 80,
140
+ ssl_context=client_ctx,
141
+ https_compatible=True,
142
+ # also, smoke test happy_eyeballs_delay
143
+ happy_eyeballs_delay=1,
144
+ )
145
+ async with stream:
146
+ assert stream._https_compatible
147
+
148
+ # Stop the echo server
149
+ nursery.cancel_scope.cancel()
150
+
151
+
152
+ async def test_open_ssl_over_tcp_listeners() -> None:
153
+ (listener,) = await open_ssl_over_tcp_listeners(0, SERVER_CTX, host="127.0.0.1")
154
+ async with listener:
155
+ assert isinstance(listener, trio.SSLListener)
156
+ tl = listener.transport_listener
157
+ assert isinstance(tl, trio.SocketListener)
158
+ assert tl.socket.getsockname()[0] == "127.0.0.1"
159
+
160
+ assert not listener._https_compatible
161
+
162
+ (listener,) = await open_ssl_over_tcp_listeners(
163
+ 0,
164
+ SERVER_CTX,
165
+ host="127.0.0.1",
166
+ https_compatible=True,
167
+ )
168
+ async with listener:
169
+ assert listener._https_compatible
@@ -0,0 +1,279 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import pathlib
5
+ from typing import TYPE_CHECKING
6
+
7
+ import pytest
8
+
9
+ import trio
10
+ from trio._file_io import AsyncIOWrapper
11
+
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Awaitable, Callable
14
+
15
+
16
+ @pytest.fixture
17
+ def path(tmp_path: pathlib.Path) -> trio.Path:
18
+ return trio.Path(tmp_path / "test")
19
+
20
+
21
+ def method_pair(
22
+ path: str,
23
+ method_name: str,
24
+ ) -> tuple[Callable[[], object], Callable[[], Awaitable[object]]]:
25
+ sync_path = pathlib.Path(path)
26
+ async_path = trio.Path(path)
27
+ return getattr(sync_path, method_name), getattr(async_path, method_name)
28
+
29
+
30
+ @pytest.mark.skipif(os.name == "nt", reason="OS is not posix")
31
+ def test_instantiate_posix() -> None:
32
+ assert isinstance(trio.Path(), trio.PosixPath)
33
+
34
+
35
+ @pytest.mark.skipif(os.name != "nt", reason="OS is not Windows")
36
+ def test_instantiate_windows() -> None:
37
+ assert isinstance(trio.Path(), trio.WindowsPath)
38
+
39
+
40
+ async def test_open_is_async_context_manager(path: trio.Path) -> None:
41
+ async with await path.open("w") as f:
42
+ assert isinstance(f, AsyncIOWrapper)
43
+
44
+ assert f.closed
45
+
46
+
47
+ def test_magic() -> None:
48
+ path = trio.Path("test")
49
+
50
+ assert str(path) == "test"
51
+ assert bytes(path) == b"test"
52
+
53
+
54
+ EitherPathType = type[trio.Path] | type[pathlib.Path]
55
+ PathOrStrType = EitherPathType | type[str]
56
+ cls_pairs: list[tuple[EitherPathType, EitherPathType]] = [
57
+ (trio.Path, pathlib.Path),
58
+ (pathlib.Path, trio.Path),
59
+ (trio.Path, trio.Path),
60
+ ]
61
+
62
+
63
+ @pytest.mark.parametrize(("cls_a", "cls_b"), cls_pairs)
64
+ def test_cmp_magic(cls_a: EitherPathType, cls_b: EitherPathType) -> None:
65
+ a, b = cls_a(""), cls_b("")
66
+ assert a == b
67
+ assert not a != b # noqa: SIM202 # negate-not-equal-op
68
+
69
+ a, b = cls_a("a"), cls_b("b")
70
+ assert a < b
71
+ assert b > a
72
+
73
+ # this is intentionally testing equivalence with none, due to the
74
+ # other=sentinel logic in _forward_magic
75
+ assert not a == None # noqa
76
+ assert not b == None # noqa
77
+
78
+
79
+ # upstream python3.8 bug: we should also test (pathlib.Path, trio.Path), but
80
+ # __*div__ does not properly raise NotImplementedError like the other comparison
81
+ # magic, so trio.Path's implementation does not get dispatched
82
+ cls_pairs_str: list[tuple[PathOrStrType, PathOrStrType]] = [
83
+ (trio.Path, pathlib.Path),
84
+ (trio.Path, trio.Path),
85
+ (trio.Path, str),
86
+ (str, trio.Path),
87
+ ]
88
+
89
+
90
+ @pytest.mark.parametrize(("cls_a", "cls_b"), cls_pairs_str)
91
+ def test_div_magic(cls_a: PathOrStrType, cls_b: PathOrStrType) -> None:
92
+ a, b = cls_a("a"), cls_b("b")
93
+
94
+ result = a / b # type: ignore[operator]
95
+ # Type checkers think str / str could happen. Check each combo manually in type_tests/.
96
+ assert isinstance(result, trio.Path)
97
+ assert str(result) == os.path.join("a", "b")
98
+
99
+
100
+ @pytest.mark.parametrize(
101
+ ("cls_a", "cls_b"),
102
+ [(trio.Path, pathlib.Path), (trio.Path, trio.Path)],
103
+ )
104
+ @pytest.mark.parametrize("path", ["foo", "foo/bar/baz", "./foo"])
105
+ def test_hash_magic(
106
+ cls_a: EitherPathType,
107
+ cls_b: EitherPathType,
108
+ path: str,
109
+ ) -> None:
110
+ a, b = cls_a(path), cls_b(path)
111
+ assert hash(a) == hash(b)
112
+
113
+
114
+ def test_forwarded_properties(path: trio.Path) -> None:
115
+ # use `name` as a representative of forwarded properties
116
+
117
+ assert "name" in dir(path)
118
+ assert path.name == "test"
119
+
120
+
121
+ def test_async_method_signature(path: trio.Path) -> None:
122
+ # use `resolve` as a representative of wrapped methods
123
+
124
+ assert path.resolve.__name__ == "resolve"
125
+ assert path.resolve.__qualname__ == "Path.resolve"
126
+
127
+ assert path.resolve.__doc__ is not None
128
+ assert path.resolve.__qualname__ in path.resolve.__doc__
129
+
130
+
131
+ @pytest.mark.parametrize("method_name", ["is_dir", "is_file"])
132
+ async def test_compare_async_stat_methods(method_name: str) -> None:
133
+ method, async_method = method_pair(".", method_name)
134
+
135
+ result = method()
136
+ async_result = await async_method()
137
+
138
+ assert result == async_result
139
+
140
+
141
+ def test_invalid_name_not_wrapped(path: trio.Path) -> None:
142
+ with pytest.raises(AttributeError):
143
+ getattr(path, "invalid_fake_attr") # noqa: B009 # "get-attr-with-constant"
144
+
145
+
146
+ @pytest.mark.parametrize("method_name", ["absolute", "resolve"])
147
+ async def test_async_methods_rewrap(method_name: str) -> None:
148
+ method, async_method = method_pair(".", method_name)
149
+
150
+ result = method()
151
+ async_result = await async_method()
152
+
153
+ assert isinstance(async_result, trio.Path)
154
+ assert str(result) == str(async_result)
155
+
156
+
157
+ def test_forward_methods_rewrap(path: trio.Path, tmp_path: pathlib.Path) -> None:
158
+ with_name = path.with_name("foo")
159
+ with_suffix = path.with_suffix(".py")
160
+
161
+ assert isinstance(with_name, trio.Path)
162
+ assert with_name == tmp_path / "foo"
163
+ assert isinstance(with_suffix, trio.Path)
164
+ assert with_suffix == tmp_path / "test.py"
165
+
166
+
167
+ def test_forward_properties_rewrap(path: trio.Path) -> None:
168
+ assert isinstance(path.parent, trio.Path)
169
+
170
+
171
+ def test_forward_methods_without_rewrap(path: trio.Path) -> None:
172
+ assert "totally-unique-path" in str(path.joinpath("totally-unique-path"))
173
+
174
+
175
+ def test_repr() -> None:
176
+ path = trio.Path(".")
177
+
178
+ assert repr(path) == "trio.Path('.')"
179
+
180
+
181
+ @pytest.mark.parametrize("meth", [trio.Path.__init__, trio.Path.joinpath])
182
+ async def test_path_wraps_path(
183
+ path: trio.Path,
184
+ meth: Callable[[trio.Path, trio.Path], object],
185
+ ) -> None:
186
+ wrapped = await path.absolute()
187
+ result = meth(path, wrapped)
188
+ if result is None:
189
+ result = path
190
+
191
+ assert wrapped == result
192
+
193
+
194
+ def test_path_nonpath() -> None:
195
+ with pytest.raises(TypeError):
196
+ trio.Path(1) # type: ignore
197
+
198
+
199
+ async def test_open_file_can_open_path(path: trio.Path) -> None:
200
+ async with await trio.open_file(path, "w") as f:
201
+ assert f.name == os.fspath(path)
202
+
203
+
204
+ async def test_globmethods(path: trio.Path) -> None:
205
+ # Populate a directory tree
206
+ await path.mkdir()
207
+ await (path / "foo").mkdir()
208
+ await (path / "foo" / "_bar.txt").write_bytes(b"")
209
+ await (path / "bar.txt").write_bytes(b"")
210
+ await (path / "bar.dat").write_bytes(b"")
211
+
212
+ # Path.glob
213
+ for pattern, results in {
214
+ "*.txt": {"bar.txt"},
215
+ "**/*.txt": {"_bar.txt", "bar.txt"},
216
+ }.items():
217
+ entries = set()
218
+ for entry in await path.glob(pattern):
219
+ assert isinstance(entry, trio.Path)
220
+ entries.add(entry.name)
221
+
222
+ assert entries == results
223
+
224
+ # Path.rglob
225
+ entries = set()
226
+ for entry in await path.rglob("*.txt"):
227
+ assert isinstance(entry, trio.Path)
228
+ entries.add(entry.name)
229
+
230
+ assert entries == {"_bar.txt", "bar.txt"}
231
+
232
+
233
+ async def test_as_uri(path: trio.Path) -> None:
234
+ path = await path.parent.resolve()
235
+
236
+ assert path.as_uri().startswith("file:///")
237
+
238
+
239
+ async def test_iterdir(path: trio.Path) -> None:
240
+ # Populate a directory
241
+ await path.mkdir()
242
+ await (path / "foo").mkdir()
243
+ await (path / "bar.txt").write_bytes(b"")
244
+
245
+ entries = set()
246
+ for entry in await path.iterdir():
247
+ assert isinstance(entry, trio.Path)
248
+ entries.add(entry.name)
249
+
250
+ assert entries == {"bar.txt", "foo"}
251
+
252
+
253
+ async def test_classmethods() -> None:
254
+ assert isinstance(await trio.Path.home(), trio.Path)
255
+
256
+ # pathlib.Path has only two classmethods
257
+ assert str(await trio.Path.home()) == os.path.expanduser("~") # noqa: ASYNC240
258
+ assert str(await trio.Path.cwd()) == os.getcwd()
259
+
260
+ # Wrapped method has docstring
261
+ assert trio.Path.home.__doc__
262
+
263
+
264
+ @pytest.mark.parametrize(
265
+ "wrapper",
266
+ [
267
+ trio._path._wraps_async,
268
+ trio._path._wrap_method,
269
+ trio._path._wrap_method_path,
270
+ trio._path._wrap_method_path_iterable,
271
+ ],
272
+ )
273
+ def test_wrapping_without_docstrings(
274
+ wrapper: Callable[[Callable[[], None]], Callable[[], None]],
275
+ ) -> None:
276
+ @wrapper
277
+ def func_without_docstring() -> None: ... # pragma: no cover
278
+
279
+ assert func_without_docstring.__doc__ is None