dekshell 0.1.96__py3-none-any.whl → 0.1.98__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.
@@ -17,6 +17,7 @@ from dektools.download import download_from_http
17
17
  from dektools.time import now
18
18
  from dektools.str import shlex_split, shlex_quote
19
19
  from ...utils.beep import sound_notify
20
+ from ..markers.base.core import MarkerBase, get_inner_vars
20
21
  from ..markers.invoke import InvokeMarker, GotoMarker
21
22
  from ..redirect import search_bin_by_path_tree
22
23
 
@@ -87,6 +88,20 @@ def _remove_path(path):
87
88
  _remove_path(item)
88
89
 
89
90
 
91
+ _xeval_default = object()
92
+
93
+
94
+ def _xeval(expression, default=_xeval_default, translate=False):
95
+ context = get_inner_vars('__inner_context__', full=True)
96
+ try:
97
+ return MarkerBase.eval_mixin(context, expression, translate)
98
+ except NameError:
99
+ if default is _xeval_default:
100
+ raise
101
+ else:
102
+ return default
103
+
104
+
90
105
  path_common_methods = {
91
106
  'cd': os.chdir,
92
107
  'cwd': lambda: os.getcwd(),
@@ -98,6 +113,7 @@ path_common_methods = {
98
113
  }
99
114
 
100
115
  default_methods = {
116
+ 'xeval': _xeval,
101
117
  'echo': lambda *x, **y: print(*x, **dict(flush=True) | y),
102
118
  'echos': lambda *x, **y: print(*x, **dict(end='', flush=True) | y),
103
119
  'echox': lambda *x, **y: print(*x, **dict(file=sys.stderr, flush=True) | y),
@@ -20,6 +20,7 @@ def make_shell_properties(shell):
20
20
  'rf': f'{shell} rf',
21
21
  'rfc': f'{shell} rfc',
22
22
  'rs': f'{shell} rs',
23
+ 'ext': '.pysh',
23
24
  },
24
25
  }
25
26
 
@@ -14,6 +14,7 @@ from .echo import *
14
14
  from .pip_ import *
15
15
  from .shell import *
16
16
  from .redirect import *
17
+ from .input import *
17
18
  from .timout import *
18
19
  from .empty import *
19
20
 
@@ -23,11 +24,12 @@ def generate_markers(*args, **kwargs):
23
24
  *args,
24
25
  *get_markers_from_modules(**kwargs),
25
26
  ErrorEchoMarker, EchoNoWrapMarker, EchoMarker,
27
+ InputMarker,
26
28
  DelVarMarker,
27
29
  ExecLinesUpdateMarker, ExecLinesMarker, ExecMarker, ExecCmdcallLinesMarker, ExecCmdcallMarker,
28
30
  EnvShellMarker, EnvMarker,
29
31
  IfMarker, IfElifMarker, IfElseMarker,
30
- WhileMarker,
32
+ WhileMarker, WhileElseMarker,
31
33
  ForMarker, ForElseMarker,
32
34
  DefineMarker,
33
35
  GotoMarker, InvokeMarker,
@@ -123,6 +123,13 @@ class MarkerBase:
123
123
  func = cls.eval(context, func)
124
124
  return func(*args, **kwargs)
125
125
 
126
+ @classmethod
127
+ def translate_case(cls, context, s, case=None):
128
+ if case is None:
129
+ return cls.translate(context, s)
130
+ else:
131
+ return cls._translate(context, s) if case else s
132
+
126
133
  @classmethod
127
134
  def translate(cls, context, s):
128
135
  return cls._translate(context, s)
@@ -221,10 +228,10 @@ class MarkerBase:
221
228
 
222
229
  @classmethod
223
230
  def eval_mixin(cls, context, expression, translate=True):
231
+ __inner_context__ = context # noqa
224
232
  expression = expression.lstrip()
225
233
  if expression.startswith(cmd_call_prefix_chain):
226
- if translate:
227
- expression = cls._translate(context, expression)
234
+ expression = cls.translate_case(context, expression, translate)
228
235
  expression = expression[len(cmd_call_prefix_chain):]
229
236
  index = re.search(
230
237
  r"%s|%s" % (re.escape(cmd_call_prefix_simple), re.escape(cmd_call_eval_prefix)), expression).span()[0]
@@ -235,12 +242,10 @@ class MarkerBase:
235
242
  value = cls.eval(context, func)(value)
236
243
  return value
237
244
  elif expression.startswith(cmd_call_prefix):
238
- if translate:
239
- expression = cls._translate(context, expression)
245
+ expression = cls.translate_case(context, expression, translate)
240
246
  return cls.cmd_call(context, expression[len(cmd_call_prefix):], False)
241
247
  elif expression.startswith(cmd_call_prefix_simple):
242
- if translate:
243
- expression = cls._translate(context, expression)
248
+ expression = cls.translate_case(context, expression, translate)
244
249
  return cls.cmd_call(context, expression[len(cmd_call_prefix_simple):], True)
245
250
  else:
246
251
  if expression.startswith(cmd_call_eval_prefix):
@@ -294,7 +299,7 @@ class TransformerMarker(MarkerBase):
294
299
 
295
300
  def transform(self, parent):
296
301
  for target in self.targets:
297
- if target.is_type(*parent.final_branch_set):
302
+ if isinstance(target, tuple(parent.final_branch_set)):
298
303
  return target
299
304
  return self.targets[0]
300
305
 
@@ -305,13 +310,13 @@ class TransformerMarker(MarkerBase):
305
310
  records_target = set()
306
311
  for i, marker in enumerate(markers):
307
312
  match = marker.get_tag_match()
308
- if marker in records_markers:
313
+ if match in records_markers:
309
314
  records_markers[match].append(marker)
310
315
  else:
311
- records_markers[match] = []
316
+ records_markers[match] = [marker]
312
317
  if len(records_markers[match]) > 1:
313
318
  records_target.add(match)
314
- if marker not in records_index:
319
+ if match not in records_index:
315
320
  records_index[match] = i
316
321
  offset = 0
317
322
  for match in sorted(records_target, key=lambda x: records_index[x]):
@@ -324,11 +329,11 @@ class TransformerMarker(MarkerBase):
324
329
  class MarkerWithEnd(MarkerBase):
325
330
  tag_tail = EndMarker
326
331
 
327
- def get_inner_content(self, context, marker_node):
332
+ def get_inner_content(self, context, marker_node, sep='\n', translate=None):
328
333
  commands = []
329
334
  marker_node.walk(lambda node, depth: commands.extend([] if depth == 0 else [node.command]))
330
- text = '\n'.join(commands)
331
- return self.translate(context, text)
335
+ text = sep.join(commands)
336
+ return self.translate_case(context, text, translate)
332
337
 
333
338
  def eval_codes(self, context, code):
334
339
  if not code:
@@ -357,7 +362,9 @@ class MarkerWithEnd(MarkerBase):
357
362
 
358
363
 
359
364
  class MarkerNoTranslator(MarkerBase):
360
- def translate(self, context, s):
365
+
366
+ @classmethod
367
+ def translate(cls, context, s):
361
368
  return s
362
369
 
363
370
 
@@ -7,16 +7,37 @@ from dektools.dict import MapChainContext
7
7
  from . import MarkerBase, TransformerMarker, ExitException, QuitContextException
8
8
 
9
9
 
10
- def get_inner_vars(*var_name_list):
11
- depth = 1
12
- while True:
13
- frame = sys._getframe(depth)
14
- if var_name_list[0] in frame.f_globals:
15
- result = tuple(frame.f_globals[x] for x in var_name_list)
16
- if len(var_name_list) == 1:
17
- return result[0]
18
- return result
19
- depth += 1
10
+ def get_inner_vars(*var_name_list, full=False):
11
+ def walk(attr):
12
+ depth = 1
13
+ while True:
14
+ try:
15
+ frame = sys._getframe(depth)
16
+ except ValueError:
17
+ return
18
+ scope = getattr(frame, attr)
19
+ for i, name in enumerate(var_name_list):
20
+ if result[i] is unset:
21
+ if name in scope:
22
+ result[i] = scope[name]
23
+ if not list_unset():
24
+ break
25
+ depth += 1
26
+
27
+ def list_unset():
28
+ return [var_name_list[i] for i, x in enumerate(result) if x is unset]
29
+
30
+ unset = object()
31
+ result = [unset] * len(var_name_list)
32
+ walk('f_globals')
33
+ if full and list_unset():
34
+ walk('f_locals')
35
+ lu = list_unset()
36
+ if lu:
37
+ raise ValueError(f"Can't find: {lu}")
38
+ if len(result) == 1:
39
+ return result[0]
40
+ return tuple(result)
20
41
 
21
42
 
22
43
  class MarkerContext:
@@ -134,7 +155,7 @@ class MarkerNode:
134
155
  return obj2str(walk(self))
135
156
 
136
157
  def is_type(self, *markers_cls):
137
- return isinstance(self.marker, tuple(markers_cls))
158
+ return isinstance(self.marker, markers_cls)
138
159
 
139
160
  def add_child(self, node):
140
161
  node.parent = self
@@ -154,6 +175,7 @@ class MarkerNode:
154
175
 
155
176
  @classmethod
156
177
  def execute_nodes(cls, context, marker_set, nodes):
178
+ __inner_marker_set__ = marker_set # noqa
157
179
  while nodes:
158
180
  node = nodes.pop(0)
159
181
  result = node.bubble_continue(context, marker_set, node)
@@ -16,7 +16,7 @@ class ExecLinesMarker(MarkerWithEnd, MarkerNoTranslator):
16
16
  tag_head = '=='
17
17
 
18
18
  def execute(self, context, command, marker_node, marker_set):
19
- code = self.get_inner_content(context, marker_node)
19
+ code = self.get_inner_content(context, marker_node, translate=False)
20
20
  self.eval_lines(context, code)
21
21
  return []
22
22
 
@@ -25,7 +25,7 @@ class ExecLinesUpdateMarker(MarkerWithEnd, MarkerNoTranslator):
25
25
  tag_head = '==='
26
26
 
27
27
  def execute(self, context, command, marker_node, marker_set):
28
- code = self.get_inner_content(context, marker_node)
28
+ code = self.get_inner_content(context, marker_node, translate=False)
29
29
  context.update_variables(self.eval_lines(context, code))
30
30
  return []
31
31
 
@@ -12,10 +12,10 @@ class CallMarker(MarkerNoTranslator):
12
12
 
13
13
  def execute_core(self, context, expression):
14
14
  if expression.startswith(cmd_call_prefix):
15
- expression = self.translate(context, expression)
15
+ expression = self.translate_case(context, expression, True)
16
16
  name, args, kwargs = self.cmd_call_parse(context, expression[len(cmd_call_prefix):], False)
17
17
  elif expression.startswith(cmd_call_prefix_simple):
18
- expression = self.translate(context, expression)
18
+ expression = self.translate_case(context, expression, True)
19
19
  name, args, kwargs = self.cmd_call_parse(context, expression[len(cmd_call_prefix_simple):], True)
20
20
  else:
21
21
  name = expression[:expression.find('(')]
@@ -0,0 +1,16 @@
1
+ import subprocess
2
+ from dektools.shell import shell_with_input
3
+ from .base import MarkerWithEnd, MarkerNoTranslator
4
+
5
+
6
+ class InputMarker(MarkerWithEnd, MarkerNoTranslator):
7
+ tag_head = 'input'
8
+
9
+ def execute(self, context, command, marker_node, marker_set):
10
+ command_text = self.get_inner_content(context, marker_node, sep='', translate=True).strip()
11
+ expression = self.split_raw(command, 1, self.tag_head)[1]
12
+ inputs = self.eval_mixin(context, expression)
13
+ rc = shell_with_input(command_text, inputs, env=context.environ_full())
14
+ if rc:
15
+ raise subprocess.CalledProcessError(rc, command_text)
16
+ return []
@@ -1,8 +1,13 @@
1
1
  from .base import MarkerWithEnd, BreakMarker, ContinueMarker, MarkerNoTranslator
2
2
 
3
3
 
4
+ class WhileElseMarker(MarkerWithEnd):
5
+ tag_head = "else"
6
+
7
+
4
8
  class WhileMarker(MarkerWithEnd, MarkerNoTranslator):
5
9
  tag_head = "while"
10
+ branch_set = {WhileElseMarker}
6
11
 
7
12
  def bubble_continue(self, context, marker_set, marker_node_self, marker_node_target):
8
13
  if marker_node_target.is_type(BreakMarker):
@@ -12,11 +17,13 @@ class WhileMarker(MarkerWithEnd, MarkerNoTranslator):
12
17
  return None
13
18
 
14
19
  def execute(self, context, command, marker_node, marker_set):
20
+ index_else = self.find_node(marker_node.children, True)
21
+
15
22
  result = self.get_condition_result(context, command)
16
23
  if result:
17
- return [*marker_node.children, marker_set.node_cls(ContinueMarker(), None, None, marker_node)]
24
+ return [*marker_node.children[:index_else], marker_set.node_cls(ContinueMarker(), None, None, marker_node)]
18
25
  else:
19
- return []
26
+ return marker_node.children[index_else:]
20
27
 
21
28
  def get_condition_result(self, context, command):
22
29
  expression = command.split(self.tag_head, 1)[-1].strip()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dekshell
3
- Version: 0.1.96
3
+ Version: 0.1.98
4
4
  Author-Email: sanzenwin <sanzenwin@gmail.com>
5
5
  License: MIT
6
6
  Requires-Python: >=3.8
@@ -1,32 +1,33 @@
1
- dekshell-0.1.96.dist-info/METADATA,sha256=zBUVdr9cVMpMPq-RSkJXw15pgIlenlR7hmm6saW5KkQ,521
2
- dekshell-0.1.96.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- dekshell-0.1.96.dist-info/entry_points.txt,sha256=d-kbfULiUTZWIBBsrQF3J_-wESncF-4K2rwHT08grlI,75
1
+ dekshell-0.1.98.dist-info/METADATA,sha256=NPP9ZnDzxOZgm3U93ABhJZ0ohKxkgTad2gm2hjtlnC8,521
2
+ dekshell-0.1.98.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ dekshell-0.1.98.dist-info/entry_points.txt,sha256=d-kbfULiUTZWIBBsrQF3J_-wESncF-4K2rwHT08grlI,75
4
4
  dekshell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  dekshell/click/__entry__.py,sha256=CMuxUzXoEe4TcHFZwv-MNFwHnu1HSZCDpXFpqQ814uM,42
6
6
  dekshell/click/__init__.py,sha256=UKK_JnWOaY6gDakc1GMlVHoU04Kj_ot79GVUt_CAVbI,1877
7
7
  dekshell/core/__init__.py,sha256=nwHnjVIRHkEuFqPeoGqrydvfRFYt7cY8VGbQVCkEY0g,5204
8
8
  dekshell/core/contexts/__init__.py,sha256=ynsfv37azOKfI2UKd0iPl2M6iBW-k5cb1BqSLOWuJpI,482
9
- dekshell/core/contexts/methods.py,sha256=0T3_aZSbXnzYqxGCymHDqYnxZpTHhMjhY2KTfYhVXcs,5065
10
- dekshell/core/contexts/properties.py,sha256=e6sLaPiosj1HqvUK3A3W-TXMMwlQHbK9jmIRvLiTrf0,1542
11
- dekshell/core/markers/__init__.py,sha256=ygIuyKz11F5vJ8C17mbfawsrymcqdK7bc6wmZ15QoeA,1666
12
- dekshell/core/markers/base/__init__.py,sha256=T2JfxaU0uMjg6RFFjq6OteUxpmmJBF9yqjI6Diy7LsQ,12781
13
- dekshell/core/markers/base/core.py,sha256=c7Dd_3_KInjHVI9vn2q6cgV5nCfDF3fq4xsGOsJGpeI,10211
9
+ dekshell/core/contexts/methods.py,sha256=377lvp_1FvLE6AgJMfbPDu_yUF4DwWMKsTuB-f268Oo,5498
10
+ dekshell/core/contexts/properties.py,sha256=aLHtyUWedbFPQw33V5vQZTc4TeLMTC-AO6e7PhBZKbk,1570
11
+ dekshell/core/markers/__init__.py,sha256=bmGMbZRqsOohMKjH0AReFxZ-nIPFF6YgPJMFT6gTJEw,1725
12
+ dekshell/core/markers/base/__init__.py,sha256=AQYr7H0F06izu5jhu8EgLYJ2ERzJh0eS38h9gtl6OZs,13067
13
+ dekshell/core/markers/base/core.py,sha256=99aRcSXohpfTW5OSO1CUyvnptr21ueKjizCk-FK6rcM,10830
14
14
  dekshell/core/markers/comment.py,sha256=28iccgLs_0bRdXLhHyQR2I_kzlWdeMSqqNUFW-2vkes,818
15
15
  dekshell/core/markers/define.py,sha256=LpMSfz9ziXq2aFJ6oMpUFFo93TpBx7GxKYNzCeht4fQ,516
16
16
  dekshell/core/markers/echo.py,sha256=1H61qQbY9tZnrKsdTI_shTmDY5ZaSGipDuBSRptAuZw,660
17
17
  dekshell/core/markers/empty.py,sha256=xMYoZIxn7Tt1RjFtLhJERisra8jqsGjJ0G7OID0oD3o,776
18
18
  dekshell/core/markers/env.py,sha256=6ZtiMNdKFbGR_DBjG6C7A8L_lJsiymN5Y5AbnTzyMrE,1158
19
- dekshell/core/markers/exec.py,sha256=7dU2He4iGkOG6khkj-xkZXQ6IPD4gC3JeExXGjybQO8,1998
19
+ dekshell/core/markers/exec.py,sha256=zT3mI7bBSgOpBICCjeb-vhAWbra9i8rABuUAVNnuMns,2032
20
20
  dekshell/core/markers/for_.py,sha256=uNOEwyDsjffttEBtUYasdlj7FP_sGnQzWuTV5d5esHY,2142
21
- dekshell/core/markers/function.py,sha256=iqzpu01kvrPP31zXbRl7cQytRW89Q2UMueaBgsWGVV8,3570
21
+ dekshell/core/markers/function.py,sha256=RPh56_rYbWXCTkNPiJu8zNEj-OE6txKgEw7Im9fBM3c,3592
22
22
  dekshell/core/markers/if_.py,sha256=bBG1fDCZd5alE5FSm0QhgHl6ZJn5awiqZAXnPnO-thc,1112
23
+ dekshell/core/markers/input.py,sha256=HpqE1_PxrmeAVbWxACu0O7SeBVQpBw-aAmNIX5uWWYs,659
23
24
  dekshell/core/markers/invoke.py,sha256=sXXg0p8Dyg4HQwnWFzWgcyhZYGWvNfhDgUumrrUoWkM,1431
24
25
  dekshell/core/markers/pip_.py,sha256=mxXa_oqcrk4Qz-HvhlkMoirsl-SbM9Fz610leNqP1o0,832
25
26
  dekshell/core/markers/redirect.py,sha256=7r0SpwIDkHkHjEDa26pNq3luOAE69fsFETyv4mKDw5k,1588
26
27
  dekshell/core/markers/shell.py,sha256=oU_APU2__BO9-LeDE4uYDXClic8MGmwambD2jujkpVc,984
27
28
  dekshell/core/markers/timout.py,sha256=sC1kNfcA_TFuKZFUaRCSnPHZ5az9Ap8rItSu5RwssUM,915
28
29
  dekshell/core/markers/var.py,sha256=UEGnKdloRDOSi1KD8aJId9k7WTYkeDIKjsuT7tBJ5Lo,4210
29
- dekshell/core/markers/while_.py,sha256=ZpwaNDYGYF9HCE6cf3q7tArafI8oGnM7TXhJ-UKwpB0,989
30
+ dekshell/core/markers/while_.py,sha256=e7lI5jsIM-qxNHMY_wUyCMvvesdXQibR5Ez2jNO9csc,1195
30
31
  dekshell/core/plugin/__init__.py,sha256=jAB_KnnHJsyJR_zIfBU_HNLngyhcyyqVv05PdlNZtF8,428
31
32
  dekshell/core/redirect.py,sha256=6YCJpG0TkQ4WMt7LBtDD_W1T-C-QkLtGRQw0S60qe54,1058
32
33
  dekshell/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -35,4 +36,4 @@ dekshell/utils/cmd.py,sha256=_WG7K-CO-WQkI9ERyrhI2d4yT-DX3OjjJWbNzhmsPus,1197
35
36
  dekshell/utils/pkg.py,sha256=TgYqRqawoJfjkxt6UAHnp9ttmpjuHiWRFbqxADOS1VE,1337
36
37
  dekshell/utils/serializer.py,sha256=aIdF2Wzo-qHmIshv46jn1XD0X66vQ1JFdU-g3ZFbH2w,386
37
38
  dekshell/utils/shell.py,sha256=0NoA2-SOOMinbmZZipwzL-npBbzPOdWEfdPVYqq5G5g,92
38
- dekshell-0.1.96.dist-info/RECORD,,
39
+ dekshell-0.1.98.dist-info/RECORD,,