dekshell 0.2.3__py3-none-any.whl → 0.2.5__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.
dekshell/core/__init__.py CHANGED
@@ -17,8 +17,12 @@ from ..utils.shell import shell_bin
17
17
  from ..utils.cmd import ak2cmd, pack_context_full
18
18
 
19
19
 
20
- def shell_file(__not_use_this_var_name__, *args, **kwargs):
21
- shell_wrapper(f'{shell_bin} rf {__not_use_this_var_name__} {ak2cmd(args, kwargs)}')
20
+ def shell_file(__placeholder__filepath, *args, **kwargs):
21
+ shell_wrapper(f'{shell_bin} rf "{__placeholder__filepath}" {ak2cmd(args, kwargs)}')
22
+
23
+
24
+ def shell_file_cd(__placeholder__filepath, *args, **kwargs):
25
+ shell_wrapper(f'{shell_bin} rfc "{__placeholder__filepath}" {ak2cmd(args, kwargs)}')
22
26
 
23
27
 
24
28
  def shell_command_file_cd(filepath, **kwargs):
@@ -83,7 +87,7 @@ def shell_command_batch_core(
83
87
  def shell_exec(filepath, c=None):
84
88
  return shell_command_file(
85
89
  filepath,
86
- context=(context or {}) | (c or {}),
90
+ context=c or {},
87
91
  marker=marker,
88
92
  ms_names=ms_names,
89
93
  marker_set_cls=marker_set_cls,
@@ -3,9 +3,11 @@ import shutil
3
3
  import sys
4
4
  import tempfile
5
5
  import getpass
6
+ from functools import reduce
7
+ from itertools import chain
6
8
  from pathlib import Path
7
9
  from dektools.file import sure_dir, write_file, read_text, remove_path, sure_parent_dir, normal_path, \
8
- format_path_desc, read_file, split_ext, path_ext, clear_dir, \
10
+ format_path_desc, read_file, split_ext, path_ext, clear_dir, copy_recurse_ignore, \
9
11
  split_file, combine_split_files, remove_split_files, meta_split_file, tree, iglob, \
10
12
  where, where_list, which, which_list
11
13
  from dektools.hash import hash_file
@@ -19,11 +21,12 @@ from dektools.ps.process import process_detail, process_kill, process_list_all
19
21
  from dektools.time import now
20
22
  from dektools.str import shlex_split, shlex_quote
21
23
  from dektools.shell import shell_wrapper, is_user_admin
24
+ from dektools.match import GeneralMatcher, glob2re, glob_compile, glob_match
25
+ from dektools.git import git_clean_dir, git_apply, git_parse_modules, git_fetch_min, git_list_remotes
22
26
  from ...utils.beep import sound_notify
23
27
  from ..markers.base.core import MarkerBase, get_inner_vars
24
28
  from ..markers.invoke import InvokeMarker, GotoMarker
25
29
  from ..redirect import search_bin_by_path_tree
26
- from .properties import current_os
27
30
 
28
31
 
29
32
  def _is_true(x):
@@ -137,6 +140,8 @@ path_common_methods = {
137
140
  }
138
141
 
139
142
  default_methods = {
143
+ 'reduce': reduce,
144
+ 'chain': chain,
140
145
  'xeval': _xeval,
141
146
  'echo': lambda *x, **y: print(*x, **dict(flush=True) | y),
142
147
  'echos': lambda *x, **y: print(*x, **dict(end='', flush=True) | y),
@@ -174,6 +179,7 @@ default_methods = {
174
179
  'wf': write_file,
175
180
  'rt': read_text,
176
181
  'rf': read_file,
182
+ 'ci': copy_recurse_ignore,
177
183
 
178
184
  'sf': split_file,
179
185
  'sfr': remove_split_files,
@@ -207,10 +213,17 @@ default_methods = {
207
213
  'notequal': lambda x, y: x != y,
208
214
  'beep': lambda x=True: sound_notify(x),
209
215
 
210
- 'invoke': lambda __not_use_this_var_name__, *args, **kwargs: InvokeMarker.execute_file(
211
- None, __not_use_this_var_name__, args, kwargs),
212
- 'goto': lambda __not_use_this_var_name__, *args, **kwargs: GotoMarker.execute_file(
213
- None, __not_use_this_var_name__, args, kwargs),
216
+ 'invoke': lambda __placeholder__filepath, *args, **kwargs: InvokeMarker.execute_file(
217
+ None, __placeholder__filepath, args, kwargs),
218
+ 'goto': lambda __placeholder__filepath, *args, **kwargs: GotoMarker.execute_file(
219
+ None, __placeholder__filepath, args, kwargs),
220
+
221
+ 'glob': {
222
+ 're': glob2re,
223
+ 'compile': glob_compile,
224
+ 'match': glob_match,
225
+ 'matcher': GeneralMatcher,
226
+ },
214
227
 
215
228
  'shlex': {
216
229
  'split': shlex_split,
@@ -222,4 +235,12 @@ default_methods = {
222
235
  'fetch': download_file,
223
236
  'download': download_from_http,
224
237
  },
238
+
239
+ 'git': {
240
+ 'apply': git_apply,
241
+ 'remotes': git_list_remotes,
242
+ 'modules': git_parse_modules,
243
+ 'fetch': git_fetch_min,
244
+ 'clean': git_clean_dir,
245
+ }
225
246
  }
@@ -65,10 +65,10 @@ default_properties = {
65
65
  'mingw': sysconfig.get_platform() == 'mingw',
66
66
  'msys': sys.platform == 'msys',
67
67
  'wsl': 'Microsoft' in read_text('/proc/version', default=''),
68
- 'win': platform.system() == 'Windows',
69
- 'mac': platform.system() == 'Darwin',
68
+ 'windows': platform.system() == 'Windows',
69
+ 'macos': platform.system() == 'Darwin',
70
70
  'linux': platform.system() == 'Linux',
71
- 'name': {'Windows': 'win', 'Darwin': 'mac', 'Linux': 'linux'}.get(platform.system()),
71
+ 'name': {'Windows': 'windows', 'Darwin': 'macos', 'Linux': 'linux'}.get(platform.system()),
72
72
  'entry': current_os,
73
73
  },
74
74
  'path': {
@@ -12,10 +12,10 @@ from .function import *
12
12
  from .exec import *
13
13
  from .echo import *
14
14
  from .pip_ import *
15
- from .shell import *
15
+ from .commands import *
16
16
  from .redirect import *
17
17
  from .input import *
18
- from .timout import *
18
+ from .shell import *
19
19
  from .empty import *
20
20
 
21
21
 
@@ -39,12 +39,12 @@ def generate_markers(*args, **kwargs):
39
39
  EndMarker, BreakMarker, ContinueMarker,
40
40
  CommentMultiLineMarker, CommentMarker, CommentShebangMarker, CommentConfigMarker,
41
41
  PipMarker,
42
- ShellMarker,
42
+ CommandsMarker,
43
43
  RedirectMarker, ShiftMarker,
44
- TimeoutMarker,
44
+ TimeoutMarker, RetryMarker,
45
45
  IgnoreMarker,
46
46
  PrefixShellMarker,
47
- AssignCallMarker, AssignInvokerMarker, AssignGotoMarker, AssignTimeoutMarker,
47
+ AssignCallMarker, AssignInvokerMarker, AssignGotoMarker, AssignTimeoutMarker, AssignRetryMarker,
48
48
  AssignExecMarker, AssignEvalMarker, AssignCmdcallMarker,
49
49
  AssignMultiLineRawStrMarker, AssignMultiLineStrMarker, AssignRawStrMarker, AssignStrMarker,
50
50
  EmptyMarker, # must be at the tail
@@ -0,0 +1,30 @@
1
+ from .base import MarkerWithEnd
2
+ from .empty import EmptyMarker
3
+
4
+
5
+ class CommandsMarker(MarkerWithEnd):
6
+ tag_head = "@@"
7
+ target_marker_cls = EmptyMarker
8
+
9
+ def execute(self, context, command, marker_node, marker_set):
10
+ argv = self.split_raw(command, 1)
11
+ config = self.get_item(argv, 1, '').strip()
12
+ if config:
13
+ config = eval(f'dict({config})', {'environ': context.environ_full()})
14
+ else:
15
+ config = None
16
+ marker = marker_set.find_marker_by_cls(self.target_marker_cls)
17
+ result = []
18
+ for child in marker_node.children:
19
+ if child.is_type(self.target_marker_cls):
20
+ node = marker_set.node_cls(
21
+ marker,
22
+ child.command,
23
+ child.index,
24
+ marker_node,
25
+ payload=config
26
+ )
27
+ result.append(node)
28
+ else:
29
+ result.append(child)
30
+ return result
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  from dektools.file import normal_path
3
- from ...utils.cmd import pack_context
3
+ from ...utils.cmd import pack_context_full
4
4
  from .base import MarkerBase
5
5
  from .base.core import get_inner_vars
6
6
 
@@ -18,7 +18,7 @@ class MarkerInvokerBase(MarkerBase):
18
18
  def execute_file(cls, marker_set, filepath, args, kwargs):
19
19
  if marker_set is None:
20
20
  marker_set = get_inner_vars('__inner_marker_set__')
21
- return cls._run_file(marker_set, normal_path(filepath), pack_context(args, kwargs))
21
+ return cls._run_file(marker_set, normal_path(filepath), pack_context_full(args, kwargs))
22
22
 
23
23
  @classmethod
24
24
  def _run_file(cls, marker_set, filepath, attrs):
@@ -28,7 +28,7 @@ class RedirectMarker(MarkerRedirect):
28
28
  shell_properties = make_shell_properties(path_shell)
29
29
  if shell_properties['shell'] != current_shell:
30
30
  fp = self.eval(context, "fp")
31
- fpp = os.path.dirname(fp).relace('/', os.sep)
31
+ fpp = os.path.dirname(fp).replace('/', os.sep)
32
32
  shell = shell_properties['sh']['rfc' if os.getcwd() == fpp else 'rf']
33
33
  args, kwargs = self.eval(context, f'({key_args}, {key_kwargs})')
34
34
  argv = ak2cmd(args, kwargs)
@@ -1,30 +1,56 @@
1
- from .base import MarkerWithEnd
2
- from .empty import EmptyMarker
1
+ import subprocess
2
+ from dektools.shell import shell_timeout, shell_wrapper, shell_retry
3
+ from .empty import MarkerShell, ShellCommand
3
4
 
4
5
 
5
- class ShellMarker(MarkerWithEnd):
6
- tag_head = "@@"
7
- target_marker_cls = EmptyMarker
6
+ class TimeoutShellCommand(ShellCommand):
7
+ def shell(self, command, timeout=None, env=None, **kwargs):
8
+ try:
9
+ if timeout > 0:
10
+ return shell_timeout(command, timeout, env=env)
11
+ else:
12
+ return shell_wrapper(command, env=env)
13
+ except subprocess.SubprocessError as e:
14
+ return e
15
+
16
+
17
+ class TimeoutMarker(MarkerShell):
18
+ tag_head = "timeout"
19
+
20
+ shell_cls = TimeoutShellCommand
8
21
 
9
22
  def execute(self, context, command, marker_node, marker_set):
10
- argv = self.split_raw(command, 1)
11
- config = self.get_item(argv, 1, '').strip()
12
- if config:
13
- config = eval(f'dict({config})', {'environ': context.environ_full()})
14
- else:
15
- config = None
16
- marker = marker_set.find_marker_by_cls(self.target_marker_cls)
17
- result = []
18
- for child in marker_node.children:
19
- if child.is_type(self.target_marker_cls):
20
- node = marker_set.node_cls(
21
- marker,
22
- child.command,
23
- child.index,
24
- marker_node,
25
- payload=config
26
- )
27
- result.append(node)
28
- else:
29
- result.append(child)
30
- return result
23
+ _, timeout, command = self.split_raw(command, 2)
24
+ if command:
25
+ self.execute_core_timeout(context, command, marker_node, marker_set, timeout)
26
+
27
+ @classmethod
28
+ def execute_core_timeout(cls, context, command, marker_node, marker_set, timeout):
29
+ return cls.execute_core(context, command, marker_node, marker_set, dict(timeout=int(float(timeout))))
30
+
31
+
32
+ class RetryShellCommand(ShellCommand):
33
+ def shell(self, command, times=None, env=None, **kwargs):
34
+ try:
35
+ return shell_retry(command=command, times=times, env=env)
36
+ except subprocess.SubprocessError as e:
37
+ return e
38
+
39
+
40
+ class RetryMarker(MarkerShell):
41
+ tag_head = "retry"
42
+
43
+ shell_cls = RetryShellCommand
44
+
45
+ def execute(self, context, command, marker_node, marker_set):
46
+ _, times, command = self.split_raw(command, 2)
47
+ if command:
48
+ self.execute_core_retry(context, command, marker_node, marker_set, times)
49
+
50
+ @classmethod
51
+ def execute_core_retry(cls, context, command, marker_node, marker_set, times):
52
+ try:
53
+ times = int(float(times))
54
+ except ValueError:
55
+ times = None
56
+ return cls.execute_core(context, command, marker_node, marker_set, dict(times=times))
@@ -1,7 +1,7 @@
1
1
  import re
2
2
  from .base import MarkerBase, MarkerWithEnd, MarkerNoTranslator, cmd_call_prefix_simple
3
3
  from .function import CallMarker
4
- from .timout import TimeoutMarker
4
+ from .shell import TimeoutMarker, RetryMarker
5
5
  from .invoke import MarkerInvokerBase, InvokeMarker, GotoMarker
6
6
 
7
7
 
@@ -114,6 +114,15 @@ class AssignTimeoutMarker(MarkerAssignValueBase, TimeoutMarker):
114
114
  return self.execute_core_timeout(context, expression, marker_node, marker_set, timeout)
115
115
 
116
116
 
117
+ class AssignRetryMarker(MarkerAssignValueBase, RetryMarker):
118
+ tag_head = None
119
+ tag_head_re_args = r'retry[ \t\f\r\n]+'
120
+
121
+ def get_value(self, context, marker_node, marker_set, expression):
122
+ times, expression = self.split_raw(expression, 1)
123
+ return self.execute_core_retry(context, expression, marker_node, marker_set, times)
124
+
125
+
117
126
  class DelVarMarker(MarkerBase):
118
127
  tag_head = "del"
119
128
 
dekshell/utils/cmd.py CHANGED
@@ -34,7 +34,7 @@ def ak2cmd(args, kwargs=None):
34
34
 
35
35
 
36
36
  def pack_context(args, kwargs):
37
- return {f'{key_arg}{i}': arg for i, arg in enumerate(args)} | {key_args: args, key_kwargs: kwargs} | kwargs
37
+ return {f'{key_arg}{i}': arg for i, arg in enumerate(args)} | {key_args: tuple(args), key_kwargs: kwargs} | kwargs
38
38
 
39
39
 
40
40
  def pack_context_argv():
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dekshell
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Author-Email: sanzenwin <sanzenwin@gmail.com>
5
5
  License: MIT
6
6
  Requires-Python: >=3.8
7
7
  Requires-Dist: packaging<=23.1
8
8
  Requires-Dist: extra-platforms<=3.1.0
9
- Requires-Dist: dektools[date,fetch,ps,tab]<1.0.0
9
+ Requires-Dist: dektools[date,fetch,ignore,ps,tab]<1.0.0
10
10
  Requires-Dist: dekmedia[audio]<1.0.0
11
11
  Description-Content-Type: text/markdown
12
12
 
@@ -1,16 +1,17 @@
1
- dekshell-0.2.3.dist-info/METADATA,sha256=LUBZ_9vPXyxEFFkQE5GOWAzltxL1nSoTiE-I33mEUnY,565
2
- dekshell-0.2.3.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- dekshell-0.2.3.dist-info/entry_points.txt,sha256=d-kbfULiUTZWIBBsrQF3J_-wESncF-4K2rwHT08grlI,75
1
+ dekshell-0.2.5.dist-info/METADATA,sha256=ouSjx0hcMkNMPo1d6jwyzqeNc0pa6f7jeLAK7k0MuB0,572
2
+ dekshell-0.2.5.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ dekshell-0.2.5.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=rFzB_exzPQaIcbbms5PdHAU3NGdl2MBaYbq9v7g7BOI,1870
7
- dekshell/core/__init__.py,sha256=Cp--1j2jpJzchXR98HiRp2QAiOHz8HXm8iy6ZChIWmc,5207
7
+ dekshell/core/__init__.py,sha256=ZAJtMPFCVClHCPkoP5rmTq1vVLLMQRa8MP-QJXLBgNM,5337
8
8
  dekshell/core/contexts/__init__.py,sha256=ynsfv37azOKfI2UKd0iPl2M6iBW-k5cb1BqSLOWuJpI,482
9
- dekshell/core/contexts/methods.py,sha256=gVj3TCl7mAammL5IgB-nLAp14pkFUBTd_QYcLESZWYk,6458
10
- dekshell/core/contexts/properties.py,sha256=nO0bOxmU4vNBIUc0hOcAZDzJckKn1eDOH76ercEs4cE,2302
11
- dekshell/core/markers/__init__.py,sha256=bmGMbZRqsOohMKjH0AReFxZ-nIPFF6YgPJMFT6gTJEw,1725
9
+ dekshell/core/contexts/methods.py,sha256=2wIXEnqNUram0T_gMtrmuWZd1HqfJnMO7G73wTZ33kQ,7078
10
+ dekshell/core/contexts/properties.py,sha256=6rEQjExvAmZ69OfhPLLIQwnynRzAjX0nIbcBuZ5yuzM,2314
11
+ dekshell/core/markers/__init__.py,sha256=O5N5rURhTW0sZvnVVvtTX_w53zHYjb6KfcUShY46YmM,1762
12
12
  dekshell/core/markers/base/__init__.py,sha256=AQYr7H0F06izu5jhu8EgLYJ2ERzJh0eS38h9gtl6OZs,13067
13
13
  dekshell/core/markers/base/core.py,sha256=99aRcSXohpfTW5OSO1CUyvnptr21ueKjizCk-FK6rcM,10830
14
+ dekshell/core/markers/commands.py,sha256=4frmkrTa7-7ZYWztXEmYprbWRkoCIuJuiy28pBGcz8A,987
14
15
  dekshell/core/markers/comment.py,sha256=28iccgLs_0bRdXLhHyQR2I_kzlWdeMSqqNUFW-2vkes,818
15
16
  dekshell/core/markers/define.py,sha256=LpMSfz9ziXq2aFJ6oMpUFFo93TpBx7GxKYNzCeht4fQ,516
16
17
  dekshell/core/markers/echo.py,sha256=1H61qQbY9tZnrKsdTI_shTmDY5ZaSGipDuBSRptAuZw,660
@@ -21,19 +22,18 @@ dekshell/core/markers/for_.py,sha256=uNOEwyDsjffttEBtUYasdlj7FP_sGnQzWuTV5d5esHY
21
22
  dekshell/core/markers/function.py,sha256=RPh56_rYbWXCTkNPiJu8zNEj-OE6txKgEw7Im9fBM3c,3592
22
23
  dekshell/core/markers/if_.py,sha256=bBG1fDCZd5alE5FSm0QhgHl6ZJn5awiqZAXnPnO-thc,1112
23
24
  dekshell/core/markers/input.py,sha256=HpqE1_PxrmeAVbWxACu0O7SeBVQpBw-aAmNIX5uWWYs,659
24
- dekshell/core/markers/invoke.py,sha256=sXXg0p8Dyg4HQwnWFzWgcyhZYGWvNfhDgUumrrUoWkM,1431
25
+ dekshell/core/markers/invoke.py,sha256=To_U_FscoCbf7osvjC5MQTk2gjH5Mu_-06Kb22YQPTo,1441
25
26
  dekshell/core/markers/pip_.py,sha256=mxXa_oqcrk4Qz-HvhlkMoirsl-SbM9Fz610leNqP1o0,832
26
- dekshell/core/markers/redirect.py,sha256=7r0SpwIDkHkHjEDa26pNq3luOAE69fsFETyv4mKDw5k,1588
27
- dekshell/core/markers/shell.py,sha256=oU_APU2__BO9-LeDE4uYDXClic8MGmwambD2jujkpVc,984
28
- dekshell/core/markers/timout.py,sha256=sC1kNfcA_TFuKZFUaRCSnPHZ5az9Ap8rItSu5RwssUM,915
29
- dekshell/core/markers/var.py,sha256=UEGnKdloRDOSi1KD8aJId9k7WTYkeDIKjsuT7tBJ5Lo,4210
27
+ dekshell/core/markers/redirect.py,sha256=ZMqHnntzJabgqlNXU7Xj1GcYNlfwOyUsZ3rrJTd1yXk,1589
28
+ dekshell/core/markers/shell.py,sha256=6Gy59gjI-BFIQadwGxApD6w3LndIRMao_4D9pMpB5Hk,1906
29
+ dekshell/core/markers/var.py,sha256=rj-gIdu-V8RQigmZ87skCLS-H103ndGgh3zrf3gQEZw,4571
30
30
  dekshell/core/markers/while_.py,sha256=e7lI5jsIM-qxNHMY_wUyCMvvesdXQibR5Ez2jNO9csc,1195
31
31
  dekshell/core/plugin/__init__.py,sha256=jAB_KnnHJsyJR_zIfBU_HNLngyhcyyqVv05PdlNZtF8,428
32
32
  dekshell/core/redirect.py,sha256=6YCJpG0TkQ4WMt7LBtDD_W1T-C-QkLtGRQw0S60qe54,1058
33
33
  dekshell/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  dekshell/utils/beep.py,sha256=teuQgHbWDr8BD1xCJ4Pt79X6N1-eq1tTlyGunK6wBIM,120
35
- dekshell/utils/cmd.py,sha256=_WG7K-CO-WQkI9ERyrhI2d4yT-DX3OjjJWbNzhmsPus,1197
35
+ dekshell/utils/cmd.py,sha256=akykpgPCovXpvavKF28G-eNM3mOZ4TY0LlSWGozDp34,1204
36
36
  dekshell/utils/pkg.py,sha256=TgYqRqawoJfjkxt6UAHnp9ttmpjuHiWRFbqxADOS1VE,1337
37
37
  dekshell/utils/serializer.py,sha256=aIdF2Wzo-qHmIshv46jn1XD0X66vQ1JFdU-g3ZFbH2w,386
38
38
  dekshell/utils/shell.py,sha256=0NoA2-SOOMinbmZZipwzL-npBbzPOdWEfdPVYqq5G5g,92
39
- dekshell-0.2.3.dist-info/RECORD,,
39
+ dekshell-0.2.5.dist-info/RECORD,,
@@ -1,26 +0,0 @@
1
- import subprocess
2
- from dektools.shell import shell_timeout
3
- from .empty import MarkerShell, ShellCommand
4
-
5
-
6
- class TimeoutShellCommand(ShellCommand):
7
- def shell(self, command, timeout=None, env=None, **kwargs):
8
- try:
9
- return shell_timeout(command, timeout, env=env, check=True)
10
- except subprocess.CalledProcessError as e:
11
- return e
12
-
13
-
14
- class TimeoutMarker(MarkerShell):
15
- tag_head = "timeout"
16
-
17
- shell_cls = TimeoutShellCommand
18
-
19
- def execute(self, context, command, marker_node, marker_set):
20
- _, timeout, command = self.split_raw(command, 2)
21
- if command:
22
- self.execute_core_timeout(context, command, marker_node, marker_set, timeout)
23
-
24
- @classmethod
25
- def execute_core_timeout(cls, context, command, marker_node, marker_set, timeout):
26
- return cls.execute_core(context, command, marker_node, marker_set, dict(timeout=int(float(timeout))))