omlish 0.0.0.dev423__py3-none-any.whl → 0.0.0.dev484__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.

Potentially problematic release.


This version of omlish might be problematic. Click here for more details.

Files changed (464) hide show
  1. omlish/{.manifests.json → .omlish-manifests.json} +12 -0
  2. omlish/__about__.py +21 -18
  3. omlish/argparse/all.py +17 -9
  4. omlish/argparse/cli.py +16 -3
  5. omlish/argparse/utils.py +21 -0
  6. omlish/asyncs/all.py +0 -13
  7. omlish/asyncs/asyncio/rlock.py +110 -0
  8. omlish/asyncs/asyncio/subprocesses.py +2 -2
  9. omlish/asyncs/asyncio/sync.py +43 -0
  10. omlish/asyncs/asyncio/utils.py +2 -0
  11. omlish/asyncs/ioproxy/proxy.py +1 -1
  12. omlish/asyncs/sync.py +25 -0
  13. omlish/bootstrap/_marshal.py +1 -1
  14. omlish/bootstrap/diag.py +12 -21
  15. omlish/bootstrap/main.py +2 -5
  16. omlish/bootstrap/sys.py +27 -28
  17. omlish/c3.py +4 -1
  18. omlish/cexts/include/omlish/omlish.hh +1 -0
  19. omlish/collections/__init__.py +13 -1
  20. omlish/collections/attrregistry.py +210 -0
  21. omlish/collections/cache/impl.py +3 -2
  22. omlish/collections/identity.py +1 -0
  23. omlish/collections/mappings.py +28 -0
  24. omlish/collections/trie.py +5 -1
  25. omlish/collections/utils.py +77 -0
  26. omlish/concurrent/__init__.py +0 -11
  27. omlish/concurrent/all.py +18 -0
  28. omlish/concurrent/futures.py +25 -0
  29. omlish/concurrent/threadlets.py +1 -1
  30. omlish/configs/processing/flattening.py +1 -1
  31. omlish/configs/processing/merging.py +8 -6
  32. omlish/configs/types.py +1 -1
  33. omlish/daemons/__init__.py +70 -0
  34. omlish/daemons/daemon.py +2 -2
  35. omlish/daemons/launching.py +2 -2
  36. omlish/daemons/reparent.py +2 -3
  37. omlish/daemons/spawning.py +2 -3
  38. omlish/dataclasses/__init__.py +5 -5
  39. omlish/dataclasses/errors.py +1 -1
  40. omlish/dataclasses/impl/api/classes/decorator.py +3 -0
  41. omlish/dataclasses/impl/api/classes/make.py +4 -1
  42. omlish/dataclasses/impl/concerns/doc.py +1 -1
  43. omlish/dataclasses/impl/concerns/repr.py +15 -2
  44. omlish/dataclasses/impl/configs.py +97 -36
  45. omlish/dataclasses/impl/generation/compilation.py +21 -19
  46. omlish/dataclasses/impl/generation/globals.py +1 -0
  47. omlish/dataclasses/impl/generation/ops.py +1 -0
  48. omlish/dataclasses/impl/generation/processor.py +105 -24
  49. omlish/dataclasses/impl/processing/base.py +8 -0
  50. omlish/dataclasses/impl/processing/driving.py +8 -8
  51. omlish/dataclasses/specs.py +34 -2
  52. omlish/dataclasses/tools/as_.py +0 -12
  53. omlish/dataclasses/tools/modifiers.py +5 -0
  54. omlish/dataclasses/tools/static.py +1 -1
  55. omlish/diag/_pycharm/runhack.py +1 -1
  56. omlish/diag/{lslocks.py → cmds/lslocks.py} +6 -6
  57. omlish/diag/{lsof.py → cmds/lsof.py} +6 -6
  58. omlish/diag/{ps.py → cmds/ps.py} +6 -6
  59. omlish/diag/procfs.py +4 -4
  60. omlish/diag/pycharm.py +16 -2
  61. omlish/diag/pydevd.py +58 -40
  62. omlish/diag/replserver/console.py +3 -3
  63. omlish/diag/replserver/server.py +2 -2
  64. omlish/dispatch/__init__.py +18 -12
  65. omlish/dispatch/methods.py +50 -140
  66. omlish/dom/rendering.py +1 -1
  67. omlish/formats/dotenv.py +8 -8
  68. omlish/formats/json/stream/__init__.py +18 -3
  69. omlish/formats/json/stream/building.py +2 -2
  70. omlish/formats/json/stream/lexing.py +401 -67
  71. omlish/formats/json/stream/parsing.py +32 -10
  72. omlish/formats/json/stream/rendering.py +6 -6
  73. omlish/formats/json/stream/utils.py +132 -30
  74. omlish/formats/json5/literals.py +7 -4
  75. omlish/formats/json5/parsing.py +33 -79
  76. omlish/formats/json5/stream.py +77 -0
  77. omlish/formats/logfmt.py +8 -2
  78. omlish/funcs/genmachine.py +2 -2
  79. omlish/funcs/guard.py +225 -0
  80. omlish/graphs/dot/rendering.py +1 -1
  81. omlish/http/all.py +122 -53
  82. omlish/http/asgi.py +2 -2
  83. omlish/http/clients/__init__.py +0 -34
  84. omlish/http/clients/asyncs.py +153 -0
  85. omlish/http/clients/base.py +63 -122
  86. omlish/http/clients/coro/sync.py +171 -0
  87. omlish/http/clients/default.py +209 -30
  88. omlish/http/clients/executor.py +56 -0
  89. omlish/http/clients/httpx.py +78 -13
  90. omlish/http/clients/middleware.py +181 -0
  91. omlish/http/clients/sync.py +151 -0
  92. omlish/http/clients/syncasync.py +49 -0
  93. omlish/http/clients/urllib.py +8 -5
  94. omlish/http/coro/client/{client.py → connection.py} +43 -37
  95. omlish/http/coro/client/headers.py +5 -5
  96. omlish/http/coro/client/response.py +37 -38
  97. omlish/http/coro/client/status.py +4 -4
  98. omlish/http/coro/{client/io.py → io.py} +19 -2
  99. omlish/http/coro/server/fdio.py +10 -9
  100. omlish/http/coro/server/server.py +14 -41
  101. omlish/http/coro/server/sockets.py +7 -6
  102. omlish/http/flasky/__init__.py +40 -0
  103. omlish/http/flasky/_compat.py +2 -0
  104. omlish/http/flasky/api.py +82 -0
  105. omlish/http/flasky/app.py +203 -0
  106. omlish/http/flasky/cvs.py +59 -0
  107. omlish/http/flasky/requests.py +20 -0
  108. omlish/http/flasky/responses.py +23 -0
  109. omlish/http/flasky/routes.py +23 -0
  110. omlish/http/flasky/types.py +15 -0
  111. omlish/http/handlers.py +3 -2
  112. omlish/http/headers.py +69 -35
  113. omlish/http/sse.py +1 -1
  114. omlish/http/urls.py +67 -0
  115. omlish/inject/__init__.py +173 -126
  116. omlish/inject/_dataclasses.py +4986 -0
  117. omlish/inject/binder.py +10 -49
  118. omlish/inject/elements.py +27 -0
  119. omlish/inject/{utils.py → helpers/constfn.py} +3 -3
  120. omlish/inject/{tags.py → helpers/id.py} +2 -2
  121. omlish/inject/helpers/multis.py +143 -0
  122. omlish/inject/helpers/wrappers.py +54 -0
  123. omlish/inject/impl/elements.py +52 -22
  124. omlish/inject/impl/injector.py +76 -49
  125. omlish/inject/impl/inspect.py +11 -1
  126. omlish/inject/impl/maysync.py +43 -0
  127. omlish/inject/impl/multis.py +10 -7
  128. omlish/inject/impl/privates.py +8 -8
  129. omlish/inject/impl/providers.py +23 -34
  130. omlish/inject/impl/providersmap.py +43 -0
  131. omlish/inject/impl/proxy.py +0 -2
  132. omlish/inject/impl/scopes.py +19 -23
  133. omlish/inject/impl/sync.py +41 -0
  134. omlish/inject/injector.py +37 -8
  135. omlish/inject/inspect.py +35 -0
  136. omlish/inject/listeners.py +4 -4
  137. omlish/inject/managed.py +54 -18
  138. omlish/inject/maysync.py +27 -0
  139. omlish/inject/multis.py +8 -0
  140. omlish/inject/overrides.py +3 -3
  141. omlish/inject/privates.py +6 -0
  142. omlish/inject/providers.py +8 -1
  143. omlish/inject/scopes.py +40 -12
  144. omlish/inject/sync.py +49 -0
  145. omlish/io/buffers.py +119 -1
  146. omlish/io/readers.py +29 -0
  147. omlish/iterators/__init__.py +28 -20
  148. omlish/iterators/transforms.py +204 -0
  149. omlish/lang/__init__.py +240 -129
  150. omlish/lang/_asyncs.cc +186 -0
  151. omlish/lang/asyncs.py +67 -43
  152. omlish/lang/{attrs.py → attrstorage.py} +15 -15
  153. omlish/lang/cached/property.py +2 -2
  154. omlish/lang/casing.py +11 -0
  155. omlish/lang/classes/bindable.py +2 -3
  156. omlish/lang/classes/restrict.py +8 -0
  157. omlish/lang/classes/simple.py +26 -4
  158. omlish/lang/collections.py +1 -1
  159. omlish/lang/contextmanagers.py +59 -9
  160. omlish/lang/functions.py +31 -33
  161. omlish/lang/imports/_capture.cc +103 -0
  162. omlish/lang/imports/capture.py +902 -0
  163. omlish/lang/imports/lazy.py +0 -25
  164. omlish/lang/imports/proxy.py +559 -0
  165. omlish/lang/iterables.py +2 -2
  166. omlish/lang/lazyglobals.py +49 -14
  167. omlish/lang/maybes.py +2 -1
  168. omlish/lang/maysync.py +2 -2
  169. omlish/lang/params.py +17 -0
  170. omlish/lang/recursion.py +0 -1
  171. omlish/lang/resources.py +1 -1
  172. omlish/lang/sequences.py +124 -0
  173. omlish/lifecycles/contextmanagers.py +1 -2
  174. omlish/lifecycles/controller.py +1 -2
  175. omlish/lite/abstract.py +54 -24
  176. omlish/lite/asyncs.py +146 -0
  177. omlish/lite/attrops.py +415 -0
  178. omlish/lite/cached.py +57 -1
  179. omlish/lite/contextmanagers.py +4 -4
  180. omlish/lite/dataclasses.py +55 -0
  181. omlish/lite/inject.py +5 -4
  182. omlish/lite/marshal.py +1 -0
  183. omlish/lite/maybes.py +10 -2
  184. omlish/lite/maysync.py +22 -5
  185. omlish/lite/pycharm.py +1 -1
  186. omlish/lite/strings.py +0 -7
  187. omlish/lite/timing.py +6 -3
  188. omlish/lite/typing.py +6 -0
  189. omlish/logs/_amalg.py +8 -0
  190. omlish/logs/all.py +59 -31
  191. omlish/logs/base.py +204 -0
  192. omlish/logs/contexts.py +171 -0
  193. omlish/logs/formatters.py +13 -0
  194. omlish/logs/infos.py +377 -0
  195. omlish/logs/levels.py +97 -0
  196. omlish/logs/modules.py +13 -0
  197. omlish/logs/protocols.py +32 -0
  198. omlish/logs/standard.py +20 -15
  199. omlish/logs/std/configs.py +29 -0
  200. omlish/logs/{filters.py → std/filters.py} +1 -1
  201. omlish/logs/std/formatters.py +25 -0
  202. omlish/logs/std/handlers.py +19 -0
  203. omlish/logs/{json.py → std/json.py} +2 -2
  204. omlish/logs/std/loggers.py +48 -0
  205. omlish/logs/{proxy.py → std/proxy.py} +3 -3
  206. omlish/logs/std/records.py +671 -0
  207. omlish/logs/typed/bindings.py +108 -37
  208. omlish/logs/typed/types.py +17 -1
  209. omlish/logs/typed/values.py +2 -2
  210. omlish/logs/utils.py +60 -4
  211. omlish/logs/warnings.py +8 -0
  212. omlish/manifests/loading.py +8 -1
  213. omlish/marshal/__init__.py +54 -22
  214. omlish/marshal/_dataclasses.py +2774 -0
  215. omlish/marshal/base/configs.py +12 -0
  216. omlish/marshal/base/contexts.py +36 -21
  217. omlish/marshal/base/funcs.py +8 -11
  218. omlish/marshal/base/options.py +8 -0
  219. omlish/marshal/base/registries.py +146 -44
  220. omlish/marshal/base/types.py +40 -16
  221. omlish/marshal/composite/iterables.py +33 -20
  222. omlish/marshal/composite/literals.py +20 -18
  223. omlish/marshal/composite/mappings.py +36 -23
  224. omlish/marshal/composite/maybes.py +29 -19
  225. omlish/marshal/composite/newtypes.py +16 -16
  226. omlish/marshal/composite/optionals.py +14 -14
  227. omlish/marshal/composite/special.py +15 -15
  228. omlish/marshal/composite/unions/literals.py +93 -0
  229. omlish/marshal/composite/unions/primitives.py +103 -0
  230. omlish/marshal/factories/invalidate.py +18 -68
  231. omlish/marshal/factories/method.py +26 -0
  232. omlish/marshal/factories/moduleimport/factories.py +22 -65
  233. omlish/marshal/factories/multi.py +13 -25
  234. omlish/marshal/factories/recursive.py +42 -56
  235. omlish/marshal/factories/typecache.py +29 -74
  236. omlish/marshal/factories/typemap.py +42 -43
  237. omlish/marshal/objects/dataclasses.py +129 -106
  238. omlish/marshal/objects/marshal.py +18 -14
  239. omlish/marshal/objects/namedtuples.py +48 -42
  240. omlish/marshal/objects/unmarshal.py +19 -15
  241. omlish/marshal/polymorphism/marshal.py +9 -11
  242. omlish/marshal/polymorphism/metadata.py +16 -5
  243. omlish/marshal/polymorphism/standard.py +13 -1
  244. omlish/marshal/polymorphism/unions.py +15 -105
  245. omlish/marshal/polymorphism/unmarshal.py +9 -10
  246. omlish/marshal/singular/enums.py +14 -18
  247. omlish/marshal/standard.py +10 -6
  248. omlish/marshal/trivial/any.py +1 -1
  249. omlish/marshal/trivial/forbidden.py +21 -26
  250. omlish/math/fixed.py +2 -2
  251. omlish/metadata.py +23 -1
  252. omlish/os/atomics.py +2 -2
  253. omlish/os/forkhooks.py +4 -0
  254. omlish/os/journald.py +3 -3
  255. omlish/os/pidfiles/pinning.py +2 -2
  256. omlish/reflect/ops.py +9 -0
  257. omlish/reflect/types.py +44 -8
  258. omlish/secrets/marshal.py +1 -1
  259. omlish/secrets/secrets.py +6 -3
  260. omlish/sockets/addresses.py +1 -1
  261. omlish/sockets/server/handlers.py +2 -2
  262. omlish/sockets/server/server.py +4 -3
  263. omlish/sockets/server/ssl.py +2 -2
  264. omlish/specs/jmespath/__init__.py +12 -3
  265. omlish/specs/jmespath/_dataclasses.py +2893 -0
  266. omlish/specs/jmespath/ast.py +1 -1
  267. omlish/specs/jsonrpc/__init__.py +13 -0
  268. omlish/specs/jsonrpc/_marshal.py +32 -23
  269. omlish/specs/jsonrpc/conns.py +10 -7
  270. omlish/specs/jsonschema/_marshal.py +1 -1
  271. omlish/specs/jsonschema/keywords/__init__.py +7 -0
  272. omlish/specs/jsonschema/keywords/_dataclasses.py +1644 -0
  273. omlish/specs/openapi/_marshal.py +31 -22
  274. omlish/sql/__init__.py +15 -20
  275. omlish/sql/{tabledefs/alchemy.py → alchemy/tabledefs.py} +2 -2
  276. omlish/sql/queries/_marshal.py +3 -3
  277. omlish/sql/queries/params.py +1 -1
  278. omlish/sql/queries/rendering.py +1 -1
  279. omlish/sql/tabledefs/_marshal.py +1 -1
  280. omlish/subprocesses/all.py +135 -0
  281. omlish/subprocesses/base.py +8 -3
  282. omlish/subprocesses/editor.py +1 -1
  283. omlish/sync.py +181 -20
  284. omlish/term/alt.py +60 -0
  285. omlish/term/confirm.py +8 -8
  286. omlish/term/pager.py +235 -0
  287. omlish/term/terminfo.py +935 -0
  288. omlish/term/termstate.py +67 -0
  289. omlish/term/vt100/terminal.py +0 -3
  290. omlish/testing/pytest/plugins/asyncs/fixtures.py +4 -1
  291. omlish/testing/pytest/plugins/skips.py +2 -5
  292. omlish/testing/unittest/main.py +3 -3
  293. omlish/text/docwrap/__init__.py +3 -0
  294. omlish/text/docwrap/__main__.py +11 -0
  295. omlish/text/docwrap/api.py +83 -0
  296. omlish/text/docwrap/cli.py +86 -0
  297. omlish/text/docwrap/groups.py +84 -0
  298. omlish/text/docwrap/lists.py +167 -0
  299. omlish/text/docwrap/parts.py +146 -0
  300. omlish/text/docwrap/reflowing.py +106 -0
  301. omlish/text/docwrap/rendering.py +151 -0
  302. omlish/text/docwrap/utils.py +11 -0
  303. omlish/text/docwrap/wrapping.py +59 -0
  304. omlish/text/filecache.py +2 -2
  305. omlish/text/lorem.py +6 -0
  306. omlish/text/parts.py +2 -2
  307. omlish/text/textwrap.py +51 -0
  308. omlish/typedvalues/__init__.py +1 -1
  309. omlish/typedvalues/marshal.py +85 -59
  310. omlish/typedvalues/values.py +2 -1
  311. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/METADATA +36 -38
  312. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/RECORD +323 -385
  313. omlish/asyncs/bluelet/LICENSE +0 -6
  314. omlish/asyncs/bluelet/all.py +0 -67
  315. omlish/asyncs/bluelet/api.py +0 -23
  316. omlish/asyncs/bluelet/core.py +0 -178
  317. omlish/asyncs/bluelet/events.py +0 -79
  318. omlish/asyncs/bluelet/files.py +0 -80
  319. omlish/asyncs/bluelet/runner.py +0 -417
  320. omlish/asyncs/bluelet/sockets.py +0 -216
  321. omlish/asyncs/bridge.py +0 -359
  322. omlish/asyncs/utils.py +0 -18
  323. omlish/dataclasses/impl/generation/mangling.py +0 -18
  324. omlish/defs.py +0 -216
  325. omlish/dispatch/_dispatch2.py +0 -69
  326. omlish/dispatch/_dispatch3.py +0 -108
  327. omlish/dynamic.py +0 -219
  328. omlish/formats/json/Json.g4 +0 -77
  329. omlish/formats/json/_antlr/JsonLexer.py +0 -109
  330. omlish/formats/json/_antlr/JsonListener.py +0 -61
  331. omlish/formats/json/_antlr/JsonParser.py +0 -457
  332. omlish/formats/json/_antlr/JsonVisitor.py +0 -42
  333. omlish/formats/json5/Json5.g4 +0 -168
  334. omlish/formats/json5/_antlr/Json5Lexer.py +0 -354
  335. omlish/formats/json5/_antlr/Json5Listener.py +0 -79
  336. omlish/formats/json5/_antlr/Json5Parser.py +0 -617
  337. omlish/formats/json5/_antlr/Json5Visitor.py +0 -52
  338. omlish/funcs/match.py +0 -227
  339. omlish/io/trampoline.py +0 -289
  340. omlish/lang/imports/proxyinit.py +0 -665
  341. omlish/lite/logs.py +0 -4
  342. omlish/lite/reprs.py +0 -85
  343. omlish/logs/abc.py +0 -319
  344. omlish/logs/callers.py +0 -67
  345. omlish/logs/color.py +0 -27
  346. omlish/logs/configs.py +0 -29
  347. omlish/logs/handlers.py +0 -17
  348. omlish/logs/protocol.py +0 -218
  349. omlish/logs/timing.py +0 -58
  350. omlish/marshal/factories/match.py +0 -34
  351. omlish/marshal/factories/simple.py +0 -28
  352. omlish/specs/irc/messages/base.py +0 -49
  353. omlish/specs/irc/messages/formats.py +0 -92
  354. omlish/specs/irc/messages/messages.py +0 -774
  355. omlish/specs/irc/messages/parsing.py +0 -98
  356. omlish/specs/irc/numerics/formats.py +0 -97
  357. omlish/specs/irc/numerics/numerics.py +0 -865
  358. omlish/specs/irc/numerics/types.py +0 -59
  359. omlish/specs/irc/protocol/LICENSE +0 -11
  360. omlish/specs/irc/protocol/__init__.py +0 -61
  361. omlish/specs/irc/protocol/consts.py +0 -6
  362. omlish/specs/irc/protocol/errors.py +0 -30
  363. omlish/specs/irc/protocol/message.py +0 -21
  364. omlish/specs/irc/protocol/nuh.py +0 -55
  365. omlish/specs/irc/protocol/parsing.py +0 -158
  366. omlish/specs/irc/protocol/rendering.py +0 -153
  367. omlish/specs/irc/protocol/tags.py +0 -102
  368. omlish/specs/irc/protocol/utils.py +0 -30
  369. omlish/specs/proto/Protobuf3.g4 +0 -396
  370. omlish/specs/proto/__init__.py +0 -0
  371. omlish/specs/proto/_antlr/Protobuf3Lexer.py +0 -340
  372. omlish/specs/proto/_antlr/Protobuf3Listener.py +0 -448
  373. omlish/specs/proto/_antlr/Protobuf3Parser.py +0 -3909
  374. omlish/specs/proto/_antlr/Protobuf3Visitor.py +0 -257
  375. omlish/specs/proto/_antlr/__init__.py +0 -0
  376. omlish/specs/proto/nodes.py +0 -54
  377. omlish/specs/proto/parsing.py +0 -97
  378. omlish/sql/parsing/Minisql.g4 +0 -292
  379. omlish/sql/parsing/__init__.py +0 -0
  380. omlish/sql/parsing/_antlr/MinisqlLexer.py +0 -322
  381. omlish/sql/parsing/_antlr/MinisqlListener.py +0 -511
  382. omlish/sql/parsing/_antlr/MinisqlParser.py +0 -3763
  383. omlish/sql/parsing/_antlr/MinisqlVisitor.py +0 -292
  384. omlish/sql/parsing/_antlr/__init__.py +0 -0
  385. omlish/sql/parsing/parsing.py +0 -119
  386. omlish/text/antlr/__init__.py +0 -3
  387. omlish/text/antlr/_runtime/BufferedTokenStream.py +0 -305
  388. omlish/text/antlr/_runtime/CommonTokenFactory.py +0 -64
  389. omlish/text/antlr/_runtime/CommonTokenStream.py +0 -90
  390. omlish/text/antlr/_runtime/FileStream.py +0 -30
  391. omlish/text/antlr/_runtime/InputStream.py +0 -90
  392. omlish/text/antlr/_runtime/IntervalSet.py +0 -183
  393. omlish/text/antlr/_runtime/LICENSE.txt +0 -28
  394. omlish/text/antlr/_runtime/LL1Analyzer.py +0 -176
  395. omlish/text/antlr/_runtime/Lexer.py +0 -332
  396. omlish/text/antlr/_runtime/ListTokenSource.py +0 -147
  397. omlish/text/antlr/_runtime/Parser.py +0 -583
  398. omlish/text/antlr/_runtime/ParserInterpreter.py +0 -173
  399. omlish/text/antlr/_runtime/ParserRuleContext.py +0 -189
  400. omlish/text/antlr/_runtime/PredictionContext.py +0 -632
  401. omlish/text/antlr/_runtime/Recognizer.py +0 -150
  402. omlish/text/antlr/_runtime/RuleContext.py +0 -230
  403. omlish/text/antlr/_runtime/StdinStream.py +0 -14
  404. omlish/text/antlr/_runtime/Token.py +0 -158
  405. omlish/text/antlr/_runtime/TokenStreamRewriter.py +0 -258
  406. omlish/text/antlr/_runtime/Utils.py +0 -36
  407. omlish/text/antlr/_runtime/__init__.py +0 -2
  408. omlish/text/antlr/_runtime/_all.py +0 -24
  409. omlish/text/antlr/_runtime/_pygrun.py +0 -174
  410. omlish/text/antlr/_runtime/atn/ATN.py +0 -135
  411. omlish/text/antlr/_runtime/atn/ATNConfig.py +0 -162
  412. omlish/text/antlr/_runtime/atn/ATNConfigSet.py +0 -215
  413. omlish/text/antlr/_runtime/atn/ATNDeserializationOptions.py +0 -27
  414. omlish/text/antlr/_runtime/atn/ATNDeserializer.py +0 -449
  415. omlish/text/antlr/_runtime/atn/ATNSimulator.py +0 -50
  416. omlish/text/antlr/_runtime/atn/ATNState.py +0 -267
  417. omlish/text/antlr/_runtime/atn/ATNType.py +0 -20
  418. omlish/text/antlr/_runtime/atn/LexerATNSimulator.py +0 -573
  419. omlish/text/antlr/_runtime/atn/LexerAction.py +0 -301
  420. omlish/text/antlr/_runtime/atn/LexerActionExecutor.py +0 -146
  421. omlish/text/antlr/_runtime/atn/ParserATNSimulator.py +0 -1664
  422. omlish/text/antlr/_runtime/atn/PredictionMode.py +0 -502
  423. omlish/text/antlr/_runtime/atn/SemanticContext.py +0 -333
  424. omlish/text/antlr/_runtime/atn/Transition.py +0 -271
  425. omlish/text/antlr/_runtime/atn/__init__.py +0 -4
  426. omlish/text/antlr/_runtime/dfa/DFA.py +0 -136
  427. omlish/text/antlr/_runtime/dfa/DFASerializer.py +0 -76
  428. omlish/text/antlr/_runtime/dfa/DFAState.py +0 -129
  429. omlish/text/antlr/_runtime/dfa/__init__.py +0 -4
  430. omlish/text/antlr/_runtime/error/DiagnosticErrorListener.py +0 -111
  431. omlish/text/antlr/_runtime/error/ErrorListener.py +0 -75
  432. omlish/text/antlr/_runtime/error/ErrorStrategy.py +0 -712
  433. omlish/text/antlr/_runtime/error/Errors.py +0 -176
  434. omlish/text/antlr/_runtime/error/__init__.py +0 -4
  435. omlish/text/antlr/_runtime/tree/Chunk.py +0 -33
  436. omlish/text/antlr/_runtime/tree/ParseTreeMatch.py +0 -121
  437. omlish/text/antlr/_runtime/tree/ParseTreePattern.py +0 -75
  438. omlish/text/antlr/_runtime/tree/ParseTreePatternMatcher.py +0 -377
  439. omlish/text/antlr/_runtime/tree/RuleTagToken.py +0 -53
  440. omlish/text/antlr/_runtime/tree/TokenTagToken.py +0 -50
  441. omlish/text/antlr/_runtime/tree/Tree.py +0 -194
  442. omlish/text/antlr/_runtime/tree/Trees.py +0 -114
  443. omlish/text/antlr/_runtime/tree/__init__.py +0 -2
  444. omlish/text/antlr/_runtime/xpath/XPath.py +0 -278
  445. omlish/text/antlr/_runtime/xpath/XPathLexer.py +0 -98
  446. omlish/text/antlr/_runtime/xpath/__init__.py +0 -4
  447. omlish/text/antlr/delimit.py +0 -109
  448. omlish/text/antlr/dot.py +0 -41
  449. omlish/text/antlr/errors.py +0 -14
  450. omlish/text/antlr/input.py +0 -96
  451. omlish/text/antlr/parsing.py +0 -54
  452. omlish/text/antlr/runtime.py +0 -102
  453. omlish/text/antlr/utils.py +0 -38
  454. /omlish/{asyncs/bluelet → cexts}/__init__.py +0 -0
  455. /omlish/{formats/json/_antlr → diag/cmds}/__init__.py +0 -0
  456. /omlish/{formats/json5/_antlr → http/clients/coro}/__init__.py +0 -0
  457. /omlish/{specs/irc → inject/helpers}/__init__.py +0 -0
  458. /omlish/{specs/irc/messages → logs/std}/__init__.py +0 -0
  459. /omlish/logs/{noisy.py → std/noisy.py} +0 -0
  460. /omlish/{specs/irc/numerics → marshal/composite/unions}/__init__.py +0 -0
  461. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/WHEEL +0 -0
  462. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/entry_points.txt +0 -0
  463. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/licenses/LICENSE +0 -0
  464. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/top_level.txt +0 -0
@@ -11,13 +11,14 @@ from ... import dataclasses as dc
11
11
  from ... import lang
12
12
  from ... import reflect as rfl
13
13
  from ...lite import marshal as lm
14
- from ..base.contexts import MarshalContext
15
- from ..base.contexts import UnmarshalContext
14
+ from ..base.contexts import MarshalFactoryContext
15
+ from ..base.contexts import UnmarshalFactoryContext
16
+ from ..base.errors import UnhandledTypeError
16
17
  from ..base.options import Option
17
18
  from ..base.types import Marshaler
19
+ from ..base.types import MarshalerFactory
18
20
  from ..base.types import Unmarshaler
19
- from ..factories.simple import SimpleMarshalerFactory
20
- from ..factories.simple import SimpleUnmarshalerFactory
21
+ from ..base.types import UnmarshalerFactory
21
22
  from ..naming import Naming
22
23
  from ..naming import translate_name
23
24
  from .marshal import ObjectMarshaler
@@ -159,19 +160,37 @@ def get_dataclass_field_infos(
159
160
  return FieldInfos(ret)
160
161
 
161
162
 
162
- def _make_field_obj(
163
- ctx,
164
- ty,
165
- obj,
166
- fac,
167
- fac_attr,
163
+ ##
164
+
165
+
166
+ def _make_field_marshal_obj(
167
+ ctx: MarshalFactoryContext,
168
+ ty: ta.Any,
169
+ obj: Marshaler | None,
170
+ fac: MarshalerFactory | None,
168
171
  ):
169
172
  if obj is not None:
170
173
  return obj
171
174
  if fac is not None:
172
- return getattr(fac, fac_attr)(ctx, ty)
173
- return ctx.make(ty)
175
+ if (m := fac.make_marshaler(ctx, ty)) is None:
176
+ raise UnhandledTypeError(ty)
177
+ return m()
178
+ return ctx.make_marshaler(ty)
179
+
174
180
 
181
+ def _make_field_unmarshal_obj(
182
+ ctx: UnmarshalFactoryContext,
183
+ ty: ta.Any,
184
+ obj: Unmarshaler | None,
185
+ fac: UnmarshalerFactory | None,
186
+ ):
187
+ if obj is not None:
188
+ return obj
189
+ if fac is not None:
190
+ if (m := fac.make_unmarshaler(ctx, ty)) is None:
191
+ raise UnhandledTypeError(ty)
192
+ return m()
193
+ return ctx.make_unmarshaler(ty)
175
194
 
176
195
  ##
177
196
 
@@ -200,119 +219,123 @@ def _type_or_generic_base(rty: rfl.Type) -> type | None:
200
219
  return None
201
220
 
202
221
 
203
- class DataclassMarshalerFactory(AbstractDataclassFactory, SimpleMarshalerFactory):
204
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
205
- return (
222
+ class DataclassMarshalerFactory(AbstractDataclassFactory, MarshalerFactory):
223
+ def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
224
+ if not (
206
225
  (ty := _type_or_generic_base(rty)) is not None and
207
226
  dc.is_dataclass(ty) and
208
227
  not lang.is_abstract_class(ty)
209
- )
228
+ ):
229
+ return None
230
+
231
+ def inner() -> Marshaler:
232
+ ty = check.isinstance(_type_or_generic_base(rty), type)
233
+ check.state(dc.is_dataclass(ty))
234
+ check.state(not lang.is_abstract_class(ty))
235
+
236
+ dc_md = self._get_metadata(ty)
237
+ fis = self._get_field_infos(ty, ctx.options)
238
+
239
+ fields = [
240
+ (
241
+ fi,
242
+ _make_field_marshal_obj(
243
+ ctx,
244
+ fi.type,
245
+ fi.metadata.marshaler,
246
+ fi.metadata.marshaler_factory,
247
+ ),
248
+ )
249
+ for fi in fis
250
+ if fi.name not in dc_md.specials.set
251
+ ]
210
252
 
211
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
212
- ty = check.isinstance(_type_or_generic_base(rty), type)
213
- check.state(dc.is_dataclass(ty))
214
- check.state(not lang.is_abstract_class(ty))
215
-
216
- dc_md = self._get_metadata(ty)
217
- fis = self._get_field_infos(ty, ctx.options)
218
-
219
- fields = [
220
- (
221
- fi,
222
- _make_field_obj(
223
- ctx,
224
- fi.type,
225
- fi.metadata.marshaler,
226
- fi.metadata.marshaler_factory,
227
- 'make_marshaler',
228
- ),
253
+ return ObjectMarshaler(
254
+ fields,
255
+ specials=dc_md.specials,
229
256
  )
230
- for fi in fis
231
- if fi.name not in dc_md.specials.set
232
- ]
233
257
 
234
- return ObjectMarshaler(
235
- fields,
236
- specials=dc_md.specials,
237
- )
258
+ return inner
238
259
 
239
260
 
240
261
  ##
241
262
 
242
263
 
243
- class DataclassUnmarshalerFactory(AbstractDataclassFactory, SimpleUnmarshalerFactory):
244
- def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
245
- return (
264
+ class DataclassUnmarshalerFactory(AbstractDataclassFactory, UnmarshalerFactory):
265
+ def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
266
+ if not (
246
267
  (ty := _type_or_generic_base(rty)) is not None and
247
268
  dc.is_dataclass(ty) and
248
269
  not lang.is_abstract_class(ty)
249
- )
270
+ ):
271
+ return None
250
272
 
251
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
252
- ty = check.isinstance(_type_or_generic_base(rty), type)
253
- check.state(dc.is_dataclass(ty))
254
- check.state(not lang.is_abstract_class(ty))
273
+ def inner() -> Unmarshaler:
274
+ ty = check.isinstance(_type_or_generic_base(rty), type)
275
+ check.state(dc.is_dataclass(ty))
276
+ check.state(not lang.is_abstract_class(ty))
255
277
 
256
- dc_md = self._get_metadata(ty)
257
- fis = self._get_field_infos(ty, ctx.options)
278
+ dc_md = self._get_metadata(ty)
279
+ fis = self._get_field_infos(ty, ctx.options)
258
280
 
259
- d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
260
- defaults: dict[str, ta.Any] = {}
261
- embeds: dict[str, type] = {}
262
- embeds_by_unmarshal_name: dict[str, tuple[str, str]] = {}
281
+ d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
282
+ defaults: dict[str, ta.Any] = {}
283
+ embeds: dict[str, type] = {}
284
+ embeds_by_unmarshal_name: dict[str, tuple[str, str]] = {}
263
285
 
264
- def add_field(fi: FieldInfo, *, prefixes: ta.Iterable[str] = ('',)) -> ta.Iterable[str]:
265
- ret: list[str] = []
286
+ def add_field(fi: FieldInfo, *, prefixes: ta.Iterable[str] = ('',)) -> ta.Iterable[str]:
287
+ ret: list[str] = []
266
288
 
267
- if fi.options.embed:
268
- e_ty = check.isinstance(fi.type, type)
269
- check.state(dc.is_dataclass(e_ty))
270
- e_dc_md = get_dataclass_metadata(e_ty)
271
- if e_dc_md.specials.set:
272
- raise Exception(f'Embedded fields cannot have specials: {e_ty}')
289
+ if fi.options.embed:
290
+ e_ty = check.isinstance(fi.type, type)
291
+ check.state(dc.is_dataclass(e_ty))
292
+ e_dc_md = get_dataclass_metadata(e_ty)
293
+ if e_dc_md.specials.set:
294
+ raise Exception(f'Embedded fields cannot have specials: {e_ty}')
273
295
 
274
- embeds[fi.name] = e_ty
275
- for e_fi in self._get_field_infos(e_ty, ctx.options):
276
- e_ns = add_field(e_fi, prefixes=[p + ep for p in prefixes for ep in fi.unmarshal_names])
277
- embeds_by_unmarshal_name.update({e_f: (fi.name, e_fi.name) for e_f in e_ns})
278
- ret.extend(e_ns)
296
+ embeds[fi.name] = e_ty
297
+ for e_fi in self._get_field_infos(e_ty, ctx.options):
298
+ e_ns = add_field(e_fi, prefixes=[p + ep for p in prefixes for ep in fi.unmarshal_names])
299
+ embeds_by_unmarshal_name.update({e_f: (fi.name, e_fi.name) for e_f in e_ns})
300
+ ret.extend(e_ns)
279
301
 
280
- else:
281
- tup = (
282
- fi,
283
- _make_field_obj(
284
- ctx,
285
- fi.type,
286
- fi.metadata.unmarshaler,
287
- fi.metadata.unmarshaler_factory,
288
- 'make_unmarshaler',
289
- ),
290
- )
302
+ else:
303
+ tup = (
304
+ fi,
305
+ _make_field_unmarshal_obj(
306
+ ctx,
307
+ fi.type,
308
+ fi.metadata.unmarshaler,
309
+ fi.metadata.unmarshaler_factory,
310
+ ),
311
+ )
291
312
 
292
- for pfx in prefixes:
293
- for un in fi.unmarshal_names:
294
- un = pfx + un
295
- if un in d:
296
- raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
297
- d[un] = tup
298
- ret.append(un)
299
-
300
- if fi.options.default.present:
301
- defaults[fi.name] = fi.options.default.must()
302
-
303
- return ret
304
-
305
- for fi in fis:
306
- if fi.name in dc_md.specials.set:
307
- continue
308
- add_field(fi)
309
-
310
- return ObjectUnmarshaler(
311
- ty,
312
- d,
313
- specials=dc_md.specials,
314
- defaults=defaults,
315
- embeds=embeds,
316
- embeds_by_unmarshal_name=embeds_by_unmarshal_name,
317
- ignore_unknown=dc_md.ignore_unknown,
318
- )
313
+ for pfx in prefixes:
314
+ for un in fi.unmarshal_names:
315
+ un = pfx + un
316
+ if un in d:
317
+ raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
318
+ d[un] = tup
319
+ ret.append(un)
320
+
321
+ if fi.options.default.present:
322
+ defaults[fi.name] = fi.options.default.must()
323
+
324
+ return ret
325
+
326
+ for fi in fis:
327
+ if fi.name in dc_md.specials.set:
328
+ continue
329
+ add_field(fi)
330
+
331
+ return ObjectUnmarshaler(
332
+ ty,
333
+ d,
334
+ specials=dc_md.specials,
335
+ defaults=defaults,
336
+ embeds=embeds,
337
+ embeds_by_unmarshal_name=embeds_by_unmarshal_name,
338
+ ignore_unknown=dc_md.ignore_unknown,
339
+ )
340
+
341
+ return inner
@@ -5,9 +5,10 @@ from ... import check
5
5
  from ... import dataclasses as dc
6
6
  from ... import reflect as rfl
7
7
  from ..base.contexts import MarshalContext
8
+ from ..base.contexts import MarshalFactoryContext
8
9
  from ..base.types import Marshaler
10
+ from ..base.types import MarshalerFactory
9
11
  from ..base.values import Value
10
- from ..factories.simple import SimpleMarshalerFactory
11
12
  from .metadata import FieldInfo
12
13
  from .metadata import FieldInfos
13
14
  from .metadata import ObjectSpecials
@@ -29,12 +30,12 @@ class ObjectMarshaler(Marshaler):
29
30
  @classmethod
30
31
  def make(
31
32
  cls,
32
- ctx: MarshalContext,
33
+ ctx: MarshalFactoryContext,
33
34
  fis: FieldInfos,
34
35
  **kwargs: ta.Any,
35
36
  ) -> Marshaler:
36
37
  fields = [
37
- (fi, ctx.make(fi.type))
38
+ (fi, ctx.make_marshaler(fi.type))
38
39
  for fi in fis
39
40
  ]
40
41
 
@@ -86,23 +87,26 @@ class ObjectMarshaler(Marshaler):
86
87
 
87
88
 
88
89
  @dc.dataclass(frozen=True)
89
- class SimpleObjectMarshalerFactory(SimpleMarshalerFactory):
90
+ class SimpleObjectMarshalerFactory(MarshalerFactory):
90
91
  dct: ta.Mapping[type, ta.Sequence[FieldInfo]]
91
92
 
92
93
  _: dc.KW_ONLY
93
94
 
94
95
  specials: ObjectSpecials = ObjectSpecials()
95
96
 
96
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
97
- return isinstance(rty, type) and rty in self.dct
97
+ def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
98
+ if not (isinstance(rty, type) and rty in self.dct):
99
+ return None
98
100
 
99
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
100
- ty = check.isinstance(rty, type)
101
+ def inner() -> Marshaler:
102
+ ty = check.isinstance(rty, type)
101
103
 
102
- fis = FieldInfos(self.dct[ty])
104
+ fis = FieldInfos(self.dct[ty])
103
105
 
104
- return ObjectMarshaler.make(
105
- ctx,
106
- fis,
107
- specials=self.specials,
108
- )
106
+ return ObjectMarshaler.make(
107
+ ctx,
108
+ fis,
109
+ specials=self.specials,
110
+ )
111
+
112
+ return inner
@@ -5,13 +5,13 @@ from ... import check
5
5
  from ... import collections as col
6
6
  from ... import lang
7
7
  from ... import reflect as rfl
8
- from ..base.contexts import MarshalContext
9
- from ..base.contexts import UnmarshalContext
8
+ from ..base.contexts import MarshalFactoryContext
9
+ from ..base.contexts import UnmarshalFactoryContext
10
10
  from ..base.options import Option
11
11
  from ..base.types import Marshaler
12
+ from ..base.types import MarshalerFactory
12
13
  from ..base.types import Unmarshaler
13
- from ..factories.simple import SimpleMarshalerFactory
14
- from ..factories.simple import SimpleUnmarshalerFactory
14
+ from ..base.types import UnmarshalerFactory
15
15
  from .marshal import ObjectMarshaler
16
16
  from .metadata import FieldInfo
17
17
  from .metadata import FieldInfos
@@ -55,57 +55,63 @@ def get_namedtuple_field_infos(
55
55
  ##
56
56
 
57
57
 
58
- class NamedtupleMarshalerFactory(SimpleMarshalerFactory):
59
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
60
- return _is_namedtuple(rty)
58
+ class NamedtupleMarshalerFactory(MarshalerFactory):
59
+ def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
60
+ if not _is_namedtuple(rty):
61
+ return None
61
62
 
62
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
63
- check.state(_is_namedtuple(rty))
64
- ty = check.isinstance(rty, type)
65
- check.state(not lang.is_abstract_class(ty))
63
+ def inner() -> Marshaler:
64
+ check.state(_is_namedtuple(rty))
65
+ ty = check.isinstance(rty, type)
66
+ check.state(not lang.is_abstract_class(ty))
66
67
 
67
- fis = get_namedtuple_field_infos(ty, ctx.options)
68
+ fis = get_namedtuple_field_infos(ty, ctx.options)
68
69
 
69
- fields = [
70
- (fi, ctx.make(fi.type))
71
- for fi in fis
72
- ]
70
+ fields = [
71
+ (fi, ctx.make_marshaler(fi.type))
72
+ for fi in fis
73
+ ]
73
74
 
74
- return ObjectMarshaler(
75
- fields,
76
- )
75
+ return ObjectMarshaler(
76
+ fields,
77
+ )
78
+
79
+ return inner
77
80
 
78
81
 
79
82
  ##
80
83
 
81
84
 
82
- class NamedtupleUnmarshalerFactory(SimpleUnmarshalerFactory):
83
- def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
84
- return _is_namedtuple(rty)
85
+ class NamedtupleUnmarshalerFactory(UnmarshalerFactory):
86
+ def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
87
+ if not _is_namedtuple(rty):
88
+ return None
89
+
90
+ def inner() -> Unmarshaler:
91
+ check.state(_is_namedtuple(rty))
92
+ ty = check.isinstance(rty, type)
93
+ check.state(not lang.is_abstract_class(ty))
85
94
 
86
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
87
- check.state(_is_namedtuple(rty))
88
- ty = check.isinstance(rty, type)
89
- check.state(not lang.is_abstract_class(ty))
95
+ fis = get_namedtuple_field_infos(ty, ctx.options)
90
96
 
91
- fis = get_namedtuple_field_infos(ty, ctx.options)
97
+ d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
98
+ defaults: dict[str, ta.Any] = {}
92
99
 
93
- d: dict[str, tuple[FieldInfo, Unmarshaler]] = {}
94
- defaults: dict[str, ta.Any] = {}
100
+ for fi in fis:
101
+ tup = (fi, ctx.make_unmarshaler(fi.type))
95
102
 
96
- for fi in fis:
97
- tup = (fi, ctx.make(fi.type))
103
+ for un in fi.unmarshal_names:
104
+ if un in d:
105
+ raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
106
+ d[un] = tup
98
107
 
99
- for un in fi.unmarshal_names:
100
- if un in d:
101
- raise KeyError(f'Duplicate fields for name {un!r}: {fi.name!r}, {d[un][0].name!r}')
102
- d[un] = tup
108
+ if fi.options.default.present:
109
+ defaults[fi.name] = fi.options.default.must()
103
110
 
104
- if fi.options.default.present:
105
- defaults[fi.name] = fi.options.default.must()
111
+ return ObjectUnmarshaler(
112
+ ty,
113
+ d,
114
+ defaults=defaults,
115
+ )
106
116
 
107
- return ObjectUnmarshaler(
108
- ty,
109
- d,
110
- defaults=defaults,
111
- )
117
+ return inner
@@ -5,9 +5,10 @@ from ... import check
5
5
  from ... import dataclasses as dc
6
6
  from ... import reflect as rfl
7
7
  from ..base.contexts import UnmarshalContext
8
+ from ..base.contexts import UnmarshalFactoryContext
8
9
  from ..base.types import Unmarshaler
10
+ from ..base.types import UnmarshalerFactory
9
11
  from ..base.values import Value
10
- from ..factories.simple import SimpleUnmarshalerFactory
11
12
  from .metadata import FieldInfo
12
13
  from .metadata import FieldInfos
13
14
  from .metadata import ObjectSpecials
@@ -35,13 +36,13 @@ class ObjectUnmarshaler(Unmarshaler):
35
36
  @classmethod
36
37
  def make(
37
38
  cls,
38
- ctx: UnmarshalContext,
39
+ ctx: UnmarshalFactoryContext,
39
40
  factory: ta.Callable,
40
41
  fis: FieldInfos,
41
42
  **kwargs: ta.Any,
42
43
  ) -> Unmarshaler:
43
44
  fields_by_unmarshal_name = {
44
- n: (fi, ctx.make(fi.type))
45
+ n: (fi, ctx.make_unmarshaler(fi.type))
45
46
  for fi in fis
46
47
  for n in fi.unmarshal_names
47
48
  }
@@ -118,24 +119,27 @@ class ObjectUnmarshaler(Unmarshaler):
118
119
 
119
120
 
120
121
  @dc.dataclass(frozen=True)
121
- class SimpleObjectUnmarshalerFactory(SimpleUnmarshalerFactory):
122
+ class SimpleObjectUnmarshalerFactory(UnmarshalerFactory):
122
123
  dct: ta.Mapping[type, ta.Sequence[FieldInfo]]
123
124
 
124
125
  _: dc.KW_ONLY
125
126
 
126
127
  specials: ObjectSpecials = ObjectSpecials()
127
128
 
128
- def guard(self, ctx: UnmarshalContext, rty: rfl.Type) -> bool:
129
- return isinstance(rty, type) and rty in self.dct
129
+ def make_unmarshaler(self, ctx: UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Unmarshaler] | None:
130
+ if not (isinstance(rty, type) and rty in self.dct):
131
+ return None
130
132
 
131
- def fn(self, ctx: UnmarshalContext, rty: rfl.Type) -> Unmarshaler:
132
- ty = check.isinstance(rty, type)
133
+ def inner() -> Unmarshaler:
134
+ ty = check.isinstance(rty, type)
133
135
 
134
- fis = FieldInfos(self.dct[ty])
136
+ fis = FieldInfos(self.dct[ty])
135
137
 
136
- return ObjectUnmarshaler.make(
137
- ctx,
138
- ty,
139
- fis,
140
- specials=self.specials,
141
- )
138
+ return ObjectUnmarshaler.make(
139
+ ctx,
140
+ ty,
141
+ fis,
142
+ specials=self.specials,
143
+ )
144
+
145
+ return inner
@@ -2,13 +2,13 @@ import abc
2
2
  import dataclasses as dc
3
3
  import typing as ta
4
4
 
5
- from ... import check
6
5
  from ... import lang
7
6
  from ... import reflect as rfl
8
7
  from ..base.contexts import MarshalContext
8
+ from ..base.contexts import MarshalFactoryContext
9
9
  from ..base.types import Marshaler
10
+ from ..base.types import MarshalerFactory
10
11
  from ..base.values import Value
11
- from ..factories.simple import SimpleMarshalerFactory
12
12
  from .metadata import FieldTypeTagging
13
13
  from .metadata import Impls
14
14
  from .metadata import Polymorphism
@@ -53,10 +53,10 @@ class FieldPolymorphismMarshaler(PolymorphismMarshaler):
53
53
  def make_polymorphism_marshaler(
54
54
  impls: Impls,
55
55
  tt: TypeTagging,
56
- ctx: MarshalContext,
56
+ ctx: MarshalFactoryContext,
57
57
  ) -> Marshaler:
58
58
  m = {
59
- i.ty: (i.tag, ctx.make(i.ty))
59
+ i.ty: (i.tag, ctx.make_marshaler(i.ty))
60
60
  for i in impls
61
61
  }
62
62
  if isinstance(tt, WrapperTypeTagging):
@@ -68,13 +68,11 @@ def make_polymorphism_marshaler(
68
68
 
69
69
 
70
70
  @dc.dataclass(frozen=True)
71
- class PolymorphismMarshalerFactory(SimpleMarshalerFactory):
71
+ class PolymorphismMarshalerFactory(MarshalerFactory):
72
72
  p: Polymorphism
73
73
  tt: TypeTagging = WrapperTypeTagging()
74
74
 
75
- def guard(self, ctx: MarshalContext, rty: rfl.Type) -> bool:
76
- return rty is self.p.ty
77
-
78
- def fn(self, ctx: MarshalContext, rty: rfl.Type) -> Marshaler:
79
- check.is_(rty, self.p.ty)
80
- return make_polymorphism_marshaler(self.p.impls, self.tt, ctx)
75
+ def make_marshaler(self, ctx: MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], Marshaler] | None:
76
+ if rty is not self.p.ty:
77
+ return None
78
+ return lambda: make_polymorphism_marshaler(self.p.impls, self.tt, ctx)
@@ -107,23 +107,34 @@ class Polymorphism:
107
107
  return self._impls
108
108
 
109
109
 
110
+ class AutoStripSuffix(lang.Marker):
111
+ pass
112
+
113
+
110
114
  def polymorphism_from_impls(
111
115
  ty: type,
112
116
  impls: ta.Iterable[type],
113
117
  *,
114
118
  naming: Naming | None = None,
115
- strip_suffix: bool | ta.Literal['auto'] = False,
119
+ strip_suffix: bool | type[AutoStripSuffix] | str = False,
116
120
  ) -> Polymorphism:
117
121
  impls = set(impls)
118
122
 
119
- if strip_suffix == 'auto':
123
+ ssx: str | None
124
+ if strip_suffix is AutoStripSuffix:
120
125
  strip_suffix = all(c.__name__.endswith(ty.__name__) for c in impls)
126
+ if isinstance(strip_suffix, bool):
127
+ ssx = ty.__name__ if strip_suffix else None
128
+ elif isinstance(strip_suffix, str):
129
+ ssx = strip_suffix
130
+ else:
131
+ raise TypeError(strip_suffix)
121
132
 
122
133
  dct: dict[str, Impl] = {}
123
134
  for cur in impls:
124
135
  name = cur.__name__
125
- if strip_suffix:
126
- name = lang.strip_suffix(name, ty.__name__)
136
+ if ssx is not None:
137
+ name = lang.strip_suffix(name, ssx)
127
138
  if naming is not None:
128
139
  name = translate_name(name, naming)
129
140
  if name in dct:
@@ -141,7 +152,7 @@ def polymorphism_from_subclasses(
141
152
  ty: type,
142
153
  *,
143
154
  naming: Naming | None = None,
144
- strip_suffix: bool | ta.Literal['auto'] = False,
155
+ strip_suffix: bool | type[AutoStripSuffix] | str = False,
145
156
  ) -> Polymorphism:
146
157
  return polymorphism_from_impls(
147
158
  ty,
@@ -6,6 +6,8 @@ from .marshal import PolymorphismMarshalerFactory
6
6
  from .metadata import Polymorphism
7
7
  from .metadata import TypeTagging
8
8
  from .metadata import WrapperTypeTagging
9
+ from .unions import PolymorphismUnionMarshalerFactory
10
+ from .unions import PolymorphismUnionUnmarshalerFactory
9
11
  from .unmarshal import PolymorphismUnmarshalerFactory
10
12
 
11
13
 
@@ -15,8 +17,18 @@ from .unmarshal import PolymorphismUnmarshalerFactory
15
17
  def standard_polymorphism_factories(
16
18
  poly: Polymorphism,
17
19
  tt: TypeTagging = WrapperTypeTagging(),
20
+ *,
21
+ unions: bool | ta.Literal['partial'] = False,
18
22
  ) -> ta.Sequence[MarshalerFactory | UnmarshalerFactory]:
19
- return [
23
+ out: list[MarshalerFactory | UnmarshalerFactory] = [
20
24
  PolymorphismMarshalerFactory(poly, tt),
21
25
  PolymorphismUnmarshalerFactory(poly, tt),
22
26
  ]
27
+
28
+ if unions:
29
+ out.extend([
30
+ PolymorphismUnionMarshalerFactory(poly.impls, tt, allow_partial=unions == 'partial'),
31
+ PolymorphismUnionUnmarshalerFactory(poly.impls, tt, allow_partial=unions == 'partial'),
32
+ ])
33
+
34
+ return out