ominfra 0.0.0.dev276__py3-none-any.whl → 0.0.0.dev277__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.
@@ -2807,9 +2807,16 @@ DEFAULT_CONFIG_RENDERER = SwitchedConfigRenderer(DEFAULT_CONFIG_RENDERERS)
2807
2807
  # ../../../../../omlish/io/buffers.py
2808
2808
 
2809
2809
 
2810
+ ##
2811
+
2812
+
2810
2813
  class DelimitingBuffer:
2811
2814
  """
2812
2815
  https://github.com/python-trio/trio/issues/796 :|
2816
+
2817
+ FIXME: when given overlapping delimiters like [b'\r', b'\r\n'], *should* refuse to output a line ending in '\r'
2818
+ without knowing it will not be followed by '\n'. does not currently do this - currently only picks longest
2819
+ delimiter present in the buffer. does this need a prefix-trie? is this borderline parsing?
2813
2820
  """
2814
2821
 
2815
2822
  #
@@ -2831,19 +2838,37 @@ class DelimitingBuffer:
2831
2838
 
2832
2839
  def __init__(
2833
2840
  self,
2834
- delimiters: ta.Iterable[int] = DEFAULT_DELIMITERS,
2841
+ delimiters: ta.Iterable[ta.Union[int, bytes]] = DEFAULT_DELIMITERS,
2835
2842
  *,
2836
2843
  keep_ends: bool = False,
2837
2844
  max_size: ta.Optional[int] = None,
2838
2845
  ) -> None:
2839
2846
  super().__init__()
2840
2847
 
2841
- self._delimiters = frozenset(check.isinstance(d, int) for d in delimiters)
2848
+ ds: ta.Set[bytes] = set()
2849
+ for d in delimiters:
2850
+ if isinstance(d, int):
2851
+ d = bytes([d])
2852
+ ds.add(check.isinstance(d, bytes))
2853
+
2854
+ self._delimiters: ta.FrozenSet[bytes] = frozenset(ds)
2842
2855
  self._keep_ends = keep_ends
2843
2856
  self._max_size = max_size
2844
2857
 
2845
2858
  self._buf: ta.Optional[io.BytesIO] = io.BytesIO()
2846
2859
 
2860
+ ddl = {}
2861
+ dl = sorted(self._delimiters, key=lambda d: -len(d))
2862
+ for i, d in enumerate(dl):
2863
+ for j, d2 in enumerate(dl):
2864
+ if len(d2) < len(d):
2865
+ break
2866
+ if i == j or not d2.startswith(d):
2867
+ continue
2868
+ ddl[d] = len(d2)
2869
+ break
2870
+ self._delimiter_disambiguation_lens: ta.Dict[bytes, int] = ddl
2871
+
2847
2872
  #
2848
2873
 
2849
2874
  @property
@@ -2860,13 +2885,30 @@ class DelimitingBuffer:
2860
2885
  raise self.ClosedError(self)
2861
2886
  return buf.getvalue()
2862
2887
 
2863
- def _find_delim(self, data: ta.Union[bytes, bytearray], i: int) -> ta.Optional[int]:
2864
- r = None # type: int | None
2888
+ def _find_delim(self, data: ta.Union[bytes, bytearray], i: int) -> ta.Optional[ta.Tuple[int, int]]:
2889
+ rp = None # type: int | None
2890
+ rl = None # type: int | None
2891
+ rd = None # type: bytes | None
2892
+
2865
2893
  for d in self._delimiters:
2866
- if (p := data.find(d, i)) >= 0:
2867
- if r is None or p < r:
2868
- r = p
2869
- return r
2894
+ if (p := data.find(d, i)) < 0:
2895
+ continue
2896
+
2897
+ dl = len(d)
2898
+
2899
+ if rp is None or p < rp:
2900
+ rp, rl, rd = p, dl, d
2901
+ elif rp == p and rl < dl: # type: ignore
2902
+ rl, rd = dl, d # noqa
2903
+
2904
+ if rp is None:
2905
+ return None
2906
+
2907
+ # FIXME:
2908
+ # if (ddl := self._delimiter_disambiguation_lens.get(rd)) is not None:
2909
+ # raise NotImplementedError
2910
+
2911
+ return rp, rl # type: ignore
2870
2912
 
2871
2913
  def _append_and_reset(self, chunk: bytes) -> bytes:
2872
2914
  buf = check.not_none(self._buf)
@@ -2897,10 +2939,11 @@ class DelimitingBuffer:
2897
2939
  l = len(data)
2898
2940
  i = 0
2899
2941
  while i < l:
2900
- if (p := self._find_delim(data, i)) is None:
2942
+ if (pt := self._find_delim(data, i)) is None:
2901
2943
  break
2902
2944
 
2903
- n = p + 1
2945
+ p, pl = pt
2946
+ n = p + pl
2904
2947
  if self._keep_ends:
2905
2948
  p = n
2906
2949
 
@@ -2928,6 +2971,9 @@ class DelimitingBuffer:
2928
2971
  i = p
2929
2972
 
2930
2973
 
2974
+ ##
2975
+
2976
+
2931
2977
  class ReadableListBuffer:
2932
2978
  # FIXME: merge with PrependableGeneratorReader
2933
2979
 
@@ -2999,6 +3045,9 @@ class ReadableListBuffer:
2999
3045
  return r if isinstance(r, bytes) else None
3000
3046
 
3001
3047
 
3048
+ ##
3049
+
3050
+
3002
3051
  class IncrementalWriteBuffer:
3003
3052
  def __init__(
3004
3053
  self,
@@ -4042,9 +4042,16 @@ class HttpRequestParser:
4042
4042
  # ../../../omlish/io/buffers.py
4043
4043
 
4044
4044
 
4045
+ ##
4046
+
4047
+
4045
4048
  class DelimitingBuffer:
4046
4049
  """
4047
4050
  https://github.com/python-trio/trio/issues/796 :|
4051
+
4052
+ FIXME: when given overlapping delimiters like [b'\r', b'\r\n'], *should* refuse to output a line ending in '\r'
4053
+ without knowing it will not be followed by '\n'. does not currently do this - currently only picks longest
4054
+ delimiter present in the buffer. does this need a prefix-trie? is this borderline parsing?
4048
4055
  """
4049
4056
 
4050
4057
  #
@@ -4066,19 +4073,37 @@ class DelimitingBuffer:
4066
4073
 
4067
4074
  def __init__(
4068
4075
  self,
4069
- delimiters: ta.Iterable[int] = DEFAULT_DELIMITERS,
4076
+ delimiters: ta.Iterable[ta.Union[int, bytes]] = DEFAULT_DELIMITERS,
4070
4077
  *,
4071
4078
  keep_ends: bool = False,
4072
4079
  max_size: ta.Optional[int] = None,
4073
4080
  ) -> None:
4074
4081
  super().__init__()
4075
4082
 
4076
- self._delimiters = frozenset(check.isinstance(d, int) for d in delimiters)
4083
+ ds: ta.Set[bytes] = set()
4084
+ for d in delimiters:
4085
+ if isinstance(d, int):
4086
+ d = bytes([d])
4087
+ ds.add(check.isinstance(d, bytes))
4088
+
4089
+ self._delimiters: ta.FrozenSet[bytes] = frozenset(ds)
4077
4090
  self._keep_ends = keep_ends
4078
4091
  self._max_size = max_size
4079
4092
 
4080
4093
  self._buf: ta.Optional[io.BytesIO] = io.BytesIO()
4081
4094
 
4095
+ ddl = {}
4096
+ dl = sorted(self._delimiters, key=lambda d: -len(d))
4097
+ for i, d in enumerate(dl):
4098
+ for j, d2 in enumerate(dl):
4099
+ if len(d2) < len(d):
4100
+ break
4101
+ if i == j or not d2.startswith(d):
4102
+ continue
4103
+ ddl[d] = len(d2)
4104
+ break
4105
+ self._delimiter_disambiguation_lens: ta.Dict[bytes, int] = ddl
4106
+
4082
4107
  #
4083
4108
 
4084
4109
  @property
@@ -4095,13 +4120,30 @@ class DelimitingBuffer:
4095
4120
  raise self.ClosedError(self)
4096
4121
  return buf.getvalue()
4097
4122
 
4098
- def _find_delim(self, data: ta.Union[bytes, bytearray], i: int) -> ta.Optional[int]:
4099
- r = None # type: int | None
4123
+ def _find_delim(self, data: ta.Union[bytes, bytearray], i: int) -> ta.Optional[ta.Tuple[int, int]]:
4124
+ rp = None # type: int | None
4125
+ rl = None # type: int | None
4126
+ rd = None # type: bytes | None
4127
+
4100
4128
  for d in self._delimiters:
4101
- if (p := data.find(d, i)) >= 0:
4102
- if r is None or p < r:
4103
- r = p
4104
- return r
4129
+ if (p := data.find(d, i)) < 0:
4130
+ continue
4131
+
4132
+ dl = len(d)
4133
+
4134
+ if rp is None or p < rp:
4135
+ rp, rl, rd = p, dl, d
4136
+ elif rp == p and rl < dl: # type: ignore
4137
+ rl, rd = dl, d # noqa
4138
+
4139
+ if rp is None:
4140
+ return None
4141
+
4142
+ # FIXME:
4143
+ # if (ddl := self._delimiter_disambiguation_lens.get(rd)) is not None:
4144
+ # raise NotImplementedError
4145
+
4146
+ return rp, rl # type: ignore
4105
4147
 
4106
4148
  def _append_and_reset(self, chunk: bytes) -> bytes:
4107
4149
  buf = check.not_none(self._buf)
@@ -4132,10 +4174,11 @@ class DelimitingBuffer:
4132
4174
  l = len(data)
4133
4175
  i = 0
4134
4176
  while i < l:
4135
- if (p := self._find_delim(data, i)) is None:
4177
+ if (pt := self._find_delim(data, i)) is None:
4136
4178
  break
4137
4179
 
4138
- n = p + 1
4180
+ p, pl = pt
4181
+ n = p + pl
4139
4182
  if self._keep_ends:
4140
4183
  p = n
4141
4184
 
@@ -4163,6 +4206,9 @@ class DelimitingBuffer:
4163
4206
  i = p
4164
4207
 
4165
4208
 
4209
+ ##
4210
+
4211
+
4166
4212
  class ReadableListBuffer:
4167
4213
  # FIXME: merge with PrependableGeneratorReader
4168
4214
 
@@ -4234,6 +4280,9 @@ class ReadableListBuffer:
4234
4280
  return r if isinstance(r, bytes) else None
4235
4281
 
4236
4282
 
4283
+ ##
4284
+
4285
+
4237
4286
  class IncrementalWriteBuffer:
4238
4287
  def __init__(
4239
4288
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ominfra
3
- Version: 0.0.0.dev276
3
+ Version: 0.0.0.dev277
4
4
  Summary: ominfra
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omdev==0.0.0.dev276
16
- Requires-Dist: omlish==0.0.0.dev276
15
+ Requires-Dist: omdev==0.0.0.dev277
16
+ Requires-Dist: omlish==0.0.0.dev277
17
17
  Provides-Extra: all
18
18
  Requires-Dist: paramiko~=3.5; extra == "all"
19
19
  Requires-Dist: asyncssh~=2.20; extra == "all"
@@ -112,9 +112,9 @@ ominfra/manage/targets/connection.py,sha256=rVI1YJxFClcF-sdttqWyIz9_XjPI01GUdwxY
112
112
  ominfra/manage/targets/inject.py,sha256=P4597xWM-V3I_gCt2O71OLhYQkkXtuJvkYRsIbhhMcE,1561
113
113
  ominfra/manage/targets/targets.py,sha256=7GP6UAZyJFEhpkJN6UQdpr_WN3p7C76v-s445y-WB6U,1885
114
114
  ominfra/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
- ominfra/scripts/journald2aws.py,sha256=e-h-YSCQdrbHwpyVkrQuFMNyEGOesX-rmJauXP-5Skg,169752
115
+ ominfra/scripts/journald2aws.py,sha256=IgF4hmmjQv_bVEETNci4k6mtGRWuiGeW90mvWl14BAI,171170
116
116
  ominfra/scripts/manage.py,sha256=OlfubrtGmXWAyUOO6eHOj-k4XmfDPrngdKTLlm6yLZA,380865
117
- ominfra/scripts/supervisor.py,sha256=5r6YXcRZUQs4FaL5-faCqnicgsXEISYGQostaGKiBaQ,298330
117
+ ominfra/scripts/supervisor.py,sha256=9fEgMFPZMRGk7uBVdywzR_E5Y6_xTxUw3zUs_SCu17o,299748
118
118
  ominfra/supervisor/LICENSE.txt,sha256=ZrHY15PVR98y26Yg6iQfa-SXnUaYTDhrUsPVcEO5OKM,1874
119
119
  ominfra/supervisor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
120
120
  ominfra/supervisor/__main__.py,sha256=I0yFw-C08OOiZ3BF6lF1Oiv789EQXu-_j6whDhQUTEA,66
@@ -156,9 +156,9 @@ ominfra/tailscale/api.py,sha256=C5-t_b6jZXUWcy5k8bXm7CFnk73pSdrlMOgGDeGVrpw,1370
156
156
  ominfra/tailscale/cli.py,sha256=3FnJbgpLw6gInTfhERd1mDy9ijjMUGxkdYVo43Tnxx4,3555
157
157
  ominfra/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
158
  ominfra/tools/listresources.py,sha256=auGP1LlbBJSFKUWNvQo_UzA8IsBNZBTMwEkFFRJ4FX4,6185
159
- ominfra-0.0.0.dev276.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
160
- ominfra-0.0.0.dev276.dist-info/METADATA,sha256=2JmrHLRyxgZ5yEgwibGziwnvsl8PxirK8snf__xmirA,753
161
- ominfra-0.0.0.dev276.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
162
- ominfra-0.0.0.dev276.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
163
- ominfra-0.0.0.dev276.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
164
- ominfra-0.0.0.dev276.dist-info/RECORD,,
159
+ ominfra-0.0.0.dev277.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
160
+ ominfra-0.0.0.dev277.dist-info/METADATA,sha256=7UxDcwMoM-Rl1B4e9hjXwMXl7sETavE3HwRwSnwZJa0,753
161
+ ominfra-0.0.0.dev277.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
162
+ ominfra-0.0.0.dev277.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
163
+ ominfra-0.0.0.dev277.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
164
+ ominfra-0.0.0.dev277.dist-info/RECORD,,