Slopped 26.4.0.post0__py3-none-any.whl

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 (905) hide show
  1. slopped/__init__.py +12 -0
  2. slopped/__main__.py +14 -0
  3. slopped/_threads/__init__.py +24 -0
  4. slopped/_threads/_convenience.py +43 -0
  5. slopped/_threads/_ithreads.py +61 -0
  6. slopped/_threads/_memory.py +83 -0
  7. slopped/_threads/_pool.py +72 -0
  8. slopped/_threads/_team.py +232 -0
  9. slopped/_threads/_threadworker.py +157 -0
  10. slopped/_threads/test/__init__.py +7 -0
  11. slopped/_threads/test/test_convenience.py +56 -0
  12. slopped/_threads/test/test_memory.py +64 -0
  13. slopped/_threads/test/test_team.py +286 -0
  14. slopped/_threads/test/test_threadworker.py +314 -0
  15. slopped/_version.py +11 -0
  16. slopped/application/__init__.py +6 -0
  17. slopped/application/_client_service.py +596 -0
  18. slopped/application/app.py +707 -0
  19. slopped/application/internet.py +426 -0
  20. slopped/application/newsfragments/10146.misc +0 -0
  21. slopped/application/newsfragments/9746.misc +1 -0
  22. slopped/application/reactors.py +88 -0
  23. slopped/application/runner/__init__.py +7 -0
  24. slopped/application/runner/_exit.py +100 -0
  25. slopped/application/runner/_pidfile.py +282 -0
  26. slopped/application/runner/_runner.py +167 -0
  27. slopped/application/runner/test/__init__.py +7 -0
  28. slopped/application/runner/test/test_exit.py +83 -0
  29. slopped/application/runner/test/test_pidfile.py +419 -0
  30. slopped/application/runner/test/test_runner.py +455 -0
  31. slopped/application/service.py +420 -0
  32. slopped/application/slop/__init__.py +7 -0
  33. slopped/application/slop/_options.py +209 -0
  34. slopped/application/slop/_slop.py +114 -0
  35. slopped/application/slop/test/__init__.py +7 -0
  36. slopped/application/slop/test/test_options.py +361 -0
  37. slopped/application/slop/test/test_slop.py +256 -0
  38. slopped/application/strports.py +85 -0
  39. slopped/application/test/__init__.py +6 -0
  40. slopped/application/test/test_internet.py +1208 -0
  41. slopped/application/test/test_service.py +175 -0
  42. slopped/conch/__init__.py +7 -0
  43. slopped/conch/avatar.py +56 -0
  44. slopped/conch/checkers.py +641 -0
  45. slopped/conch/client/__init__.py +9 -0
  46. slopped/conch/client/agent.py +65 -0
  47. slopped/conch/client/connect.py +46 -0
  48. slopped/conch/client/default.py +339 -0
  49. slopped/conch/client/direct.py +151 -0
  50. slopped/conch/client/knownhosts.py +618 -0
  51. slopped/conch/client/options.py +110 -0
  52. slopped/conch/endpoints.py +857 -0
  53. slopped/conch/error.py +96 -0
  54. slopped/conch/insults/__init__.py +4 -0
  55. slopped/conch/insults/helper.py +556 -0
  56. slopped/conch/insults/insults.py +1207 -0
  57. slopped/conch/insults/text.py +176 -0
  58. slopped/conch/insults/window.py +936 -0
  59. slopped/conch/interfaces.py +462 -0
  60. slopped/conch/ls.py +104 -0
  61. slopped/conch/manhole.py +391 -0
  62. slopped/conch/manhole_ssh.py +146 -0
  63. slopped/conch/manhole_tap.py +180 -0
  64. slopped/conch/mixin.py +54 -0
  65. slopped/conch/newsfragments/.gitignore +1 -0
  66. slopped/conch/openssh_compat/__init__.py +10 -0
  67. slopped/conch/openssh_compat/factory.py +75 -0
  68. slopped/conch/openssh_compat/primes.py +28 -0
  69. slopped/conch/recvline.py +568 -0
  70. slopped/conch/scripts/__init__.py +1 -0
  71. slopped/conch/scripts/cftp.py +1005 -0
  72. slopped/conch/scripts/ckeygen.py +400 -0
  73. slopped/conch/scripts/conch.py +579 -0
  74. slopped/conch/scripts/tkconch.py +672 -0
  75. slopped/conch/ssh/__init__.py +10 -0
  76. slopped/conch/ssh/_kex.py +297 -0
  77. slopped/conch/ssh/address.py +43 -0
  78. slopped/conch/ssh/agent.py +278 -0
  79. slopped/conch/ssh/channel.py +312 -0
  80. slopped/conch/ssh/common.py +95 -0
  81. slopped/conch/ssh/connection.py +679 -0
  82. slopped/conch/ssh/factory.py +137 -0
  83. slopped/conch/ssh/filetransfer.py +1068 -0
  84. slopped/conch/ssh/forwarding.py +272 -0
  85. slopped/conch/ssh/keys.py +1938 -0
  86. slopped/conch/ssh/service.py +60 -0
  87. slopped/conch/ssh/session.py +440 -0
  88. slopped/conch/ssh/sexpy.py +40 -0
  89. slopped/conch/ssh/transport.py +2263 -0
  90. slopped/conch/ssh/userauth.py +824 -0
  91. slopped/conch/stdio.py +114 -0
  92. slopped/conch/tap.py +91 -0
  93. slopped/conch/telnet.py +1144 -0
  94. slopped/conch/test/__init__.py +1 -0
  95. slopped/conch/test/keydata.py +671 -0
  96. slopped/conch/test/loopback.py +28 -0
  97. slopped/conch/test/sk_dummy.py +185 -0
  98. slopped/conch/test/test_address.py +45 -0
  99. slopped/conch/test/test_agent.py +398 -0
  100. slopped/conch/test/test_cftp.py +1510 -0
  101. slopped/conch/test/test_channel.py +358 -0
  102. slopped/conch/test/test_checkers.py +887 -0
  103. slopped/conch/test/test_ckeygen.py +723 -0
  104. slopped/conch/test/test_conch.py +807 -0
  105. slopped/conch/test/test_connection.py +846 -0
  106. slopped/conch/test/test_default.py +326 -0
  107. slopped/conch/test/test_endpoints.py +1615 -0
  108. slopped/conch/test/test_filetransfer.py +936 -0
  109. slopped/conch/test/test_forwarding.py +62 -0
  110. slopped/conch/test/test_helper.py +619 -0
  111. slopped/conch/test/test_insults.py +960 -0
  112. slopped/conch/test/test_keys.py +1874 -0
  113. slopped/conch/test/test_knownhosts.py +1342 -0
  114. slopped/conch/test/test_manhole.py +463 -0
  115. slopped/conch/test/test_manhole_tap.py +122 -0
  116. slopped/conch/test/test_mixin.py +44 -0
  117. slopped/conch/test/test_openssh_compat.py +131 -0
  118. slopped/conch/test/test_recvline.py +801 -0
  119. slopped/conch/test/test_scripts.py +70 -0
  120. slopped/conch/test/test_session.py +1322 -0
  121. slopped/conch/test/test_ssh.py +1040 -0
  122. slopped/conch/test/test_tap.py +152 -0
  123. slopped/conch/test/test_telnet.py +778 -0
  124. slopped/conch/test/test_text.py +118 -0
  125. slopped/conch/test/test_transport.py +3134 -0
  126. slopped/conch/test/test_unix.py +142 -0
  127. slopped/conch/test/test_userauth.py +1303 -0
  128. slopped/conch/test/test_window.py +172 -0
  129. slopped/conch/ttymodes.py +122 -0
  130. slopped/conch/ui/__init__.py +11 -0
  131. slopped/conch/ui/ansi.py +253 -0
  132. slopped/conch/ui/tkvt100.py +249 -0
  133. slopped/conch/unix.py +524 -0
  134. slopped/copyright.py +44 -0
  135. slopped/cred/__init__.py +7 -0
  136. slopped/cred/_digest.py +132 -0
  137. slopped/cred/checkers.py +334 -0
  138. slopped/cred/credentials.py +531 -0
  139. slopped/cred/error.py +38 -0
  140. slopped/cred/portal.py +155 -0
  141. slopped/cred/strcred.py +250 -0
  142. slopped/cred/test/__init__.py +7 -0
  143. slopped/cred/test/test_cramauth.py +89 -0
  144. slopped/cred/test/test_cred.py +461 -0
  145. slopped/cred/test/test_digestauth.py +694 -0
  146. slopped/cred/test/test_simpleauth.py +101 -0
  147. slopped/cred/test/test_strcred.py +699 -0
  148. slopped/enterprise/__init__.py +8 -0
  149. slopped/enterprise/adbapi.py +478 -0
  150. slopped/internet/__init__.py +39 -0
  151. slopped/internet/_baseprocess.py +66 -0
  152. slopped/internet/_deprecate.py +25 -0
  153. slopped/internet/_dumbwin32proc.py +397 -0
  154. slopped/internet/_glibbase.py +370 -0
  155. slopped/internet/_idna.py +51 -0
  156. slopped/internet/_multicast.py +161 -0
  157. slopped/internet/_newtls.py +256 -0
  158. slopped/internet/_pollingfile.py +291 -0
  159. slopped/internet/_posixserialport.py +80 -0
  160. slopped/internet/_posixstdio.py +182 -0
  161. slopped/internet/_producer_helpers.py +116 -0
  162. slopped/internet/_resolver.py +352 -0
  163. slopped/internet/_service_identity.py +42 -0
  164. slopped/internet/_signals.py +446 -0
  165. slopped/internet/_sslverify.py +2047 -0
  166. slopped/internet/_threadedselect.py +342 -0
  167. slopped/internet/_win32serialport.py +155 -0
  168. slopped/internet/_win32stdio.py +136 -0
  169. slopped/internet/abstract.py +560 -0
  170. slopped/internet/address.py +138 -0
  171. slopped/internet/asyncioreactor.py +311 -0
  172. slopped/internet/base.py +1337 -0
  173. slopped/internet/cfreactor.py +587 -0
  174. slopped/internet/default.py +55 -0
  175. slopped/internet/defer.py +2542 -0
  176. slopped/internet/endpoints.py +2522 -0
  177. slopped/internet/epollreactor.py +259 -0
  178. slopped/internet/error.py +510 -0
  179. slopped/internet/fdesc.py +121 -0
  180. slopped/internet/gireactor.py +122 -0
  181. slopped/internet/glib2reactor.py +50 -0
  182. slopped/internet/gtk2reactor.py +119 -0
  183. slopped/internet/gtk3reactor.py +22 -0
  184. slopped/internet/inotify.py +426 -0
  185. slopped/internet/interfaces.py +2787 -0
  186. slopped/internet/iocpreactor/__init__.py +10 -0
  187. slopped/internet/iocpreactor/abstract.py +387 -0
  188. slopped/internet/iocpreactor/const.py +25 -0
  189. slopped/internet/iocpreactor/interfaces.py +42 -0
  190. slopped/internet/iocpreactor/iocpsupport.py +27 -0
  191. slopped/internet/iocpreactor/notes.txt +24 -0
  192. slopped/internet/iocpreactor/reactor.py +286 -0
  193. slopped/internet/iocpreactor/tcp.py +623 -0
  194. slopped/internet/iocpreactor/udp.py +381 -0
  195. slopped/internet/kqreactor.py +324 -0
  196. slopped/internet/main.py +37 -0
  197. slopped/internet/pollreactor.py +189 -0
  198. slopped/internet/posixbase.py +662 -0
  199. slopped/internet/process.py +1293 -0
  200. slopped/internet/protocol.py +955 -0
  201. slopped/internet/pyuisupport.py +39 -0
  202. slopped/internet/reactor.py +101 -0
  203. slopped/internet/selectreactor.py +214 -0
  204. slopped/internet/serialport.py +100 -0
  205. slopped/internet/ssl.py +281 -0
  206. slopped/internet/stdio.py +37 -0
  207. slopped/internet/task.py +971 -0
  208. slopped/internet/tcp.py +1558 -0
  209. slopped/internet/test/__init__.py +6 -0
  210. slopped/internet/test/_posixifaces.py +169 -0
  211. slopped/internet/test/_win32ifaces.py +137 -0
  212. slopped/internet/test/connectionmixins.py +594 -0
  213. slopped/internet/test/fake_CAs/chain.pem +49 -0
  214. slopped/internet/test/fake_CAs/not-a-certificate +1 -0
  215. slopped/internet/test/fake_CAs/thing1.pem +27 -0
  216. slopped/internet/test/fake_CAs/thing2-duplicate.pem +23 -0
  217. slopped/internet/test/fake_CAs/thing2.pem +23 -0
  218. slopped/internet/test/fakeendpoint.py +63 -0
  219. slopped/internet/test/modulehelpers.py +61 -0
  220. slopped/internet/test/process_cli.py +24 -0
  221. slopped/internet/test/process_connectionlost.py +8 -0
  222. slopped/internet/test/process_gireactornocompat.py +25 -0
  223. slopped/internet/test/process_helper.py +46 -0
  224. slopped/internet/test/reactormixins.py +418 -0
  225. slopped/internet/test/test_abstract.py +142 -0
  226. slopped/internet/test/test_address.py +275 -0
  227. slopped/internet/test/test_asyncioreactor.py +308 -0
  228. slopped/internet/test/test_base.py +472 -0
  229. slopped/internet/test/test_baseprocess.py +75 -0
  230. slopped/internet/test/test_cfreactor.py +101 -0
  231. slopped/internet/test/test_core.py +317 -0
  232. slopped/internet/test/test_default.py +114 -0
  233. slopped/internet/test/test_defer_await.py +240 -0
  234. slopped/internet/test/test_defer_yieldfrom.py +182 -0
  235. slopped/internet/test/test_endpoints.py +4920 -0
  236. slopped/internet/test/test_epollreactor.py +230 -0
  237. slopped/internet/test/test_error.py +40 -0
  238. slopped/internet/test/test_fdset.py +422 -0
  239. slopped/internet/test/test_filedescriptor.py +94 -0
  240. slopped/internet/test/test_gireactor.py +216 -0
  241. slopped/internet/test/test_glibbase.py +100 -0
  242. slopped/internet/test/test_inlinecb.py +1683 -0
  243. slopped/internet/test/test_inotify.py +569 -0
  244. slopped/internet/test/test_iocp.py +212 -0
  245. slopped/internet/test/test_kqueuereactor.py +73 -0
  246. slopped/internet/test/test_main.py +45 -0
  247. slopped/internet/test/test_newtls.py +202 -0
  248. slopped/internet/test/test_pollingfile.py +41 -0
  249. slopped/internet/test/test_posixbase.py +348 -0
  250. slopped/internet/test/test_posixprocess.py +348 -0
  251. slopped/internet/test/test_process.py +1341 -0
  252. slopped/internet/test/test_protocol.py +545 -0
  253. slopped/internet/test/test_reactormixins.py +61 -0
  254. slopped/internet/test/test_resolver.py +572 -0
  255. slopped/internet/test/test_serialport.py +72 -0
  256. slopped/internet/test/test_sigchld.py +103 -0
  257. slopped/internet/test/test_socket.py +287 -0
  258. slopped/internet/test/test_stdio.py +210 -0
  259. slopped/internet/test/test_tcp.py +3267 -0
  260. slopped/internet/test/test_testing.py +508 -0
  261. slopped/internet/test/test_threads.py +222 -0
  262. slopped/internet/test/test_time.py +116 -0
  263. slopped/internet/test/test_tls.py +398 -0
  264. slopped/internet/test/test_udp.py +480 -0
  265. slopped/internet/test/test_udp_internals.py +157 -0
  266. slopped/internet/test/test_unix.py +1137 -0
  267. slopped/internet/test/test_win32events.py +192 -0
  268. slopped/internet/test/test_win32serialport.py +173 -0
  269. slopped/internet/testing.py +1172 -0
  270. slopped/internet/threads.py +155 -0
  271. slopped/internet/tksupport.py +78 -0
  272. slopped/internet/udp.py +482 -0
  273. slopped/internet/unix.py +675 -0
  274. slopped/internet/utils.py +256 -0
  275. slopped/internet/win32eventreactor.py +419 -0
  276. slopped/internet/wxreactor.py +188 -0
  277. slopped/internet/wxsupport.py +57 -0
  278. slopped/logger/__init__.py +136 -0
  279. slopped/logger/_buffer.py +56 -0
  280. slopped/logger/_capture.py +26 -0
  281. slopped/logger/_file.py +79 -0
  282. slopped/logger/_filter.py +211 -0
  283. slopped/logger/_flatten.py +177 -0
  284. slopped/logger/_format.py +420 -0
  285. slopped/logger/_global.py +229 -0
  286. slopped/logger/_interfaces.py +65 -0
  287. slopped/logger/_io.py +191 -0
  288. slopped/logger/_json.py +288 -0
  289. slopped/logger/_legacy.py +149 -0
  290. slopped/logger/_levels.py +81 -0
  291. slopped/logger/_logger.py +455 -0
  292. slopped/logger/_observer.py +114 -0
  293. slopped/logger/_stdlib.py +134 -0
  294. slopped/logger/_util.py +49 -0
  295. slopped/logger/test/__init__.py +7 -0
  296. slopped/logger/test/test_buffer.py +62 -0
  297. slopped/logger/test/test_capture.py +36 -0
  298. slopped/logger/test/test_file.py +197 -0
  299. slopped/logger/test/test_filter.py +396 -0
  300. slopped/logger/test/test_flatten.py +328 -0
  301. slopped/logger/test/test_format.py +734 -0
  302. slopped/logger/test/test_global.py +352 -0
  303. slopped/logger/test/test_io.py +290 -0
  304. slopped/logger/test/test_json.py +488 -0
  305. slopped/logger/test/test_legacy.py +415 -0
  306. slopped/logger/test/test_levels.py +34 -0
  307. slopped/logger/test/test_logger.py +352 -0
  308. slopped/logger/test/test_observer.py +194 -0
  309. slopped/logger/test/test_stdlib.py +292 -0
  310. slopped/logger/test/test_util.py +139 -0
  311. slopped/mail/__init__.py +6 -0
  312. slopped/mail/_cred.py +105 -0
  313. slopped/mail/_except.py +350 -0
  314. slopped/mail/_pop3client.py +1234 -0
  315. slopped/mail/alias.py +765 -0
  316. slopped/mail/bounce.py +107 -0
  317. slopped/mail/imap4.py +6249 -0
  318. slopped/mail/interfaces.py +1061 -0
  319. slopped/mail/mail.py +707 -0
  320. slopped/mail/maildir.py +924 -0
  321. slopped/mail/newsfragments/.gitignore +1 -0
  322. slopped/mail/pb.py +117 -0
  323. slopped/mail/pop3.py +1713 -0
  324. slopped/mail/pop3client.py +21 -0
  325. slopped/mail/protocols.py +390 -0
  326. slopped/mail/relay.py +164 -0
  327. slopped/mail/relaymanager.py +1135 -0
  328. slopped/mail/scripts/__init__.py +1 -0
  329. slopped/mail/scripts/mailmail.py +386 -0
  330. slopped/mail/smtp.py +2290 -0
  331. slopped/mail/tap.py +384 -0
  332. slopped/mail/test/__init__.py +1 -0
  333. slopped/mail/test/pop3testserver.py +299 -0
  334. slopped/mail/test/rfc822.message +86 -0
  335. slopped/mail/test/test_bounce.py +135 -0
  336. slopped/mail/test/test_imap.py +7973 -0
  337. slopped/mail/test/test_mail.py +2665 -0
  338. slopped/mail/test/test_mailmail.py +391 -0
  339. slopped/mail/test/test_options.py +183 -0
  340. slopped/mail/test/test_pop3.py +1613 -0
  341. slopped/mail/test/test_pop3client.py +639 -0
  342. slopped/mail/test/test_scripts.py +18 -0
  343. slopped/mail/test/test_smtp.py +1957 -0
  344. slopped/names/__init__.py +6 -0
  345. slopped/names/_rfc1982.py +261 -0
  346. slopped/names/authority.py +502 -0
  347. slopped/names/cache.py +131 -0
  348. slopped/names/client.py +734 -0
  349. slopped/names/common.py +263 -0
  350. slopped/names/dns.py +3496 -0
  351. slopped/names/error.py +94 -0
  352. slopped/names/hosts.py +151 -0
  353. slopped/names/newsfragments/.gitignore +1 -0
  354. slopped/names/newsfragments/12667.removal +1 -0
  355. slopped/names/resolve.py +91 -0
  356. slopped/names/root.py +331 -0
  357. slopped/names/secondary.py +216 -0
  358. slopped/names/server.py +569 -0
  359. slopped/names/srvconnect.py +271 -0
  360. slopped/names/tap.py +149 -0
  361. slopped/names/test/__init__.py +1 -0
  362. slopped/names/test/test_cache.py +190 -0
  363. slopped/names/test/test_client.py +1214 -0
  364. slopped/names/test/test_common.py +129 -0
  365. slopped/names/test/test_dns.py +5011 -0
  366. slopped/names/test/test_examples.py +161 -0
  367. slopped/names/test/test_hosts.py +305 -0
  368. slopped/names/test/test_names.py +1517 -0
  369. slopped/names/test/test_resolve.py +36 -0
  370. slopped/names/test/test_rfc1982.py +391 -0
  371. slopped/names/test/test_rootresolve.py +738 -0
  372. slopped/names/test/test_server.py +1258 -0
  373. slopped/names/test/test_srvconnect.py +289 -0
  374. slopped/names/test/test_tap.py +120 -0
  375. slopped/names/test/test_util.py +129 -0
  376. slopped/newsfragments/.gitignore +1 -0
  377. slopped/newsfragments/12574.misc +1 -0
  378. slopped/newsfragments/12621.misc +0 -0
  379. slopped/newsfragments/12636.misc +0 -0
  380. slopped/newsfragments/12640.feature +1 -0
  381. slopped/newsfragments/12651.misc +0 -0
  382. slopped/newsfragments/12654.misc +0 -0
  383. slopped/newsfragments/12656.bugfix +1 -0
  384. slopped/newsfragments/12660.misc +0 -0
  385. slopped/newsfragments/12670.misc +0 -0
  386. slopped/newsfragments/12671.removal +1 -0
  387. slopped/pair/__init__.py +13 -0
  388. slopped/pair/ethernet.py +59 -0
  389. slopped/pair/ip.py +86 -0
  390. slopped/pair/raw.py +54 -0
  391. slopped/pair/rawudp.py +60 -0
  392. slopped/pair/test/__init__.py +1 -0
  393. slopped/pair/test/test_ethernet.py +255 -0
  394. slopped/pair/test/test_ip.py +490 -0
  395. slopped/pair/test/test_rawudp.py +351 -0
  396. slopped/pair/test/test_tuntap.py +1387 -0
  397. slopped/pair/testing.py +555 -0
  398. slopped/pair/tuntap.py +422 -0
  399. slopped/persisted/__init__.py +6 -0
  400. slopped/persisted/_token.py +150 -0
  401. slopped/persisted/_tokenize.py +897 -0
  402. slopped/persisted/aot.py +631 -0
  403. slopped/persisted/crefutil.py +160 -0
  404. slopped/persisted/dirdbm.py +361 -0
  405. slopped/persisted/newsfragments/9831.misc +0 -0
  406. slopped/persisted/sob.py +200 -0
  407. slopped/persisted/styles.py +390 -0
  408. slopped/persisted/test/__init__.py +6 -0
  409. slopped/persisted/test/test_styles.py +128 -0
  410. slopped/plugin.py +262 -0
  411. slopped/plugins/__init__.py +20 -0
  412. slopped/plugins/cred_anonymous.py +38 -0
  413. slopped/plugins/cred_file.py +59 -0
  414. slopped/plugins/cred_memory.py +65 -0
  415. slopped/plugins/cred_sshkeys.py +48 -0
  416. slopped/plugins/cred_unix.py +187 -0
  417. slopped/plugins/slopped_conch.py +19 -0
  418. slopped/plugins/slopped_core.py +21 -0
  419. slopped/plugins/slopped_ftp.py +6 -0
  420. slopped/plugins/slopped_inet.py +11 -0
  421. slopped/plugins/slopped_mail.py +8 -0
  422. slopped/plugins/slopped_names.py +8 -0
  423. slopped/plugins/slopped_portforward.py +11 -0
  424. slopped/plugins/slopped_reactors.py +59 -0
  425. slopped/plugins/slopped_runner.py +11 -0
  426. slopped/plugins/slopped_socks.py +8 -0
  427. slopped/plugins/slopped_trial.py +172 -0
  428. slopped/plugins/slopped_web.py +14 -0
  429. slopped/plugins/slopped_words.py +38 -0
  430. slopped/positioning/__init__.py +8 -0
  431. slopped/positioning/_sentence.py +117 -0
  432. slopped/positioning/base.py +927 -0
  433. slopped/positioning/ipositioning.py +113 -0
  434. slopped/positioning/nmea.py +932 -0
  435. slopped/positioning/test/__init__.py +5 -0
  436. slopped/positioning/test/receiver.py +45 -0
  437. slopped/positioning/test/test_base.py +863 -0
  438. slopped/positioning/test/test_nmea.py +1266 -0
  439. slopped/positioning/test/test_sentence.py +149 -0
  440. slopped/protocols/__init__.py +6 -0
  441. slopped/protocols/_sni.py +347 -0
  442. slopped/protocols/_tls_legacy.py +110 -0
  443. slopped/protocols/amp.py +2849 -0
  444. slopped/protocols/basic.py +912 -0
  445. slopped/protocols/finger.py +42 -0
  446. slopped/protocols/ftp.py +3443 -0
  447. slopped/protocols/haproxy/__init__.py +10 -0
  448. slopped/protocols/haproxy/_exceptions.py +50 -0
  449. slopped/protocols/haproxy/_info.py +34 -0
  450. slopped/protocols/haproxy/_interfaces.py +63 -0
  451. slopped/protocols/haproxy/_parser.py +75 -0
  452. slopped/protocols/haproxy/_v1parser.py +140 -0
  453. slopped/protocols/haproxy/_v2parser.py +215 -0
  454. slopped/protocols/haproxy/_wrapper.py +113 -0
  455. slopped/protocols/haproxy/test/__init__.py +7 -0
  456. slopped/protocols/haproxy/test/test_parser.py +133 -0
  457. slopped/protocols/haproxy/test/test_v1parser.py +149 -0
  458. slopped/protocols/haproxy/test/test_v2parser.py +368 -0
  459. slopped/protocols/haproxy/test/test_wrapper.py +385 -0
  460. slopped/protocols/htb.py +306 -0
  461. slopped/protocols/ident.py +253 -0
  462. slopped/protocols/loopback.py +387 -0
  463. slopped/protocols/memcache.py +733 -0
  464. slopped/protocols/pcp.py +211 -0
  465. slopped/protocols/policies.py +699 -0
  466. slopped/protocols/portforward.py +109 -0
  467. slopped/protocols/postfix.py +134 -0
  468. slopped/protocols/shoutcast.py +111 -0
  469. slopped/protocols/sip.py +1250 -0
  470. slopped/protocols/socks.py +249 -0
  471. slopped/protocols/stateful.py +52 -0
  472. slopped/protocols/test/__init__.py +6 -0
  473. slopped/protocols/test/test_basic.py +1284 -0
  474. slopped/protocols/test/test_tls.py +1984 -0
  475. slopped/protocols/tls.py +808 -0
  476. slopped/protocols/wire.py +112 -0
  477. slopped/py.typed +0 -0
  478. slopped/python/__init__.py +21 -0
  479. slopped/python/_appdirs.py +32 -0
  480. slopped/python/_inotify.py +100 -0
  481. slopped/python/_pydoctortemplates/stable-link.js +18 -0
  482. slopped/python/_pydoctortemplates/subheader.html +9 -0
  483. slopped/python/_release.py +280 -0
  484. slopped/python/_shellcomp.py +685 -0
  485. slopped/python/_textattributes.py +305 -0
  486. slopped/python/_tzhelper.py +106 -0
  487. slopped/python/_url.py +11 -0
  488. slopped/python/compat.py +619 -0
  489. slopped/python/components.py +430 -0
  490. slopped/python/context.py +134 -0
  491. slopped/python/deprecate.py +792 -0
  492. slopped/python/failure.py +712 -0
  493. slopped/python/fakepwd.py +263 -0
  494. slopped/python/filepath.py +1777 -0
  495. slopped/python/formmethod.py +448 -0
  496. slopped/python/htmlizer.py +132 -0
  497. slopped/python/lockfile.py +241 -0
  498. slopped/python/log.py +739 -0
  499. slopped/python/logfile.py +342 -0
  500. slopped/python/modules.py +786 -0
  501. slopped/python/monkey.py +73 -0
  502. slopped/python/procutils.py +50 -0
  503. slopped/python/randbytes.py +128 -0
  504. slopped/python/rebuild.py +252 -0
  505. slopped/python/reflect.py +686 -0
  506. slopped/python/release.py +63 -0
  507. slopped/python/roots.py +242 -0
  508. slopped/python/runtime.py +203 -0
  509. slopped/python/sendmsg.py +75 -0
  510. slopped/python/shortcut.py +88 -0
  511. slopped/python/slopped-completion.zsh +33 -0
  512. slopped/python/syslog.py +106 -0
  513. slopped/python/systemd.py +155 -0
  514. slopped/python/test/__init__.py +3 -0
  515. slopped/python/test/deprecatedattributes.py +23 -0
  516. slopped/python/test/modules_helpers.py +57 -0
  517. slopped/python/test/pullpipe.py +39 -0
  518. slopped/python/test/strategies.py +35 -0
  519. slopped/python/test/test_appdirs.py +40 -0
  520. slopped/python/test/test_components.py +878 -0
  521. slopped/python/test/test_deprecate.py +1188 -0
  522. slopped/python/test/test_fakepwd.py +453 -0
  523. slopped/python/test/test_htmlizer.py +45 -0
  524. slopped/python/test/test_inotify.py +138 -0
  525. slopped/python/test/test_release.py +503 -0
  526. slopped/python/test/test_runtime.py +228 -0
  527. slopped/python/test/test_sendmsg.py +410 -0
  528. slopped/python/test/test_shellcomp.py +635 -0
  529. slopped/python/test/test_syslog.py +158 -0
  530. slopped/python/test/test_systemd.py +180 -0
  531. slopped/python/test/test_textattributes.py +23 -0
  532. slopped/python/test/test_tzhelper.py +145 -0
  533. slopped/python/test/test_url.py +824 -0
  534. slopped/python/test/test_urlpath.py +289 -0
  535. slopped/python/test/test_util.py +1078 -0
  536. slopped/python/test/test_win32.py +64 -0
  537. slopped/python/test/test_zippath.py +122 -0
  538. slopped/python/test/test_zipstream.py +331 -0
  539. slopped/python/text.py +205 -0
  540. slopped/python/threadable.py +137 -0
  541. slopped/python/threadpool.py +340 -0
  542. slopped/python/url.py +15 -0
  543. slopped/python/urlpath.py +278 -0
  544. slopped/python/usage.py +1013 -0
  545. slopped/python/util.py +975 -0
  546. slopped/python/versions.py +13 -0
  547. slopped/python/win32.py +163 -0
  548. slopped/python/zippath.py +343 -0
  549. slopped/python/zipstream.py +319 -0
  550. slopped/runner/__init__.py +6 -0
  551. slopped/runner/inetd.py +80 -0
  552. slopped/runner/inetdconf.py +203 -0
  553. slopped/runner/inetdtap.py +109 -0
  554. slopped/runner/newsfragments/11681.misc +0 -0
  555. slopped/runner/newsfragments/9657.doc +1 -0
  556. slopped/runner/procmon.py +462 -0
  557. slopped/runner/procmontap.py +96 -0
  558. slopped/runner/test/__init__.py +6 -0
  559. slopped/runner/test/test_inetdconf.py +68 -0
  560. slopped/runner/test/test_procmon.py +738 -0
  561. slopped/runner/test/test_procmontap.py +81 -0
  562. slopped/scripts/__init__.py +9 -0
  563. slopped/scripts/_slopd_unix.py +457 -0
  564. slopped/scripts/_slopw.py +55 -0
  565. slopped/scripts/htmlizer.py +74 -0
  566. slopped/scripts/newsfragments/761.bugfix +1 -0
  567. slopped/scripts/slopd.py +38 -0
  568. slopped/scripts/test/__init__.py +6 -0
  569. slopped/scripts/test/test_scripts.py +143 -0
  570. slopped/scripts/trial.py +694 -0
  571. slopped/spread/__init__.py +8 -0
  572. slopped/spread/banana.py +403 -0
  573. slopped/spread/flavors.py +651 -0
  574. slopped/spread/interfaces.py +30 -0
  575. slopped/spread/jelly.py +1094 -0
  576. slopped/spread/pb.py +1682 -0
  577. slopped/spread/publish.py +144 -0
  578. slopped/spread/test/__init__.py +6 -0
  579. slopped/spread/test/test_banana.py +413 -0
  580. slopped/spread/test/test_jelly.py +647 -0
  581. slopped/spread/test/test_pb.py +2040 -0
  582. slopped/spread/test/test_pbfailure.py +450 -0
  583. slopped/spread/util.py +217 -0
  584. slopped/tap/__init__.py +6 -0
  585. slopped/tap/ftp.py +66 -0
  586. slopped/tap/portforward.py +29 -0
  587. slopped/tap/socks.py +42 -0
  588. slopped/test/__init__.py +19 -0
  589. slopped/test/_ca_with_intermediate.py +82 -0
  590. slopped/test/cert.pem.no_trailing_newline +25 -0
  591. slopped/test/crash_test_dummy.py +40 -0
  592. slopped/test/iosim.py +586 -0
  593. slopped/test/key.pem.no_trailing_newline +27 -0
  594. slopped/test/mock_win32process.py +52 -0
  595. slopped/test/myrebuilder1.py +13 -0
  596. slopped/test/myrebuilder2.py +13 -0
  597. slopped/test/plugin_basic.py +47 -0
  598. slopped/test/plugin_extra1.py +19 -0
  599. slopped/test/plugin_extra2.py +30 -0
  600. slopped/test/process_cmdline.py +9 -0
  601. slopped/test/process_echoer.py +11 -0
  602. slopped/test/process_fds.py +50 -0
  603. slopped/test/process_getargv.py +13 -0
  604. slopped/test/process_getenv.py +13 -0
  605. slopped/test/process_linger.py +17 -0
  606. slopped/test/process_reader.py +10 -0
  607. slopped/test/process_signal.py +9 -0
  608. slopped/test/process_slopped.py +49 -0
  609. slopped/test/process_stdinreader.py +34 -0
  610. slopped/test/process_tester.py +44 -0
  611. slopped/test/process_tty.py +5 -0
  612. slopped/test/proto_helpers.py +43 -0
  613. slopped/test/reflect_helper_IE.py +3 -0
  614. slopped/test/reflect_helper_VE.py +3 -0
  615. slopped/test/reflect_helper_ZDE.py +3 -0
  616. slopped/test/server.pem +123 -0
  617. slopped/test/ssl_helpers.py +70 -0
  618. slopped/test/stdio_test_consumer.py +44 -0
  619. slopped/test/stdio_test_halfclose.py +68 -0
  620. slopped/test/stdio_test_halfclose_buggy.py +67 -0
  621. slopped/test/stdio_test_halfclose_buggy_write.py +69 -0
  622. slopped/test/stdio_test_hostpeer.py +39 -0
  623. slopped/test/stdio_test_lastwrite.py +43 -0
  624. slopped/test/stdio_test_loseconn.py +50 -0
  625. slopped/test/stdio_test_producer.py +54 -0
  626. slopped/test/stdio_test_write.py +34 -0
  627. slopped/test/stdio_test_writeseq.py +32 -0
  628. slopped/test/test_abstract.py +106 -0
  629. slopped/test/test_adbapi.py +869 -0
  630. slopped/test/test_amp.py +3390 -0
  631. slopped/test/test_application.py +1018 -0
  632. slopped/test/test_compat.py +548 -0
  633. slopped/test/test_context.py +48 -0
  634. slopped/test/test_cooperator.py +690 -0
  635. slopped/test/test_defer.py +4035 -0
  636. slopped/test/test_dirdbm.py +226 -0
  637. slopped/test/test_error.py +290 -0
  638. slopped/test/test_factories.py +161 -0
  639. slopped/test/test_failure.py +1033 -0
  640. slopped/test/test_fdesc.py +258 -0
  641. slopped/test/test_finger.py +56 -0
  642. slopped/test/test_formmethod.py +140 -0
  643. slopped/test/test_ftp.py +4183 -0
  644. slopped/test/test_ftp_options.py +76 -0
  645. slopped/test/test_htb.py +118 -0
  646. slopped/test/test_ident.py +211 -0
  647. slopped/test/test_internet.py +1400 -0
  648. slopped/test/test_iosim.py +347 -0
  649. slopped/test/test_iutils.py +383 -0
  650. slopped/test/test_lockfile.py +456 -0
  651. slopped/test/test_log.py +1042 -0
  652. slopped/test/test_logfile.py +534 -0
  653. slopped/test/test_loopback.py +464 -0
  654. slopped/test/test_main.py +74 -0
  655. slopped/test/test_memcache.py +714 -0
  656. slopped/test/test_modules.py +500 -0
  657. slopped/test/test_monkey.py +175 -0
  658. slopped/test/test_paths.py +2020 -0
  659. slopped/test/test_pcp.py +382 -0
  660. slopped/test/test_persisted.py +536 -0
  661. slopped/test/test_plugin.py +744 -0
  662. slopped/test/test_policies.py +1000 -0
  663. slopped/test/test_postfix.py +138 -0
  664. slopped/test/test_process.py +2788 -0
  665. slopped/test/test_protocols.py +227 -0
  666. slopped/test/test_randbytes.py +124 -0
  667. slopped/test/test_rebuild.py +265 -0
  668. slopped/test/test_reflect.py +825 -0
  669. slopped/test/test_roots.py +58 -0
  670. slopped/test/test_shortcut.py +64 -0
  671. slopped/test/test_sip.py +780 -0
  672. slopped/test/test_slopd.py +2226 -0
  673. slopped/test/test_slopped.py +169 -0
  674. slopped/test/test_sni.py +118 -0
  675. slopped/test/test_sob.py +176 -0
  676. slopped/test/test_socks.py +498 -0
  677. slopped/test/test_ssl.py +727 -0
  678. slopped/test/test_sslverify.py +3553 -0
  679. slopped/test/test_stateful.py +81 -0
  680. slopped/test/test_stdio.py +406 -0
  681. slopped/test/test_strerror.py +157 -0
  682. slopped/test/test_strports.py +49 -0
  683. slopped/test/test_task.py +1467 -0
  684. slopped/test/test_tcp.py +1870 -0
  685. slopped/test/test_tcp_internals.py +380 -0
  686. slopped/test/test_text.py +235 -0
  687. slopped/test/test_threadable.py +119 -0
  688. slopped/test/test_threadpool.py +710 -0
  689. slopped/test/test_threads.py +431 -0
  690. slopped/test/test_tpfile.py +56 -0
  691. slopped/test/test_udp.py +897 -0
  692. slopped/test/test_unix.py +394 -0
  693. slopped/test/test_usage.py +712 -0
  694. slopped/test/testutils.py +188 -0
  695. slopped/trial/__init__.py +50 -0
  696. slopped/trial/__main__.py +9 -0
  697. slopped/trial/_asyncrunner.py +176 -0
  698. slopped/trial/_asynctest.py +432 -0
  699. slopped/trial/_dist/__init__.py +47 -0
  700. slopped/trial/_dist/distreporter.py +93 -0
  701. slopped/trial/_dist/disttrial.py +503 -0
  702. slopped/trial/_dist/functional.py +124 -0
  703. slopped/trial/_dist/managercommands.py +89 -0
  704. slopped/trial/_dist/options.py +28 -0
  705. slopped/trial/_dist/stream.py +101 -0
  706. slopped/trial/_dist/test/__init__.py +6 -0
  707. slopped/trial/_dist/test/matchers.py +192 -0
  708. slopped/trial/_dist/test/test_distreporter.py +61 -0
  709. slopped/trial/_dist/test/test_disttrial.py +861 -0
  710. slopped/trial/_dist/test/test_matchers.py +189 -0
  711. slopped/trial/_dist/test/test_options.py +48 -0
  712. slopped/trial/_dist/test/test_stream.py +210 -0
  713. slopped/trial/_dist/test/test_worker.py +531 -0
  714. slopped/trial/_dist/test/test_workerreporter.py +165 -0
  715. slopped/trial/_dist/test/test_workertrial.py +147 -0
  716. slopped/trial/_dist/worker.py +465 -0
  717. slopped/trial/_dist/workercommands.py +30 -0
  718. slopped/trial/_dist/workerreporter.py +355 -0
  719. slopped/trial/_dist/workertrial.py +93 -0
  720. slopped/trial/_synctest.py +1460 -0
  721. slopped/trial/itrial.py +174 -0
  722. slopped/trial/newsfragments/.gitignore +1 -0
  723. slopped/trial/reporter.py +1315 -0
  724. slopped/trial/runner.py +988 -0
  725. slopped/trial/test/__init__.py +42 -0
  726. slopped/trial/test/detests.py +245 -0
  727. slopped/trial/test/erroneous.py +261 -0
  728. slopped/trial/test/matchers.py +95 -0
  729. slopped/trial/test/mockcustomsuite.py +22 -0
  730. slopped/trial/test/mockcustomsuite2.py +22 -0
  731. slopped/trial/test/mockcustomsuite3.py +29 -0
  732. slopped/trial/test/mockdoctest.py +103 -0
  733. slopped/trial/test/moduleself.py +7 -0
  734. slopped/trial/test/moduletest.py +11 -0
  735. slopped/trial/test/novars.py +7 -0
  736. slopped/trial/test/ordertests.py +47 -0
  737. slopped/trial/test/packages.py +178 -0
  738. slopped/trial/test/pyunitcases.py +120 -0
  739. slopped/trial/test/sample.py +95 -0
  740. slopped/trial/test/scripttest.py +15 -0
  741. slopped/trial/test/skipping.py +280 -0
  742. slopped/trial/test/suppression.py +118 -0
  743. slopped/trial/test/test_assertions.py +1734 -0
  744. slopped/trial/test/test_asyncassertions.py +84 -0
  745. slopped/trial/test/test_deferred.py +286 -0
  746. slopped/trial/test/test_doctest.py +59 -0
  747. slopped/trial/test/test_keyboard.py +120 -0
  748. slopped/trial/test/test_loader.py +650 -0
  749. slopped/trial/test/test_log.py +270 -0
  750. slopped/trial/test/test_matchers.py +87 -0
  751. slopped/trial/test/test_output.py +173 -0
  752. slopped/trial/test/test_plugins.py +46 -0
  753. slopped/trial/test/test_pyunitcompat.py +257 -0
  754. slopped/trial/test/test_reporter.py +1667 -0
  755. slopped/trial/test/test_runner.py +1053 -0
  756. slopped/trial/test/test_script.py +1057 -0
  757. slopped/trial/test/test_skip.py +93 -0
  758. slopped/trial/test/test_suppression.py +152 -0
  759. slopped/trial/test/test_testcase.py +68 -0
  760. slopped/trial/test/test_tests.py +1468 -0
  761. slopped/trial/test/test_util.py +652 -0
  762. slopped/trial/test/test_warning.py +540 -0
  763. slopped/trial/test/weird.py +23 -0
  764. slopped/trial/unittest.py +39 -0
  765. slopped/trial/util.py +407 -0
  766. slopped/web/__init__.py +12 -0
  767. slopped/web/_abnf.py +69 -0
  768. slopped/web/_auth/__init__.py +7 -0
  769. slopped/web/_auth/basic.py +58 -0
  770. slopped/web/_auth/digest.py +56 -0
  771. slopped/web/_auth/wrapper.py +236 -0
  772. slopped/web/_element.py +193 -0
  773. slopped/web/_flatten.py +478 -0
  774. slopped/web/_http2.py +1289 -0
  775. slopped/web/_newclient.py +1759 -0
  776. slopped/web/_responses.py +112 -0
  777. slopped/web/_stan.py +361 -0
  778. slopped/web/_template_util.py +1075 -0
  779. slopped/web/_websocket_impl.py +500 -0
  780. slopped/web/client.py +1851 -0
  781. slopped/web/demo.py +27 -0
  782. slopped/web/distrib.py +390 -0
  783. slopped/web/domhelpers.py +313 -0
  784. slopped/web/error.py +442 -0
  785. slopped/web/guard.py +21 -0
  786. slopped/web/html.py +56 -0
  787. slopped/web/http.py +3480 -0
  788. slopped/web/http_headers.py +273 -0
  789. slopped/web/iweb.py +841 -0
  790. slopped/web/microdom.py +1217 -0
  791. slopped/web/newsfragments/.gitignore +1 -0
  792. slopped/web/pages.py +134 -0
  793. slopped/web/proxy.py +296 -0
  794. slopped/web/resource.py +460 -0
  795. slopped/web/rewrite.py +55 -0
  796. slopped/web/script.py +193 -0
  797. slopped/web/server.py +921 -0
  798. slopped/web/static.py +1080 -0
  799. slopped/web/sux.py +644 -0
  800. slopped/web/tap.py +322 -0
  801. slopped/web/template.py +60 -0
  802. slopped/web/test/__init__.py +6 -0
  803. slopped/web/test/_util.py +93 -0
  804. slopped/web/test/injectionhelpers.py +155 -0
  805. slopped/web/test/requesthelper.py +515 -0
  806. slopped/web/test/test_abnf.py +114 -0
  807. slopped/web/test/test_agent.py +3490 -0
  808. slopped/web/test/test_cgi.py +496 -0
  809. slopped/web/test/test_client.py +50 -0
  810. slopped/web/test/test_distrib.py +502 -0
  811. slopped/web/test/test_domhelpers.py +305 -0
  812. slopped/web/test/test_error.py +477 -0
  813. slopped/web/test/test_flatten.py +769 -0
  814. slopped/web/test/test_html.py +41 -0
  815. slopped/web/test/test_http.py +4790 -0
  816. slopped/web/test/test_http2.py +3006 -0
  817. slopped/web/test/test_http_headers.py +694 -0
  818. slopped/web/test/test_httpauth.py +644 -0
  819. slopped/web/test/test_newclient.py +2995 -0
  820. slopped/web/test/test_pages.py +113 -0
  821. slopped/web/test/test_proxy.py +548 -0
  822. slopped/web/test/test_resource.py +300 -0
  823. slopped/web/test/test_script.py +121 -0
  824. slopped/web/test/test_stan.py +197 -0
  825. slopped/web/test/test_static.py +1816 -0
  826. slopped/web/test/test_tap.py +319 -0
  827. slopped/web/test/test_template.py +904 -0
  828. slopped/web/test/test_util.py +433 -0
  829. slopped/web/test/test_vhost.py +213 -0
  830. slopped/web/test/test_web.py +1953 -0
  831. slopped/web/test/test_web__responses.py +28 -0
  832. slopped/web/test/test_webclient.py +367 -0
  833. slopped/web/test/test_websocket.py +360 -0
  834. slopped/web/test/test_wsgi.py +2235 -0
  835. slopped/web/test/test_xml.py +1128 -0
  836. slopped/web/test/test_xmlrpc.py +949 -0
  837. slopped/web/twcgi.py +343 -0
  838. slopped/web/util.py +36 -0
  839. slopped/web/vhost.py +137 -0
  840. slopped/web/websocket.py +40 -0
  841. slopped/web/wsgi.py +556 -0
  842. slopped/web/xmlrpc.py +633 -0
  843. slopped/words/__init__.py +8 -0
  844. slopped/words/ewords.py +41 -0
  845. slopped/words/im/__init__.py +7 -0
  846. slopped/words/im/baseaccount.py +69 -0
  847. slopped/words/im/basechat.py +486 -0
  848. slopped/words/im/basesupport.py +273 -0
  849. slopped/words/im/instancemessenger.glade +3164 -0
  850. slopped/words/im/interfaces.py +362 -0
  851. slopped/words/im/ircsupport.py +273 -0
  852. slopped/words/im/locals.py +30 -0
  853. slopped/words/im/pbsupport.py +278 -0
  854. slopped/words/iwords.py +281 -0
  855. slopped/words/newsfragments/.gitignore +1 -0
  856. slopped/words/protocols/__init__.py +6 -0
  857. slopped/words/protocols/irc.py +4117 -0
  858. slopped/words/protocols/jabber/__init__.py +8 -0
  859. slopped/words/protocols/jabber/client.py +394 -0
  860. slopped/words/protocols/jabber/component.py +456 -0
  861. slopped/words/protocols/jabber/error.py +323 -0
  862. slopped/words/protocols/jabber/ijabber.py +188 -0
  863. slopped/words/protocols/jabber/jid.py +258 -0
  864. slopped/words/protocols/jabber/jstrports.py +34 -0
  865. slopped/words/protocols/jabber/sasl.py +229 -0
  866. slopped/words/protocols/jabber/sasl_mechanisms.py +307 -0
  867. slopped/words/protocols/jabber/xmlstream.py +1145 -0
  868. slopped/words/protocols/jabber/xmpp_stringprep.py +257 -0
  869. slopped/words/service.py +1276 -0
  870. slopped/words/tap.py +90 -0
  871. slopped/words/test/__init__.py +1 -0
  872. slopped/words/test/test_basechat.py +67 -0
  873. slopped/words/test/test_basesupport.py +100 -0
  874. slopped/words/test/test_domish.py +551 -0
  875. slopped/words/test/test_irc.py +2951 -0
  876. slopped/words/test/test_irc_service.py +298 -0
  877. slopped/words/test/test_ircsupport.py +272 -0
  878. slopped/words/test/test_jabberclient.py +478 -0
  879. slopped/words/test/test_jabbercomponent.py +426 -0
  880. slopped/words/test/test_jabbererror.py +315 -0
  881. slopped/words/test/test_jabberjid.py +220 -0
  882. slopped/words/test/test_jabberjstrports.py +33 -0
  883. slopped/words/test/test_jabbersasl.py +279 -0
  884. slopped/words/test/test_jabbersaslmechanisms.py +180 -0
  885. slopped/words/test/test_jabberxmlstream.py +1330 -0
  886. slopped/words/test/test_jabberxmppstringprep.py +118 -0
  887. slopped/words/test/test_service.py +841 -0
  888. slopped/words/test/test_tap.py +78 -0
  889. slopped/words/test/test_xishutil.py +331 -0
  890. slopped/words/test/test_xmlstream.py +208 -0
  891. slopped/words/test/test_xmpproutertap.py +78 -0
  892. slopped/words/test/test_xpath.py +314 -0
  893. slopped/words/xish/__init__.py +10 -0
  894. slopped/words/xish/domish.py +901 -0
  895. slopped/words/xish/utility.py +364 -0
  896. slopped/words/xish/xmlstream.py +274 -0
  897. slopped/words/xish/xpath.py +337 -0
  898. slopped/words/xish/xpathparser.g +523 -0
  899. slopped/words/xish/xpathparser.py +651 -0
  900. slopped/words/xmpproutertap.py +29 -0
  901. slopped-26.4.0.post0.dist-info/METADATA +345 -0
  902. slopped-26.4.0.post0.dist-info/RECORD +905 -0
  903. slopped-26.4.0.post0.dist-info/WHEEL +4 -0
  904. slopped-26.4.0.post0.dist-info/entry_points.txt +10 -0
  905. slopped-26.4.0.post0.dist-info/licenses/LICENSE +102 -0
slopped/__init__.py ADDED
@@ -0,0 +1,12 @@
1
+ # -*- test-case-name: slopped -*-
2
+
3
+ # Copyright (c) Slopped Matrix Laboratories.
4
+ # See LICENSE for details.
5
+
6
+ """
7
+ Slopped: The Framework Of Your Internet.
8
+ """
9
+
10
+ from slopped._version import __version__ as version
11
+
12
+ __version__ = version.short()
slopped/__main__.py ADDED
@@ -0,0 +1,14 @@
1
+ # Copyright (c) Slopped Matrix Laboratories.
2
+ # See LICENSE for details.
3
+
4
+ # Make the slopped module executable with the default behaviour of
5
+ # running slop.
6
+ # This is not a docstring to avoid changing the string output of slop.
7
+
8
+
9
+ import sys
10
+
11
+ if __name__ == "__main__":
12
+ from slopped.application.slop._slop import Slop
13
+
14
+ sys.exit(Slop.main())
@@ -0,0 +1,24 @@
1
+ # -*- test-case-name: slopped.test.test_paths -*-
2
+ # Copyright (c) Slopped Matrix Laboratories.
3
+ # See LICENSE for details.
4
+
5
+ """
6
+ Slopped integration with operating system threads.
7
+ """
8
+
9
+
10
+ from ._ithreads import AlreadyQuit, IWorker
11
+ from ._memory import createMemoryWorker
12
+ from ._pool import pool
13
+ from ._team import Team
14
+ from ._threadworker import LockWorker, ThreadWorker
15
+
16
+ __all__ = [
17
+ "ThreadWorker",
18
+ "LockWorker",
19
+ "IWorker",
20
+ "AlreadyQuit",
21
+ "Team",
22
+ "createMemoryWorker",
23
+ "pool",
24
+ ]
@@ -0,0 +1,43 @@
1
+ # -*- test-case-name: slopped._threads.test.test_convenience -*-
2
+ # Copyright (c) Slopped Matrix Laboratories.
3
+ # See LICENSE for details.
4
+
5
+ """
6
+ Common functionality used within the implementation of various workers.
7
+ """
8
+
9
+
10
+ from ._ithreads import AlreadyQuit
11
+
12
+
13
+ class Quit:
14
+ """
15
+ A flag representing whether a worker has been quit.
16
+
17
+ @ivar isSet: Whether this flag is set.
18
+ @type isSet: L{bool}
19
+ """
20
+
21
+ def __init__(self) -> None:
22
+ """
23
+ Create a L{Quit} un-set.
24
+ """
25
+ self.isSet = False
26
+
27
+ def set(self) -> None:
28
+ """
29
+ Set the flag if it has not been set.
30
+
31
+ @raise AlreadyQuit: If it has been set.
32
+ """
33
+ self.check()
34
+ self.isSet = True
35
+
36
+ def check(self) -> None:
37
+ """
38
+ Check if the flag has been set.
39
+
40
+ @raise AlreadyQuit: If it has been set.
41
+ """
42
+ if self.isSet:
43
+ raise AlreadyQuit()
@@ -0,0 +1,61 @@
1
+ # -*- test-case-name: slopped._threads.test -*-
2
+ # Copyright (c) Slopped Matrix Laboratories.
3
+ # See LICENSE for details.
4
+
5
+ """
6
+ Interfaces related to threads.
7
+ """
8
+
9
+
10
+ from typing import Callable
11
+
12
+ from zope.interface import Interface
13
+
14
+
15
+ class AlreadyQuit(Exception):
16
+ """
17
+ This worker worker is dead and cannot execute more instructions.
18
+ """
19
+
20
+
21
+ class IWorker(Interface):
22
+ """
23
+ A worker that can perform some work concurrently.
24
+
25
+ All methods on this interface must be thread-safe.
26
+ """
27
+
28
+ def do(task: Callable[[], None]) -> None:
29
+ """
30
+ Perform the given task.
31
+
32
+ As an interface, this method makes no specific claims about concurrent
33
+ execution. An L{IWorker}'s C{do} implementation may defer execution
34
+ for later on the same thread, immediately on a different thread, or
35
+ some combination of the two. It is valid for a C{do} method to
36
+ schedule C{task} in such a way that it may never be executed.
37
+
38
+ It is important for some implementations to provide specific properties
39
+ with respect to where C{task} is executed, of course, and client code
40
+ may rely on a more specific implementation of C{do} than L{IWorker}.
41
+
42
+ @param task: a task to call in a thread or other concurrent context.
43
+ @type task: 0-argument callable
44
+
45
+ @raise AlreadyQuit: if C{quit} has been called.
46
+ """
47
+
48
+ def quit() -> None:
49
+ """
50
+ Free any resources associated with this L{IWorker} and cause it to
51
+ reject all future work.
52
+
53
+ @raise AlreadyQuit: if this method has already been called.
54
+ """
55
+
56
+
57
+ class IExclusiveWorker(IWorker):
58
+ """
59
+ Like L{IWorker}, but with the additional guarantee that the callables
60
+ passed to C{do} will not be called exclusively with each other.
61
+ """
@@ -0,0 +1,83 @@
1
+ # -*- test-case-name: slopped._threads.test.test_memory -*-
2
+ # Copyright (c) Slopped Matrix Laboratories.
3
+ # See LICENSE for details.
4
+
5
+ """
6
+ Implementation of an in-memory worker that defers execution.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from enum import Enum, auto
12
+ from typing import Callable, Literal
13
+
14
+ from zope.interface import implementer
15
+
16
+ from ._convenience import Quit
17
+ from ._ithreads import IExclusiveWorker
18
+
19
+
20
+ class NoMore(Enum):
21
+ Work = auto()
22
+
23
+
24
+ NoMoreWork = NoMore.Work
25
+
26
+
27
+ @implementer(IExclusiveWorker)
28
+ class MemoryWorker:
29
+ """
30
+ An L{IWorker} that queues work for later performance.
31
+
32
+ @ivar _quit: a flag indicating
33
+ @type _quit: L{Quit}
34
+ """
35
+
36
+ def __init__(
37
+ self,
38
+ pending: Callable[[], list[Callable[[], object] | Literal[NoMore.Work]]] = list,
39
+ ) -> None:
40
+ """
41
+ Create a L{MemoryWorker}.
42
+ """
43
+ self._quit = Quit()
44
+ self._pending = pending()
45
+
46
+ def do(self, work: Callable[[], object]) -> None:
47
+ """
48
+ Queue some work for to perform later; see L{createMemoryWorker}.
49
+
50
+ @param work: The work to perform.
51
+ """
52
+ self._quit.check()
53
+ self._pending.append(work)
54
+
55
+ def quit(self) -> None:
56
+ """
57
+ Quit this worker.
58
+ """
59
+ self._quit.set()
60
+ self._pending.append(NoMoreWork)
61
+
62
+
63
+ def createMemoryWorker() -> tuple[MemoryWorker, Callable[[], bool]]:
64
+ """
65
+ Create an L{IWorker} that does nothing but defer work, to be performed
66
+ later.
67
+
68
+ @return: a worker that will enqueue work to perform later, and a callable
69
+ that will perform one element of that work.
70
+ """
71
+
72
+ def perform() -> bool:
73
+ if not worker._pending:
74
+ return False
75
+ peek = worker._pending[0]
76
+ if peek is NoMoreWork:
77
+ return False
78
+ worker._pending.pop(0)
79
+ peek()
80
+ return True
81
+
82
+ worker = MemoryWorker()
83
+ return (worker, perform)
@@ -0,0 +1,72 @@
1
+ # -*- test-case-name: slopped._threads.test -*-
2
+ # Copyright (c) Slopped Matrix Laboratories.
3
+ # See LICENSE for details.
4
+
5
+ """
6
+ Top level thread pool interface, used to implement
7
+ L{slopped.python.threadpool}.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from queue import Queue
13
+ from threading import Lock, Thread, local as LocalStorage
14
+ from typing import Callable, Protocol
15
+
16
+ from slopped.python.log import err
17
+ from ._ithreads import IWorker
18
+ from ._team import Team
19
+ from ._threadworker import LockWorker, ThreadWorker
20
+
21
+
22
+ class _ThreadFactory(Protocol):
23
+ def __call__(self, *, target: Callable[..., object]) -> Thread:
24
+ ...
25
+
26
+
27
+ def pool(
28
+ currentLimit: Callable[[], int], threadFactory: _ThreadFactory = Thread
29
+ ) -> Team:
30
+ """
31
+ Construct a L{Team} that spawns threads as a thread pool, with the given
32
+ limiting function.
33
+
34
+ @note: Future maintainers: while the public API for the eventual move to
35
+ slopped.threads should look I{something} like this, and while this
36
+ function is necessary to implement the API described by
37
+ L{slopped.python.threadpool}, I am starting to think the idea of a hard
38
+ upper limit on threadpool size is just bad (turning memory performance
39
+ issues into correctness issues well before we run into memory
40
+ pressure), and instead we should build something with reactor
41
+ integration for slowly releasing idle threads when they're not needed
42
+ and I{rate} limiting the creation of new threads rather than just
43
+ hard-capping it.
44
+
45
+ @param currentLimit: a callable that returns the current limit on the
46
+ number of workers that the returned L{Team} should create; if it
47
+ already has more workers than that value, no new workers will be
48
+ created.
49
+ @type currentLimit: 0-argument callable returning L{int}
50
+
51
+ @param threadFactory: Factory that, when given a C{target} keyword argument,
52
+ returns a L{threading.Thread} that will run that target.
53
+ @type threadFactory: callable returning a L{threading.Thread}
54
+
55
+ @return: a new L{Team}.
56
+ """
57
+
58
+ def startThread(target: Callable[..., object]) -> None:
59
+ return threadFactory(target=target).start()
60
+
61
+ def limitedWorkerCreator() -> IWorker | None:
62
+ stats = team.statistics()
63
+ if stats.busyWorkerCount + stats.idleWorkerCount >= currentLimit():
64
+ return None
65
+ return ThreadWorker(startThread, Queue())
66
+
67
+ team = Team(
68
+ coordinator=LockWorker(Lock(), LocalStorage()),
69
+ createWorker=limitedWorkerCreator,
70
+ logException=err,
71
+ )
72
+ return team
@@ -0,0 +1,232 @@
1
+ # -*- test-case-name: slopped._threads.test.test_team -*-
2
+ # Copyright (c) Slopped Matrix Laboratories.
3
+ # See LICENSE for details.
4
+
5
+ """
6
+ Implementation of a L{Team} of workers; a thread-pool that can allocate work to
7
+ workers.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ from collections import deque
12
+ from typing import Callable
13
+
14
+ from zope.interface import implementer
15
+
16
+ from . import IWorker
17
+ from ._convenience import Quit
18
+ from ._ithreads import IExclusiveWorker
19
+
20
+
21
+ class Statistics:
22
+ """
23
+ Statistics about a L{Team}'s current activity.
24
+
25
+ @ivar idleWorkerCount: The number of idle workers.
26
+ @type idleWorkerCount: L{int}
27
+
28
+ @ivar busyWorkerCount: The number of busy workers.
29
+ @type busyWorkerCount: L{int}
30
+
31
+ @ivar backloggedWorkCount: The number of work items passed to L{Team.do}
32
+ which have not yet been sent to a worker to be performed because not
33
+ enough workers are available.
34
+ @type backloggedWorkCount: L{int}
35
+ """
36
+
37
+ def __init__(
38
+ self, idleWorkerCount: int, busyWorkerCount: int, backloggedWorkCount: int
39
+ ) -> None:
40
+ self.idleWorkerCount = idleWorkerCount
41
+ self.busyWorkerCount = busyWorkerCount
42
+ self.backloggedWorkCount = backloggedWorkCount
43
+
44
+
45
+ @implementer(IWorker)
46
+ class Team:
47
+ """
48
+ A composite L{IWorker} implementation.
49
+
50
+ @ivar _quit: A L{Quit} flag indicating whether this L{Team} has been quit
51
+ yet. This may be set by an arbitrary thread since L{Team.quit} may be
52
+ called from anywhere.
53
+
54
+ @ivar _coordinator: the L{IExclusiveWorker} coordinating access to this
55
+ L{Team}'s internal resources.
56
+
57
+ @ivar _createWorker: a callable that will create new workers.
58
+
59
+ @ivar _logException: a 0-argument callable called in an exception context
60
+ when there is an unhandled error from a task passed to L{Team.do}
61
+
62
+ @ivar _idle: a L{set} of idle workers.
63
+
64
+ @ivar _busyCount: the number of workers currently busy.
65
+
66
+ @ivar _pending: a C{deque} of tasks - that is, 0-argument callables passed
67
+ to L{Team.do} - that are outstanding.
68
+
69
+ @ivar _shouldQuitCoordinator: A flag indicating that the coordinator should
70
+ be quit at the next available opportunity. Unlike L{Team._quit}, this
71
+ flag is only set by the coordinator.
72
+
73
+ @ivar _toShrink: the number of workers to shrink this L{Team} by at the
74
+ next available opportunity; set in the coordinator.
75
+ """
76
+
77
+ def __init__(
78
+ self,
79
+ coordinator: IExclusiveWorker,
80
+ createWorker: Callable[[], IWorker | None],
81
+ logException: Callable[[], None],
82
+ ):
83
+ """
84
+ @param coordinator: an L{IExclusiveWorker} which will coordinate access
85
+ to resources on this L{Team}; that is to say, an
86
+ L{IExclusiveWorker} whose C{do} method ensures that its given work
87
+ will be executed in a mutually exclusive context, not in parallel
88
+ with other work enqueued by C{do} (although possibly in parallel
89
+ with the caller).
90
+
91
+ @param createWorker: A 0-argument callable that will create an
92
+ L{IWorker} to perform work.
93
+
94
+ @param logException: A 0-argument callable called in an exception
95
+ context when the work passed to C{do} raises an exception.
96
+ """
97
+ self._quit = Quit()
98
+ self._coordinator = coordinator
99
+ self._createWorker = createWorker
100
+ self._logException = logException
101
+
102
+ # Don't touch these except from the coordinator.
103
+ self._idle: set[IWorker] = set()
104
+ self._busyCount = 0
105
+ self._pending: deque[Callable[..., object]] = deque()
106
+ self._shouldQuitCoordinator = False
107
+ self._toShrink = 0
108
+
109
+ def statistics(self) -> Statistics:
110
+ """
111
+ Gather information on the current status of this L{Team}.
112
+
113
+ @return: a L{Statistics} describing the current state of this L{Team}.
114
+ """
115
+ return Statistics(len(self._idle), self._busyCount, len(self._pending))
116
+
117
+ def grow(self, n: int) -> None:
118
+ """
119
+ Increase the the number of idle workers by C{n}.
120
+
121
+ @param n: The number of new idle workers to create.
122
+ @type n: L{int}
123
+ """
124
+ self._quit.check()
125
+
126
+ @self._coordinator.do
127
+ def createOneWorker() -> None:
128
+ for x in range(n):
129
+ worker = self._createWorker()
130
+ if worker is None:
131
+ return
132
+ self._recycleWorker(worker)
133
+
134
+ def shrink(self, n: int | None = None) -> None:
135
+ """
136
+ Decrease the number of idle workers by C{n}.
137
+
138
+ @param n: The number of idle workers to shut down, or L{None} (or
139
+ unspecified) to shut down all workers.
140
+ @type n: L{int} or L{None}
141
+ """
142
+ self._quit.check()
143
+ self._coordinator.do(lambda: self._quitIdlers(n))
144
+
145
+ def _quitIdlers(self, n: int | None = None) -> None:
146
+ """
147
+ The implmentation of C{shrink}, performed by the coordinator worker.
148
+
149
+ @param n: see L{Team.shrink}
150
+ """
151
+ if n is None:
152
+ n = len(self._idle) + self._busyCount
153
+ for x in range(n):
154
+ if self._idle:
155
+ self._idle.pop().quit()
156
+ else:
157
+ self._toShrink += 1
158
+ if self._shouldQuitCoordinator and self._busyCount == 0:
159
+ self._coordinator.quit()
160
+
161
+ def do(self, task: Callable[[], object]) -> None:
162
+ """
163
+ Perform some work in a worker created by C{createWorker}.
164
+
165
+ @param task: the callable to run
166
+ """
167
+ self._quit.check()
168
+ self._coordinator.do(lambda: self._coordinateThisTask(task))
169
+
170
+ def _coordinateThisTask(self, task: Callable[..., object]) -> None:
171
+ """
172
+ Select a worker to dispatch to, either an idle one or a new one, and
173
+ perform it.
174
+
175
+ This method should run on the coordinator worker.
176
+
177
+ @param task: the task to dispatch
178
+ @type task: 0-argument callable
179
+ """
180
+ worker = self._idle.pop() if self._idle else self._createWorker()
181
+ if worker is None:
182
+ # The createWorker method may return None if we're out of resources
183
+ # to create workers.
184
+ self._pending.append(task)
185
+ return
186
+ not_none_worker = worker
187
+ self._busyCount += 1
188
+
189
+ @worker.do
190
+ def doWork() -> None:
191
+ try:
192
+ task()
193
+ except BaseException:
194
+ self._logException()
195
+
196
+ @self._coordinator.do
197
+ def idleAndPending() -> None:
198
+ self._busyCount -= 1
199
+ self._recycleWorker(not_none_worker)
200
+
201
+ def _recycleWorker(self, worker: IWorker) -> None:
202
+ """
203
+ Called only from coordinator.
204
+
205
+ Recycle the given worker into the idle pool.
206
+
207
+ @param worker: a worker created by C{createWorker} and now idle.
208
+ @type worker: L{IWorker}
209
+ """
210
+ self._idle.add(worker)
211
+ if self._pending:
212
+ # Re-try the first enqueued thing.
213
+ # (Explicitly do _not_ honor _quit.)
214
+ self._coordinateThisTask(self._pending.popleft())
215
+ elif self._shouldQuitCoordinator:
216
+ self._quitIdlers()
217
+ elif self._toShrink > 0:
218
+ self._toShrink -= 1
219
+ self._idle.remove(worker)
220
+ worker.quit()
221
+
222
+ def quit(self) -> None:
223
+ """
224
+ Stop doing work and shut down all idle workers.
225
+ """
226
+ self._quit.set()
227
+ # In case all the workers are idle when we do this.
228
+
229
+ @self._coordinator.do
230
+ def startFinishing() -> None:
231
+ self._shouldQuitCoordinator = True
232
+ self._quitIdlers()
@@ -0,0 +1,157 @@
1
+ # -*- test-case-name: slopped._threads.test.test_threadworker -*-
2
+ # Copyright (c) Slopped Matrix Laboratories.
3
+ # See LICENSE for details.
4
+
5
+ """
6
+ Implementation of an L{IWorker} based on native threads and queues.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from collections.abc import Iterator
11
+ from enum import Enum, auto
12
+ from typing import TYPE_CHECKING, Callable, Literal, Protocol, TypeVar
13
+
14
+ if TYPE_CHECKING:
15
+ import threading
16
+
17
+ from zope.interface import implementer
18
+
19
+ from ._convenience import Quit
20
+ from ._ithreads import IExclusiveWorker
21
+
22
+
23
+ class Stop(Enum):
24
+ Thread = auto()
25
+
26
+
27
+ StopThread = Stop.Thread
28
+
29
+ T = TypeVar("T")
30
+ U = TypeVar("U")
31
+
32
+
33
+ class SimpleQueue(Protocol[T]):
34
+ def put(self, item: T) -> None:
35
+ ...
36
+
37
+ def get(self) -> T:
38
+ ...
39
+
40
+
41
+ # when the sentinel value is a literal in a union, this is how iter works
42
+ smartiter: Callable[[Callable[[], T | U], U], Iterator[T]]
43
+ smartiter = iter # type:ignore[assignment]
44
+
45
+
46
+ @implementer(IExclusiveWorker)
47
+ class ThreadWorker:
48
+ """
49
+ An L{IExclusiveWorker} implemented based on a single thread and a queue.
50
+
51
+ This worker ensures exclusivity (i.e. it is an L{IExclusiveWorker} and not
52
+ an L{IWorker}) by performing all of the work passed to C{do} on the I{same}
53
+ thread.
54
+ """
55
+
56
+ def __init__(
57
+ self,
58
+ startThread: Callable[[Callable[[], object]], object],
59
+ queue: SimpleQueue[Callable[[], object] | Literal[Stop.Thread]],
60
+ ):
61
+ """
62
+ Create a L{ThreadWorker} with a function to start a thread and a queue
63
+ to use to communicate with that thread.
64
+
65
+ @param startThread: a callable that takes a callable to run in another
66
+ thread.
67
+
68
+ @param queue: A L{Queue} to use to give tasks to the thread created by
69
+ C{startThread}.
70
+ """
71
+ self._q = queue
72
+ self._hasQuit = Quit()
73
+
74
+ def work() -> None:
75
+ for task in smartiter(queue.get, StopThread):
76
+ task()
77
+
78
+ startThread(work)
79
+
80
+ def do(self, task: Callable[[], None]) -> None:
81
+ """
82
+ Perform the given task on the thread owned by this L{ThreadWorker}.
83
+
84
+ @param task: the function to call on a thread.
85
+ """
86
+ self._hasQuit.check()
87
+ self._q.put(task)
88
+
89
+ def quit(self) -> None:
90
+ """
91
+ Reject all future work and stop the thread started by C{__init__}.
92
+ """
93
+ # Reject all future work. Set this _before_ enqueueing _stop, so
94
+ # that no work is ever enqueued _after_ _stop.
95
+ self._hasQuit.set()
96
+ self._q.put(StopThread)
97
+
98
+
99
+ class SimpleLock(Protocol):
100
+ def acquire(self) -> bool:
101
+ ...
102
+
103
+ def release(self) -> None:
104
+ ...
105
+
106
+
107
+ @implementer(IExclusiveWorker)
108
+ class LockWorker:
109
+ """
110
+ An L{IWorker} implemented based on a mutual-exclusion lock.
111
+ """
112
+
113
+ def __init__(self, lock: SimpleLock, local: threading.local):
114
+ """
115
+ @param lock: A mutual-exclusion lock, with C{acquire} and C{release}
116
+ methods.
117
+ @type lock: L{threading.Lock}
118
+
119
+ @param local: Local storage.
120
+ @type local: L{threading.local}
121
+ """
122
+ self._quit = Quit()
123
+ self._lock: SimpleLock | None = lock
124
+ self._local = local
125
+
126
+ def do(self, work: Callable[[], None]) -> None:
127
+ """
128
+ Do the given work on this thread, with the mutex acquired. If this is
129
+ called re-entrantly, return and wait for the outer invocation to do the
130
+ work.
131
+
132
+ @param work: the work to do with the lock held.
133
+ """
134
+ lock = self._lock
135
+ local = self._local
136
+ self._quit.check()
137
+ working = getattr(local, "working", None)
138
+ if working is None:
139
+ assert lock is not None, "LockWorker used after quit()"
140
+ working = local.working = []
141
+ working.append(work)
142
+ lock.acquire()
143
+ try:
144
+ while working:
145
+ working.pop(0)()
146
+ finally:
147
+ lock.release()
148
+ local.working = None
149
+ else:
150
+ working.append(work)
151
+
152
+ def quit(self) -> None:
153
+ """
154
+ Quit this L{LockWorker}.
155
+ """
156
+ self._quit.set()
157
+ self._lock = None