omlish 0.0.0.dev213__py3-none-any.whl → 0.0.0.dev214__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 (32) hide show
  1. omlish/.manifests.json +4 -4
  2. omlish/__about__.py +3 -5
  3. omlish/antlr/__init__.py +3 -0
  4. omlish/antlr/parsing.py +34 -2
  5. omlish/asyncs/asyncio/asyncio.py +34 -0
  6. omlish/asyncs/ioproxy/all.py +32 -0
  7. omlish/asyncs/ioproxy/io.py +13 -13
  8. omlish/asyncs/ioproxy/proxier.py +30 -30
  9. omlish/asyncs/ioproxy/typing.py +3 -3
  10. omlish/formats/json/stream/lex.py +1 -0
  11. omlish/formats/json5/Json5.g4 +172 -0
  12. omlish/formats/json5/__init__.py +8 -0
  13. omlish/formats/json5/_antlr/Json5Lexer.py +353 -0
  14. omlish/formats/json5/_antlr/Json5Listener.py +78 -0
  15. omlish/formats/json5/_antlr/Json5Parser.py +616 -0
  16. omlish/formats/json5/_antlr/Json5Visitor.py +51 -0
  17. omlish/formats/json5/_antlr/__init__.py +0 -0
  18. omlish/formats/{json5.py → json5/codec.py} +6 -11
  19. omlish/formats/json5/errors.py +2 -0
  20. omlish/formats/json5/literals.py +130 -0
  21. omlish/formats/json5/parsing.py +79 -0
  22. omlish/lang/__init__.py +2 -0
  23. omlish/lang/imports.py +4 -0
  24. omlish/lang/strings.py +33 -1
  25. omlish/os/files.py +17 -30
  26. omlish/os/temp.py +50 -0
  27. {omlish-0.0.0.dev213.dist-info → omlish-0.0.0.dev214.dist-info}/METADATA +5 -7
  28. {omlish-0.0.0.dev213.dist-info → omlish-0.0.0.dev214.dist-info}/RECORD +32 -20
  29. {omlish-0.0.0.dev213.dist-info → omlish-0.0.0.dev214.dist-info}/LICENSE +0 -0
  30. {omlish-0.0.0.dev213.dist-info → omlish-0.0.0.dev214.dist-info}/WHEEL +0 -0
  31. {omlish-0.0.0.dev213.dist-info → omlish-0.0.0.dev214.dist-info}/entry_points.txt +0 -0
  32. {omlish-0.0.0.dev213.dist-info → omlish-0.0.0.dev214.dist-info}/top_level.txt +0 -0
omlish/.manifests.json CHANGED
@@ -108,13 +108,13 @@
108
108
  }
109
109
  },
110
110
  {
111
- "module": ".formats.json5",
111
+ "module": ".formats.json5.codec",
112
112
  "attr": "_JSON5_LAZY_CODEC",
113
- "file": "omlish/formats/json5.py",
114
- "line": 30,
113
+ "file": "omlish/formats/json5/codec.py",
114
+ "line": 25,
115
115
  "value": {
116
116
  "$.codecs.base.LazyLoadedCodec": {
117
- "mod_name": "omlish.formats.json5",
117
+ "mod_name": "omlish.formats.json5.codec",
118
118
  "attr_name": "JSON5_CODEC",
119
119
  "name": "json5",
120
120
  "aliases": null
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev213'
2
- __revision__ = '03c9d6a7f92cec54535af989bf531b8598a896c0'
1
+ __version__ = '0.0.0.dev214'
2
+ __revision__ = '9512c6d71a63bb51772d9183f0205459f229de64'
3
3
 
4
4
 
5
5
  #
@@ -54,7 +54,7 @@ class Project(ProjectBase):
54
54
 
55
55
  'diag': [
56
56
  'asttokens ~= 3.0',
57
- 'executing ~= 2.1',
57
+ 'executing ~= 2.2',
58
58
 
59
59
  'psutil ~= 6.0',
60
60
  ],
@@ -63,8 +63,6 @@ class Project(ProjectBase):
63
63
  'orjson ~= 3.10',
64
64
  'ujson ~= 5.10',
65
65
 
66
- 'json5 ~= 0.9',
67
-
68
66
  'pyyaml ~= 6.0',
69
67
 
70
68
  'cbor2 ~= 5.6',
omlish/antlr/__init__.py CHANGED
@@ -0,0 +1,3 @@
1
+ from . import errors # noqa
2
+ from . import parsing # noqa
3
+ from . import runtime # noqa
omlish/antlr/parsing.py CHANGED
@@ -1,19 +1,51 @@
1
1
  # ruff: noqa: N802 N803
2
2
  import typing as ta
3
3
 
4
+ from .. import check
4
5
  from . import runtime as antlr4
6
+ from .errors import SilentRaisingErrorListener
5
7
 
6
8
 
7
9
  LexerT = ta.TypeVar('LexerT', bound=antlr4.Lexer)
8
10
  ParserT = ta.TypeVar('ParserT', bound=antlr4.Parser)
9
11
 
10
12
 
11
- def parse(
13
+ def is_eof_context(ctx: antlr4.ParserRuleContext) -> bool:
14
+ return ctx.getChildCount() == 1 and ctx.getChild(0).getSymbol().type == antlr4.Token.EOF
15
+
16
+
17
+ class StandardParseTreeVisitor(antlr4.ParseTreeVisitor):
18
+ def visit(self, ctx: antlr4.ParserRuleContext):
19
+ check.isinstance(ctx, antlr4.ParserRuleContext)
20
+ return ctx.accept(self)
21
+
22
+ def aggregateResult(self, aggregate, nextResult): # noqa
23
+ if aggregate is not None:
24
+ check.none(nextResult)
25
+ return aggregate
26
+ else:
27
+ check.none(aggregate)
28
+ return nextResult
29
+
30
+
31
+ def make_parser(
12
32
  buf: str,
13
33
  lexer_cls: type[LexerT],
14
34
  parser_cls: type[ParserT],
35
+ *,
36
+ silent_errors: bool = False,
15
37
  ) -> ParserT:
16
38
  lexer = lexer_cls(antlr4.InputStream(buf))
39
+ if silent_errors:
40
+ lexer.removeErrorListeners()
41
+ lexer.addErrorListener(SilentRaisingErrorListener())
42
+
17
43
  stream = antlr4.CommonTokenStream(lexer)
18
44
  stream.fill()
19
- return parser_cls(stream)
45
+
46
+ parser = parser_cls(stream)
47
+ if silent_errors:
48
+ parser.removeErrorListeners()
49
+ parser.addErrorListener(SilentRaisingErrorListener())
50
+
51
+ return parser
@@ -1,9 +1,13 @@
1
+ # ruff: noqa: UP006 UP007
2
+ # @omlish-lite
1
3
  import asyncio
2
4
  import contextlib
3
5
  import functools
4
6
  import typing as ta
5
7
 
6
8
 
9
+ T = ta.TypeVar('T')
10
+
7
11
  CallableT = ta.TypeVar('CallableT', bound=ta.Callable)
8
12
 
9
13
 
@@ -36,3 +40,33 @@ def draining_asyncio_tasks() -> ta.Iterator[None]:
36
40
  finally:
37
41
  if loop is not None:
38
42
  drain_tasks(loop) # noqa
43
+
44
+
45
+ async def asyncio_wait_concurrent(
46
+ coros: ta.Iterable[ta.Awaitable[T]],
47
+ concurrency: ta.Union[int, asyncio.Semaphore],
48
+ *,
49
+ return_when: ta.Any = asyncio.FIRST_EXCEPTION,
50
+ ) -> ta.List[T]:
51
+ if isinstance(concurrency, asyncio.Semaphore):
52
+ semaphore = concurrency
53
+ elif isinstance(concurrency, int):
54
+ semaphore = asyncio.Semaphore(concurrency)
55
+ else:
56
+ raise TypeError(concurrency)
57
+
58
+ async def limited_task(coro):
59
+ async with semaphore:
60
+ return await coro
61
+
62
+ tasks = [asyncio.create_task(limited_task(coro)) for coro in coros]
63
+ done, pending = await asyncio.wait(tasks, return_when=return_when)
64
+
65
+ for task in pending:
66
+ task.cancel()
67
+
68
+ for task in done:
69
+ if task.exception():
70
+ raise task.exception() # type: ignore
71
+
72
+ return [task.result() for task in done]
@@ -0,0 +1,32 @@
1
+ from .io import ( # noqa
2
+ BufferedIOBase_AsyncIoProxy as BufferedIOBase,
3
+ BufferedRandom_AsyncIoProxy as BufferedRandom,
4
+ BufferedReader_AsyncIoProxy as BufferedReader,
5
+ BufferedRWPair_AsyncIoProxy as BufferedRWPair,
6
+ BufferedWriter_AsyncIoProxy as BufferedWriter,
7
+ BytesIO_AsyncIoProxy as BytesIO,
8
+ FileIO_AsyncIoProxy as FileIO,
9
+ IOBase_AsyncIoProxy as IOBase,
10
+ RawIOBase_AsyncIoProxy as RawIOBase,
11
+ StringIO_AsyncIoProxy as StringIO,
12
+ TextIOBase_AsyncIoProxy as TextIOBase,
13
+ TextIOWrapper_AsyncIoProxy as TextIOWrapper,
14
+ )
15
+
16
+ from .proxier import ( # noqa
17
+ AsyncIoProxier as Proxier,
18
+ )
19
+
20
+ from .proxy import ( # noqa
21
+ AsyncIoProxy as Proxy,
22
+ AsyncIoProxyRunner as Runer,
23
+ AsyncIoProxyTarget as Target,
24
+ async_io_proxy_cls_for as proxy_cls_for,
25
+ async_io_proxy_fn as proxy_fn,
26
+ )
27
+
28
+ from .typing import ( # noqa
29
+ TypingBinaryIO_AsyncIoProxy as TypingBinaryIO,
30
+ TypingIO_AsyncIoProxy as TypingIO,
31
+ TypingTextIO_AsyncIoProxy as TypingTextIO,
32
+ )
@@ -13,7 +13,7 @@ SelfT = ta.TypeVar('SelfT')
13
13
 
14
14
 
15
15
  @_register_async_io_proxy_cls
16
- class IOBaseAsyncIoProxy(AsyncIoProxy, proxied_cls=io.IOBase):
16
+ class IOBase_AsyncIoProxy(AsyncIoProxy, proxied_cls=io.IOBase): # noqa
17
17
  # https://github.com/python/cpython/blob/e65a1eb93ae35f9fbab1508606e3fbc89123629f/Lib/_pyio.py#L305
18
18
 
19
19
  ##
@@ -91,7 +91,7 @@ class IOBaseAsyncIoProxy(AsyncIoProxy, proxied_cls=io.IOBase):
91
91
 
92
92
 
93
93
  @_register_async_io_proxy_cls
94
- class RawIOBaseAsyncIoProxy(IOBaseAsyncIoProxy, proxied_cls=io.RawIOBase):
94
+ class RawIOBase_AsyncIoProxy(IOBase_AsyncIoProxy, proxied_cls=io.RawIOBase): # noqa
95
95
  async def read(self, size=-1):
96
96
  raise TypeError
97
97
 
@@ -106,7 +106,7 @@ class RawIOBaseAsyncIoProxy(IOBaseAsyncIoProxy, proxied_cls=io.RawIOBase):
106
106
 
107
107
 
108
108
  @_register_async_io_proxy_cls
109
- class BufferedIOBaseAsyncIoProxy(IOBaseAsyncIoProxy, proxied_cls=io.BufferedIOBase):
109
+ class BufferedIOBase_AsyncIoProxy(IOBase_AsyncIoProxy, proxied_cls=io.BufferedIOBase): # noqa
110
110
  async def read(self, size=-1):
111
111
  raise TypeError
112
112
 
@@ -126,7 +126,7 @@ class BufferedIOBaseAsyncIoProxy(IOBaseAsyncIoProxy, proxied_cls=io.BufferedIOBa
126
126
  raise TypeError
127
127
 
128
128
 
129
- class BufferedIOMixinAsyncIoProxy(BufferedIOBaseAsyncIoProxy):
129
+ class BufferedIOMixin_AsyncIoProxy(BufferedIOBase_AsyncIoProxy): # noqa
130
130
  @property
131
131
  def raw(self):
132
132
  raise TypeError
@@ -141,7 +141,7 @@ class BufferedIOMixinAsyncIoProxy(BufferedIOBaseAsyncIoProxy):
141
141
 
142
142
 
143
143
  @_register_async_io_proxy_cls
144
- class BytesIOAsyncIoProxy(BufferedIOBaseAsyncIoProxy, proxied_cls=io.BytesIO):
144
+ class BytesIO_AsyncIoProxy(BufferedIOBase_AsyncIoProxy, proxied_cls=io.BytesIO): # noqa
145
145
  async def getvalue(self):
146
146
  raise TypeError
147
147
 
@@ -150,29 +150,29 @@ class BytesIOAsyncIoProxy(BufferedIOBaseAsyncIoProxy, proxied_cls=io.BytesIO):
150
150
 
151
151
 
152
152
  @_register_async_io_proxy_cls
153
- class BufferedReaderAsyncIoProxy(BufferedIOMixinAsyncIoProxy, proxied_cls=io.BufferedReader):
153
+ class BufferedReader_AsyncIoProxy(BufferedIOMixin_AsyncIoProxy, proxied_cls=io.BufferedReader): # noqa
154
154
  async def peek(self, size=0):
155
155
  raise TypeError
156
156
 
157
157
 
158
158
  @_register_async_io_proxy_cls
159
- class BufferedWriterAsyncIoProxy(BufferedIOMixinAsyncIoProxy, proxied_cls=io.BufferedWriter):
159
+ class BufferedWriter_AsyncIoProxy(BufferedIOMixin_AsyncIoProxy, proxied_cls=io.BufferedWriter): # noqa
160
160
  pass
161
161
 
162
162
 
163
163
  @_register_async_io_proxy_cls
164
- class BufferedRWPairAsyncIoProxy(BufferedIOBaseAsyncIoProxy, proxied_cls=io.BufferedRWPair):
164
+ class BufferedRWPair_AsyncIoProxy(BufferedIOBase_AsyncIoProxy, proxied_cls=io.BufferedRWPair): # noqa
165
165
  async def peek(self, size=0):
166
166
  raise TypeError
167
167
 
168
168
 
169
169
  @_register_async_io_proxy_cls
170
- class BufferedRandomAsyncIoProxy(BufferedWriterAsyncIoProxy, BufferedReaderAsyncIoProxy, proxied_cls=io.BufferedRandom):
170
+ class BufferedRandom_AsyncIoProxy(BufferedWriter_AsyncIoProxy, BufferedReader_AsyncIoProxy, proxied_cls=io.BufferedRandom): # noqa
171
171
  pass
172
172
 
173
173
 
174
174
  @_register_async_io_proxy_cls
175
- class FileIOAsyncIoProxy(RawIOBaseAsyncIoProxy, proxied_cls=io.FileIO):
175
+ class FileIO_AsyncIoProxy(RawIOBase_AsyncIoProxy, proxied_cls=io.FileIO): # noqa
176
176
  @property
177
177
  def closefd(self):
178
178
  raise TypeError
@@ -183,7 +183,7 @@ class FileIOAsyncIoProxy(RawIOBaseAsyncIoProxy, proxied_cls=io.FileIO):
183
183
 
184
184
 
185
185
  @_register_async_io_proxy_cls
186
- class TextIOBaseAsyncIoProxy(IOBaseAsyncIoProxy, proxied_cls=io.TextIOBase):
186
+ class TextIOBase_AsyncIoProxy(IOBase_AsyncIoProxy, proxied_cls=io.TextIOBase): # noqa
187
187
  async def read(self, size=-1):
188
188
  raise TypeError
189
189
 
@@ -207,7 +207,7 @@ class TextIOBaseAsyncIoProxy(IOBaseAsyncIoProxy, proxied_cls=io.TextIOBase):
207
207
 
208
208
 
209
209
  @_register_async_io_proxy_cls
210
- class TextIOWrapperAsyncIoProxy(TextIOBaseAsyncIoProxy, proxied_cls=io.TextIOWrapper):
210
+ class TextIOWrapper_AsyncIoProxy(TextIOBase_AsyncIoProxy, proxied_cls=io.TextIOWrapper): # noqa
211
211
  @property
212
212
  def line_buffering(self):
213
213
  raise TypeError
@@ -237,6 +237,6 @@ class TextIOWrapperAsyncIoProxy(TextIOBaseAsyncIoProxy, proxied_cls=io.TextIOWra
237
237
 
238
238
 
239
239
  @_register_async_io_proxy_cls
240
- class StringIOAsyncIoProxy(TextIOWrapperAsyncIoProxy, proxied_cls=io.StringIO):
240
+ class StringIO_AsyncIoProxy(TextIOWrapper_AsyncIoProxy, proxied_cls=io.StringIO): # noqa
241
241
  async def getvalue(self):
242
242
  raise TypeError
@@ -3,25 +3,25 @@ import io
3
3
  import types
4
4
  import typing as ta
5
5
 
6
- from .io import BufferedIOBaseAsyncIoProxy
7
- from .io import BufferedRandomAsyncIoProxy
8
- from .io import BufferedReaderAsyncIoProxy
9
- from .io import BufferedRWPairAsyncIoProxy
10
- from .io import BufferedWriterAsyncIoProxy
11
- from .io import BytesIOAsyncIoProxy
12
- from .io import FileIOAsyncIoProxy
13
- from .io import IOBaseAsyncIoProxy
14
- from .io import RawIOBaseAsyncIoProxy
15
- from .io import StringIOAsyncIoProxy
16
- from .io import TextIOBaseAsyncIoProxy
17
- from .io import TextIOWrapperAsyncIoProxy
6
+ from .io import BufferedIOBase_AsyncIoProxy
7
+ from .io import BufferedRandom_AsyncIoProxy
8
+ from .io import BufferedReader_AsyncIoProxy
9
+ from .io import BufferedRWPair_AsyncIoProxy
10
+ from .io import BufferedWriter_AsyncIoProxy
11
+ from .io import BytesIO_AsyncIoProxy
12
+ from .io import FileIO_AsyncIoProxy
13
+ from .io import IOBase_AsyncIoProxy
14
+ from .io import RawIOBase_AsyncIoProxy
15
+ from .io import StringIO_AsyncIoProxy
16
+ from .io import TextIOBase_AsyncIoProxy
17
+ from .io import TextIOWrapper_AsyncIoProxy
18
18
  from .proxy import AsyncIoProxyRunner
19
19
  from .proxy import AsyncIoProxyTarget
20
20
  from .proxy import async_io_proxy_cls_for
21
21
  from .proxy import async_io_proxy_fn
22
- from .typing import TypingBinaryIOAsyncIoProxy
23
- from .typing import TypingIOAsyncIoProxy
24
- from .typing import TypingTextIOAsyncIoProxy
22
+ from .typing import TypingBinaryIO_AsyncIoProxy
23
+ from .typing import TypingIO_AsyncIoProxy
24
+ from .typing import TypingTextIO_AsyncIoProxy
25
25
 
26
26
 
27
27
  ##
@@ -56,65 +56,65 @@ class AsyncIoProxier:
56
56
  ##
57
57
 
58
58
  @ta.overload
59
- def proxy_obj(self, obj: io.StringIO) -> StringIOAsyncIoProxy: # type: ignore[overload-overlap] # 1
59
+ def proxy_obj(self, obj: io.StringIO) -> StringIO_AsyncIoProxy: # type: ignore[overload-overlap] # 1
60
60
  ...
61
61
 
62
62
  @ta.overload
63
- def proxy_obj(self, obj: io.TextIOWrapper) -> TextIOWrapperAsyncIoProxy: # type: ignore[overload-overlap] # 2
63
+ def proxy_obj(self, obj: io.TextIOWrapper) -> TextIOWrapper_AsyncIoProxy: # type: ignore[overload-overlap] # 2
64
64
  ...
65
65
 
66
66
  @ta.overload
67
- def proxy_obj(self, obj: io.TextIOBase) -> TextIOBaseAsyncIoProxy: # 3
67
+ def proxy_obj(self, obj: io.TextIOBase) -> TextIOBase_AsyncIoProxy: # 3
68
68
  ...
69
69
 
70
70
  @ta.overload
71
- def proxy_obj(self, obj: io.FileIO) -> FileIOAsyncIoProxy: # type: ignore[overload-overlap] # 4
71
+ def proxy_obj(self, obj: io.FileIO) -> FileIO_AsyncIoProxy: # type: ignore[overload-overlap] # 4
72
72
  ...
73
73
 
74
74
  @ta.overload
75
- def proxy_obj(self, obj: io.BufferedRandom) -> BufferedRandomAsyncIoProxy: # type: ignore[overload-overlap] # 5
75
+ def proxy_obj(self, obj: io.BufferedRandom) -> BufferedRandom_AsyncIoProxy: # type: ignore[overload-overlap] # 5
76
76
  ...
77
77
 
78
78
  @ta.overload
79
- def proxy_obj(self, obj: io.BufferedRWPair) -> BufferedRWPairAsyncIoProxy: # 6
79
+ def proxy_obj(self, obj: io.BufferedRWPair) -> BufferedRWPair_AsyncIoProxy: # 6
80
80
  ...
81
81
 
82
82
  @ta.overload
83
- def proxy_obj(self, obj: io.BufferedWriter) -> BufferedWriterAsyncIoProxy: # type: ignore[overload-overlap] # 7
83
+ def proxy_obj(self, obj: io.BufferedWriter) -> BufferedWriter_AsyncIoProxy: # type: ignore[overload-overlap] # 7
84
84
  ...
85
85
 
86
86
  @ta.overload
87
- def proxy_obj(self, obj: io.BufferedReader) -> BufferedReaderAsyncIoProxy: # type: ignore[overload-overlap] # 8
87
+ def proxy_obj(self, obj: io.BufferedReader) -> BufferedReader_AsyncIoProxy: # type: ignore[overload-overlap] # 8
88
88
  ...
89
89
 
90
90
  @ta.overload
91
- def proxy_obj(self, obj: io.BytesIO) -> BytesIOAsyncIoProxy: # type: ignore[overload-overlap] # 9
91
+ def proxy_obj(self, obj: io.BytesIO) -> BytesIO_AsyncIoProxy: # type: ignore[overload-overlap] # 9
92
92
  ...
93
93
 
94
94
  @ta.overload
95
- def proxy_obj(self, obj: io.BufferedIOBase) -> BufferedIOBaseAsyncIoProxy: # 10
95
+ def proxy_obj(self, obj: io.BufferedIOBase) -> BufferedIOBase_AsyncIoProxy: # 10
96
96
  ...
97
97
 
98
98
  @ta.overload
99
- def proxy_obj(self, obj: io.RawIOBase) -> RawIOBaseAsyncIoProxy: # 11
99
+ def proxy_obj(self, obj: io.RawIOBase) -> RawIOBase_AsyncIoProxy: # 11
100
100
  ...
101
101
 
102
102
  @ta.overload
103
- def proxy_obj(self, obj: io.IOBase) -> IOBaseAsyncIoProxy: # 12
103
+ def proxy_obj(self, obj: io.IOBase) -> IOBase_AsyncIoProxy: # 12
104
104
  ...
105
105
 
106
106
  #
107
107
 
108
108
  @ta.overload
109
- def proxy_obj(self, obj: ta.TextIO) -> TypingTextIOAsyncIoProxy: # 13
109
+ def proxy_obj(self, obj: ta.TextIO) -> TypingTextIO_AsyncIoProxy: # 13
110
110
  ...
111
111
 
112
112
  @ta.overload
113
- def proxy_obj(self, obj: ta.BinaryIO) -> TypingBinaryIOAsyncIoProxy: # 14
113
+ def proxy_obj(self, obj: ta.BinaryIO) -> TypingBinaryIO_AsyncIoProxy: # 14
114
114
  ...
115
115
 
116
116
  @ta.overload
117
- def proxy_obj(self, obj: ta.IO) -> TypingIOAsyncIoProxy: # 15
117
+ def proxy_obj(self, obj: ta.IO) -> TypingIO_AsyncIoProxy: # 15
118
118
  ...
119
119
 
120
120
  #
@@ -14,7 +14,7 @@ AnyStrT = ta.TypeVar('AnyStrT', bytes, str)
14
14
 
15
15
 
16
16
  @_register_async_io_proxy_cls
17
- class TypingIOAsyncIoProxy(AsyncIoProxy, ta.Generic[AnyStrT], proxied_cls=ta.IO):
17
+ class TypingIO_AsyncIoProxy(AsyncIoProxy, ta.Generic[AnyStrT], proxied_cls=ta.IO): # noqa
18
18
  @property
19
19
  def mode(self) -> str:
20
20
  raise TypeError
@@ -80,13 +80,13 @@ class TypingIOAsyncIoProxy(AsyncIoProxy, ta.Generic[AnyStrT], proxied_cls=ta.IO)
80
80
 
81
81
 
82
82
  @_register_async_io_proxy_cls
83
- class TypingBinaryIOAsyncIoProxy(TypingIOAsyncIoProxy[bytes], proxied_cls=ta.BinaryIO):
83
+ class TypingBinaryIO_AsyncIoProxy(TypingIO_AsyncIoProxy[bytes], proxied_cls=ta.BinaryIO): # noqa
84
84
  def write(self, s: ta.Union[bytes, bytearray]) -> int: # type: ignore[override]
85
85
  raise TypeError
86
86
 
87
87
 
88
88
  @_register_async_io_proxy_cls
89
- class TypingTextIOAsyncIoProxy(TypingIOAsyncIoProxy[str], proxied_cls=ta.TextIO):
89
+ class TypingTextIO_AsyncIoProxy(TypingIO_AsyncIoProxy[str], proxied_cls=ta.TextIO): # noqa
90
90
  # @property
91
91
  # def buffer(self) -> BinaryIO:
92
92
  # pass
@@ -4,6 +4,7 @@ TODO:
4
4
  - max recursion depth
5
5
  - mark start pos of tokens, currently returning end
6
6
  - _do_string inner loop optimization somehow
7
+ - json5 mode
7
8
  """
8
9
  import dataclasses as dc
9
10
  import io
@@ -0,0 +1,172 @@
1
+ // Student Main
2
+ // 2020-07-22
3
+ // Public domain
4
+
5
+ // JSON5 is a superset of JSON, it included some feature from ES5.1
6
+ // See https://json5.org/
7
+ // Derived from ../json/JSON.g4 which original derived from http://json.org
8
+
9
+ // $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false
10
+ // $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging
11
+
12
+ grammar Json5;
13
+
14
+ json5
15
+ : value? EOF
16
+ ;
17
+
18
+ obj
19
+ : '{' pair (',' pair)* ','? '}'
20
+ | '{' '}'
21
+ ;
22
+
23
+ pair
24
+ : key ':' value
25
+ ;
26
+
27
+ key
28
+ : STRING
29
+ | IDENTIFIER
30
+ | LITERAL
31
+ | NUMERIC_LITERAL
32
+ ;
33
+
34
+ value
35
+ : STRING
36
+ | number
37
+ | obj
38
+ | arr
39
+ | LITERAL
40
+ ;
41
+
42
+ arr
43
+ : '[' value (',' value)* ','? ']'
44
+ | '[' ']'
45
+ ;
46
+
47
+ number
48
+ : SYMBOL? (NUMERIC_LITERAL | NUMBER)
49
+ ;
50
+
51
+ // Lexer
52
+
53
+ SINGLE_LINE_COMMENT
54
+ : '//' .*? (NEWLINE | EOF) -> skip
55
+ ;
56
+
57
+ MULTI_LINE_COMMENT
58
+ : '/*' .*? '*/' -> skip
59
+ ;
60
+
61
+ LITERAL
62
+ : 'true'
63
+ | 'false'
64
+ | 'null'
65
+ ;
66
+
67
+ STRING
68
+ : '"' DOUBLE_QUOTE_CHAR* '"'
69
+ | '\'' SINGLE_QUOTE_CHAR* '\''
70
+ ;
71
+
72
+ fragment DOUBLE_QUOTE_CHAR
73
+ : ~["\\\r\n]
74
+ | ESCAPE_SEQUENCE
75
+ ;
76
+
77
+ fragment SINGLE_QUOTE_CHAR
78
+ : ~['\\\r\n]
79
+ | ESCAPE_SEQUENCE
80
+ ;
81
+
82
+ fragment ESCAPE_SEQUENCE
83
+ : '\\' (
84
+ NEWLINE
85
+ | UNICODE_SEQUENCE // \u1234
86
+ | ['"\\/bfnrtv] // single escape char
87
+ | ~['"\\bfnrtv0-9xu\r\n] // non escape char
88
+ | '0' // \0
89
+ | 'x' HEX HEX // \x3a
90
+ )
91
+ ;
92
+
93
+ NUMBER
94
+ : INT ('.' [0-9]*)? EXP? // +1.e2, 1234, 1234.5
95
+ | '.' [0-9]+ EXP? // -.2e3
96
+ | '0' [xX] HEX+ // 0x12345678
97
+ ;
98
+
99
+ NUMERIC_LITERAL
100
+ : 'Infinity'
101
+ | 'NaN'
102
+ ;
103
+
104
+ SYMBOL
105
+ : '+'
106
+ | '-'
107
+ ;
108
+
109
+ fragment HEX
110
+ : [0-9a-fA-F]
111
+ ;
112
+
113
+ fragment INT
114
+ : '0'
115
+ | [1-9] [0-9]*
116
+ ;
117
+
118
+ fragment EXP
119
+ : [Ee] SYMBOL? [0-9]*
120
+ ;
121
+
122
+ IDENTIFIER
123
+ : IDENTIFIER_START IDENTIFIER_PART*
124
+ ;
125
+
126
+ fragment IDENTIFIER_START
127
+ : [\p{L}]
128
+ | '$'
129
+ | '_'
130
+ | '\\' UNICODE_SEQUENCE
131
+ ;
132
+
133
+ fragment IDENTIFIER_PART
134
+ : IDENTIFIER_START
135
+ | [\p{M}]
136
+ | [\p{N}]
137
+ | [\p{Pc}]
138
+ | '\u200C'
139
+ | '\u200D'
140
+ ;
141
+
142
+ fragment UNICODE_SEQUENCE
143
+ : 'u' HEX HEX HEX HEX
144
+ ;
145
+
146
+ fragment NEWLINE
147
+ : '\r\n'
148
+ | [\r\n\u2028\u2029]
149
+ ;
150
+
151
+ fragment WS1
152
+ : '\u0009'
153
+ | '\u000A'
154
+ | '\u000B'
155
+ | '\u000C'
156
+ | '\u000D'
157
+ | '\u0020'
158
+ | '\u00A0'
159
+ | '\u2028'
160
+ | '\u2029'
161
+ | '\uFEFF'
162
+
163
+ | '\u1680'
164
+ | '\u2000' ..'\u200A'
165
+ | '\u202F'
166
+ | '\u205F'
167
+ | '\u3000'
168
+ ;
169
+
170
+ WS
171
+ : WS1+ -> skip
172
+ ;
@@ -0,0 +1,8 @@
1
+ from .codec import ( # noqa
2
+ dumps,
3
+ loads,
4
+ )
5
+
6
+ from .errors import ( # noqa
7
+ Json5Error,
8
+ )