ominfra 0.0.0.dev141__py3-none-any.whl → 0.0.0.dev142__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
ominfra/scripts/manage.py CHANGED
@@ -59,6 +59,9 @@ CallableT = ta.TypeVar('CallableT', bound=ta.Callable)
59
59
  # ../../omlish/lite/check.py
60
60
  SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
61
61
 
62
+ # ../../omlish/lite/subprocesses.py
63
+ SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull']
64
+
62
65
 
63
66
  ########################################
64
67
  # ../commands/base.py
@@ -251,12 +254,14 @@ def _pyremote_bootstrap_main(context_name: str) -> None:
251
254
  os.close(f)
252
255
 
253
256
  # Save vars
254
- os.environ[_PYREMOTE_BOOTSTRAP_CHILD_PID_VAR] = str(cp)
255
- os.environ[_PYREMOTE_BOOTSTRAP_ARGV0_VAR] = sys.executable
256
- os.environ[_PYREMOTE_BOOTSTRAP_CONTEXT_NAME_VAR] = context_name
257
+ env = os.environ
258
+ exe = sys.executable
259
+ env[_PYREMOTE_BOOTSTRAP_CHILD_PID_VAR] = str(cp)
260
+ env[_PYREMOTE_BOOTSTRAP_ARGV0_VAR] = exe
261
+ env[_PYREMOTE_BOOTSTRAP_CONTEXT_NAME_VAR] = context_name
257
262
 
258
263
  # Start repl reading stdin from r0
259
- os.execl(sys.executable, sys.executable + (_PYREMOTE_BOOTSTRAP_PROC_TITLE_FMT % (context_name,)))
264
+ os.execl(exe, exe + (_PYREMOTE_BOOTSTRAP_PROC_TITLE_FMT % (context_name,)))
260
265
 
261
266
  else:
262
267
  # Child process
@@ -320,12 +325,12 @@ def pyremote_build_bootstrap_cmd(context_name: str) -> str:
320
325
  if cl.strip()
321
326
  )
322
327
 
323
- bs_z = zlib.compress(bs_src.encode('utf-8'))
324
- bs_z64 = base64.encodebytes(bs_z).replace(b'\n', b'')
328
+ bs_z = zlib.compress(bs_src.encode('utf-8'), 9)
329
+ bs_z85 = base64.b85encode(bs_z).replace(b'\n', b'')
325
330
 
326
331
  stmts = [
327
332
  f'import {", ".join(_PYREMOTE_BOOTSTRAP_IMPORTS)}',
328
- f'exec(zlib.decompress(base64.decodebytes({bs_z64!r})))',
333
+ f'exec(zlib.decompress(base64.b85decode({bs_z85!r})))',
329
334
  f'_pyremote_bootstrap_main({context_name!r})',
330
335
  ]
331
336
 
@@ -514,7 +519,7 @@ class PyremoteBootstrapDriver:
514
519
 
515
520
  #
516
521
 
517
- def run(self, stdin: ta.IO, stdout: ta.IO) -> Result:
522
+ def run(self, input: ta.IO, output: ta.IO) -> Result: # noqa
518
523
  gen = self.gen()
519
524
 
520
525
  gi: ta.Optional[bytes] = None
@@ -528,12 +533,12 @@ class PyremoteBootstrapDriver:
528
533
  return e.value
529
534
 
530
535
  if isinstance(go, self.Read):
531
- if len(gi := stdout.read(go.sz)) != go.sz:
536
+ if len(gi := input.read(go.sz)) != go.sz:
532
537
  raise EOFError
533
538
  elif isinstance(go, self.Write):
534
539
  gi = None
535
- stdin.write(go.d)
536
- stdin.flush()
540
+ output.write(go.d)
541
+ output.flush()
537
542
  else:
538
543
  raise TypeError(go)
539
544
 
@@ -1286,120 +1291,144 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
1286
1291
  }
1287
1292
 
1288
1293
 
1289
- def _make_obj_marshaler(
1290
- ty: ta.Any,
1291
- rec: ta.Callable[[ta.Any], ObjMarshaler],
1292
- *,
1293
- nonstrict_dataclasses: bool = False,
1294
- ) -> ObjMarshaler:
1295
- if isinstance(ty, type):
1296
- if abc.ABC in ty.__bases__:
1297
- return PolymorphicObjMarshaler.of([ # type: ignore
1298
- PolymorphicObjMarshaler.Impl(
1299
- ity,
1300
- ity.__qualname__,
1301
- rec(ity),
1302
- )
1303
- for ity in deep_subclasses(ty)
1304
- if abc.ABC not in ity.__bases__
1305
- ])
1306
-
1307
- if issubclass(ty, enum.Enum):
1308
- return EnumObjMarshaler(ty)
1309
-
1310
- if dc.is_dataclass(ty):
1311
- return DataclassObjMarshaler(
1312
- ty,
1313
- {f.name: rec(f.type) for f in dc.fields(ty)},
1314
- nonstrict=nonstrict_dataclasses,
1315
- )
1294
+ ##
1316
1295
 
1317
- if is_generic_alias(ty):
1318
- try:
1319
- mt = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES[ta.get_origin(ty)]
1320
- except KeyError:
1321
- pass
1322
- else:
1323
- k, v = ta.get_args(ty)
1324
- return MappingObjMarshaler(mt, rec(k), rec(v))
1325
1296
 
1326
- try:
1327
- st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
1328
- except KeyError:
1329
- pass
1330
- else:
1331
- [e] = ta.get_args(ty)
1332
- return IterableObjMarshaler(st, rec(e))
1297
+ class ObjMarshalerManager:
1298
+ def __init__(
1299
+ self,
1300
+ *,
1301
+ default_obj_marshalers: ta.Dict[ta.Any, ObjMarshaler] = _DEFAULT_OBJ_MARSHALERS, # noqa
1302
+ generic_mapping_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_MAPPING_TYPES, # noqa
1303
+ generic_iterable_types: ta.Dict[ta.Any, type] = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES, # noqa
1304
+ ) -> None:
1305
+ super().__init__()
1333
1306
 
1334
- if is_union_alias(ty):
1335
- return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
1307
+ self._obj_marshalers = dict(default_obj_marshalers)
1308
+ self._generic_mapping_types = generic_mapping_types
1309
+ self._generic_iterable_types = generic_iterable_types
1336
1310
 
1337
- raise TypeError(ty)
1311
+ self._lock = threading.RLock()
1312
+ self._marshalers: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
1313
+ self._proxies: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
1338
1314
 
1315
+ #
1339
1316
 
1340
- ##
1317
+ def make_obj_marshaler(
1318
+ self,
1319
+ ty: ta.Any,
1320
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
1321
+ *,
1322
+ nonstrict_dataclasses: bool = False,
1323
+ ) -> ObjMarshaler:
1324
+ if isinstance(ty, type):
1325
+ if abc.ABC in ty.__bases__:
1326
+ return PolymorphicObjMarshaler.of([ # type: ignore
1327
+ PolymorphicObjMarshaler.Impl(
1328
+ ity,
1329
+ ity.__qualname__,
1330
+ rec(ity),
1331
+ )
1332
+ for ity in deep_subclasses(ty)
1333
+ if abc.ABC not in ity.__bases__
1334
+ ])
1335
+
1336
+ if issubclass(ty, enum.Enum):
1337
+ return EnumObjMarshaler(ty)
1338
+
1339
+ if dc.is_dataclass(ty):
1340
+ return DataclassObjMarshaler(
1341
+ ty,
1342
+ {f.name: rec(f.type) for f in dc.fields(ty)},
1343
+ nonstrict=nonstrict_dataclasses,
1344
+ )
1341
1345
 
1346
+ if is_generic_alias(ty):
1347
+ try:
1348
+ mt = self._generic_mapping_types[ta.get_origin(ty)]
1349
+ except KeyError:
1350
+ pass
1351
+ else:
1352
+ k, v = ta.get_args(ty)
1353
+ return MappingObjMarshaler(mt, rec(k), rec(v))
1342
1354
 
1343
- _OBJ_MARSHALERS_LOCK = threading.RLock()
1355
+ try:
1356
+ st = self._generic_iterable_types[ta.get_origin(ty)]
1357
+ except KeyError:
1358
+ pass
1359
+ else:
1360
+ [e] = ta.get_args(ty)
1361
+ return IterableObjMarshaler(st, rec(e))
1344
1362
 
1345
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
1363
+ if is_union_alias(ty):
1364
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
1346
1365
 
1347
- _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
1366
+ raise TypeError(ty)
1348
1367
 
1368
+ #
1349
1369
 
1350
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
1351
- with _OBJ_MARSHALERS_LOCK:
1352
- if ty in _OBJ_MARSHALERS:
1353
- raise KeyError(ty)
1354
- _OBJ_MARSHALERS[ty] = m
1370
+ def register_opj_marshaler(self, ty: ta.Any, m: ObjMarshaler) -> None:
1371
+ with self._lock:
1372
+ if ty in self._obj_marshalers:
1373
+ raise KeyError(ty)
1374
+ self._obj_marshalers[ty] = m
1355
1375
 
1376
+ def get_obj_marshaler(
1377
+ self,
1378
+ ty: ta.Any,
1379
+ *,
1380
+ no_cache: bool = False,
1381
+ **kwargs: ta.Any,
1382
+ ) -> ObjMarshaler:
1383
+ with self._lock:
1384
+ if not no_cache:
1385
+ try:
1386
+ return self._obj_marshalers[ty]
1387
+ except KeyError:
1388
+ pass
1356
1389
 
1357
- def get_obj_marshaler(
1358
- ty: ta.Any,
1359
- *,
1360
- no_cache: bool = False,
1361
- **kwargs: ta.Any,
1362
- ) -> ObjMarshaler:
1363
- with _OBJ_MARSHALERS_LOCK:
1364
- if not no_cache:
1365
1390
  try:
1366
- return _OBJ_MARSHALERS[ty]
1391
+ return self._proxies[ty]
1367
1392
  except KeyError:
1368
1393
  pass
1369
1394
 
1370
- try:
1371
- return _OBJ_MARSHALER_PROXIES[ty]
1372
- except KeyError:
1373
- pass
1374
-
1375
- rec = functools.partial(
1376
- get_obj_marshaler,
1377
- no_cache=no_cache,
1378
- **kwargs,
1379
- )
1395
+ rec = functools.partial(
1396
+ self.get_obj_marshaler,
1397
+ no_cache=no_cache,
1398
+ **kwargs,
1399
+ )
1380
1400
 
1381
- p = ProxyObjMarshaler()
1382
- _OBJ_MARSHALER_PROXIES[ty] = p
1383
- try:
1384
- m = _make_obj_marshaler(ty, rec, **kwargs)
1385
- finally:
1386
- del _OBJ_MARSHALER_PROXIES[ty]
1387
- p.m = m
1401
+ p = ProxyObjMarshaler()
1402
+ self._proxies[ty] = p
1403
+ try:
1404
+ m = self.make_obj_marshaler(ty, rec, **kwargs)
1405
+ finally:
1406
+ del self._proxies[ty]
1407
+ p.m = m
1388
1408
 
1389
- if not no_cache:
1390
- _OBJ_MARSHALERS[ty] = m
1391
- return m
1409
+ if not no_cache:
1410
+ self._obj_marshalers[ty] = m
1411
+ return m
1412
+
1413
+ #
1414
+
1415
+ def marshal_obj(self, o: ta.Any, ty: ta.Any = None) -> ta.Any:
1416
+ return self.get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
1417
+
1418
+ def unmarshal_obj(self, o: ta.Any, ty: ta.Union[ta.Type[T], ta.Any]) -> T:
1419
+ return self.get_obj_marshaler(ty).unmarshal(o)
1392
1420
 
1393
1421
 
1394
1422
  ##
1395
1423
 
1396
1424
 
1397
- def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
1398
- return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
1425
+ OBJ_MARSHALER_MANAGER = ObjMarshalerManager()
1399
1426
 
1427
+ register_opj_marshaler = OBJ_MARSHALER_MANAGER.register_opj_marshaler
1428
+ get_obj_marshaler = OBJ_MARSHALER_MANAGER.get_obj_marshaler
1400
1429
 
1401
- def unmarshal_obj(o: ta.Any, ty: ta.Union[ta.Type[T], ta.Any]) -> T:
1402
- return get_obj_marshaler(ty).unmarshal(o)
1430
+ marshal_obj = OBJ_MARSHALER_MANAGER.marshal_obj
1431
+ unmarshal_obj = OBJ_MARSHALER_MANAGER.unmarshal_obj
1403
1432
 
1404
1433
 
1405
1434
  ########################################
@@ -1419,6 +1448,48 @@ def check_runtime_version() -> None:
1419
1448
  raise OSError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa
1420
1449
 
1421
1450
 
1451
+ ########################################
1452
+ # ../protocol.py
1453
+
1454
+
1455
+ class Channel:
1456
+ def __init__(
1457
+ self,
1458
+ input: ta.IO, # noqa
1459
+ output: ta.IO,
1460
+ *,
1461
+ msh: ObjMarshalerManager = OBJ_MARSHALER_MANAGER,
1462
+ ) -> None:
1463
+ super().__init__()
1464
+
1465
+ self._input = input
1466
+ self._output = output
1467
+ self._msh = msh
1468
+
1469
+ def send_obj(self, o: ta.Any, ty: ta.Any = None) -> None:
1470
+ j = json_dumps_compact(self._msh.marshal_obj(o, ty))
1471
+ d = j.encode('utf-8')
1472
+
1473
+ self._output.write(struct.pack('<I', len(d)))
1474
+ self._output.write(d)
1475
+ self._output.flush()
1476
+
1477
+ def recv_obj(self, ty: ta.Any) -> ta.Any:
1478
+ d = self._input.read(4)
1479
+ if not d:
1480
+ return None
1481
+ if len(d) != 4:
1482
+ raise EOFError
1483
+
1484
+ sz = struct.unpack('<I', d)[0]
1485
+ d = self._input.read(sz)
1486
+ if len(d) != sz:
1487
+ raise EOFError
1488
+
1489
+ j = json.loads(d.decode('utf-8'))
1490
+ return self._msh.unmarshal_obj(j, ty)
1491
+
1492
+
1422
1493
  ########################################
1423
1494
  # ../../../omlish/lite/subprocesses.py
1424
1495
 
@@ -1426,6 +1497,16 @@ def check_runtime_version() -> None:
1426
1497
  ##
1427
1498
 
1428
1499
 
1500
+ SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
1501
+ 'pipe': subprocess.PIPE,
1502
+ 'stdout': subprocess.STDOUT,
1503
+ 'devnull': subprocess.DEVNULL,
1504
+ }
1505
+
1506
+
1507
+ ##
1508
+
1509
+
1429
1510
  _SUBPROCESS_SHELL_WRAP_EXECS = False
1430
1511
 
1431
1512
 
@@ -1552,21 +1633,21 @@ def subprocess_close(
1552
1633
 
1553
1634
  @dc.dataclass(frozen=True)
1554
1635
  class SubprocessCommand(Command['SubprocessCommand.Output']):
1555
- args: ta.Sequence[str]
1636
+ cmd: ta.Sequence[str]
1556
1637
 
1557
1638
  shell: bool = False
1558
1639
  cwd: ta.Optional[str] = None
1559
1640
  env: ta.Optional[ta.Mapping[str, str]] = None
1560
1641
 
1561
- capture_stdout: bool = False
1562
- capture_stderr: bool = False
1642
+ stdout: str = 'pipe' # SubprocessChannelOption
1643
+ stderr: str = 'pipe' # SubprocessChannelOption
1563
1644
 
1564
1645
  input: ta.Optional[bytes] = None
1565
1646
  timeout: ta.Optional[float] = None
1566
1647
 
1567
1648
  def __post_init__(self) -> None:
1568
- if isinstance(self.args, str):
1569
- raise TypeError(self.args)
1649
+ if isinstance(self.cmd, str):
1650
+ raise TypeError(self.cmd)
1570
1651
 
1571
1652
  @dc.dataclass(frozen=True)
1572
1653
  class Output(Command.Output):
@@ -1584,24 +1665,23 @@ class SubprocessCommand(Command['SubprocessCommand.Output']):
1584
1665
 
1585
1666
  class SubprocessCommandExecutor(CommandExecutor[SubprocessCommand, SubprocessCommand.Output]):
1586
1667
  def execute(self, inp: SubprocessCommand) -> SubprocessCommand.Output:
1587
- proc = subprocess.Popen(
1588
- subprocess_maybe_shell_wrap_exec(*inp.args),
1668
+ with subprocess.Popen(
1669
+ subprocess_maybe_shell_wrap_exec(*inp.cmd),
1589
1670
 
1590
1671
  shell=inp.shell,
1591
1672
  cwd=inp.cwd,
1592
1673
  env={**os.environ, **(inp.env or {})},
1593
1674
 
1594
1675
  stdin=subprocess.PIPE if inp.input is not None else None,
1595
- stdout=subprocess.PIPE if inp.capture_stdout else None,
1596
- stderr=subprocess.PIPE if inp.capture_stderr else None,
1597
- )
1598
-
1599
- start_time = time.time()
1600
- stdout, stderr = proc.communicate(
1601
- input=inp.input,
1602
- timeout=inp.timeout,
1603
- )
1604
- end_time = time.time()
1676
+ stdout=SUBPROCESS_CHANNEL_OPTION_VALUES[ta.cast(SubprocessChannelOption, inp.stdout)],
1677
+ stderr=SUBPROCESS_CHANNEL_OPTION_VALUES[ta.cast(SubprocessChannelOption, inp.stderr)],
1678
+ ) as proc:
1679
+ start_time = time.time()
1680
+ stdout, stderr = proc.communicate(
1681
+ input=inp.input,
1682
+ timeout=inp.timeout,
1683
+ )
1684
+ end_time = time.time()
1605
1685
 
1606
1686
  return SubprocessCommand.Output(
1607
1687
  rc=proc.returncode,
@@ -1628,7 +1708,7 @@ class PySpawner:
1628
1708
  shell: ta.Optional[str] = None,
1629
1709
  shell_quote: bool = False,
1630
1710
  python: str = DEFAULT_PYTHON,
1631
- stderr: ta.Optional[ta.Literal['pipe', 'stdout', 'devnull']] = None,
1711
+ stderr: ta.Optional[SubprocessChannelOption] = None,
1632
1712
  ) -> None:
1633
1713
  super().__init__()
1634
1714
 
@@ -1663,12 +1743,6 @@ class PySpawner:
1663
1743
 
1664
1744
  #
1665
1745
 
1666
- _STDERR_KWARG_MAP: ta.Mapping[str, int] = {
1667
- 'pipe': subprocess.PIPE,
1668
- 'stdout': subprocess.STDOUT,
1669
- 'devnull': subprocess.DEVNULL,
1670
- }
1671
-
1672
1746
  @dc.dataclass(frozen=True)
1673
1747
  class Spawned:
1674
1748
  stdin: ta.IO
@@ -1688,7 +1762,7 @@ class PySpawner:
1688
1762
  shell=pc.shell,
1689
1763
  stdin=subprocess.PIPE,
1690
1764
  stdout=subprocess.PIPE,
1691
- stderr=self._STDERR_KWARG_MAP[self._stderr] if self._stderr is not None else None,
1765
+ stderr=SUBPROCESS_CHANNEL_OPTION_VALUES[self._stderr] if self._stderr is not None else None,
1692
1766
  ) as proc:
1693
1767
  stdin = check_not_none(proc.stdin)
1694
1768
  stdout = check_not_none(proc.stdout)
@@ -1721,51 +1795,28 @@ _COMMAND_TYPES = {
1721
1795
  }
1722
1796
 
1723
1797
 
1724
- @static_init
1725
- def _register_command_marshaling() -> None:
1798
+ ##
1799
+
1800
+
1801
+ def register_command_marshaling(msh: ObjMarshalerManager) -> None:
1726
1802
  for fn in [
1727
1803
  lambda c: c,
1728
1804
  lambda c: c.Output,
1729
1805
  ]:
1730
- register_opj_marshaler(
1806
+ msh.register_opj_marshaler(
1731
1807
  fn(Command),
1732
1808
  PolymorphicObjMarshaler.of([
1733
1809
  PolymorphicObjMarshaler.Impl(
1734
1810
  fn(cty),
1735
1811
  k,
1736
- get_obj_marshaler(fn(cty)),
1812
+ msh.get_obj_marshaler(fn(cty)),
1737
1813
  )
1738
1814
  for k, cty in _COMMAND_TYPES.items()
1739
1815
  ]),
1740
1816
  )
1741
1817
 
1742
1818
 
1743
- ##
1744
-
1745
-
1746
- def _send_obj(f: ta.IO, o: ta.Any, ty: ta.Any = None) -> None:
1747
- j = json_dumps_compact(marshal_obj(o, ty))
1748
- d = j.encode('utf-8')
1749
-
1750
- f.write(struct.pack('<I', len(d)))
1751
- f.write(d)
1752
- f.flush()
1753
-
1754
-
1755
- def _recv_obj(f: ta.IO, ty: ta.Any) -> ta.Any:
1756
- d = f.read(4)
1757
- if not d:
1758
- return None
1759
- if len(d) != 4:
1760
- raise EOFError
1761
-
1762
- sz = struct.unpack('<I', d)[0]
1763
- d = f.read(sz)
1764
- if len(d) != sz:
1765
- raise EOFError
1766
-
1767
- j = json.loads(d.decode('utf-8'))
1768
- return unmarshal_obj(j, ty)
1819
+ register_command_marshaling(OBJ_MARSHALER_MANAGER)
1769
1820
 
1770
1821
 
1771
1822
  ##
@@ -1773,9 +1824,10 @@ def _recv_obj(f: ta.IO, ty: ta.Any) -> ta.Any:
1773
1824
 
1774
1825
  def _remote_main() -> None:
1775
1826
  rt = pyremote_bootstrap_finalize() # noqa
1827
+ chan = Channel(rt.input, rt.output)
1776
1828
 
1777
1829
  while True:
1778
- i = _recv_obj(rt.input, Command)
1830
+ i = chan.recv_obj(Command)
1779
1831
  if i is None:
1780
1832
  break
1781
1833
 
@@ -1784,7 +1836,7 @@ def _remote_main() -> None:
1784
1836
  else:
1785
1837
  raise TypeError(i)
1786
1838
 
1787
- _send_obj(rt.output, o, Command.Output)
1839
+ chan.send_obj(o, Command.Output)
1788
1840
 
1789
1841
 
1790
1842
  ##
@@ -1795,11 +1847,13 @@ def _main() -> None:
1795
1847
 
1796
1848
  parser = argparse.ArgumentParser()
1797
1849
 
1850
+ parser.add_argument('--_payload-file')
1851
+
1798
1852
  parser.add_argument('-s', '--shell')
1799
1853
  parser.add_argument('-q', '--shell-quote', action='store_true')
1800
1854
  parser.add_argument('--python', default='python3')
1855
+
1801
1856
  parser.add_argument('--debug', action='store_true')
1802
- parser.add_argument('--_payload-file')
1803
1857
 
1804
1858
  args = parser.parse_args()
1805
1859
 
@@ -1807,8 +1861,6 @@ def _main() -> None:
1807
1861
 
1808
1862
  payload_src = get_payload_src(file=args._payload_file) # noqa
1809
1863
 
1810
- #
1811
-
1812
1864
  remote_src = '\n\n'.join([
1813
1865
  '__name__ = "__remote__"',
1814
1866
  payload_src,
@@ -1817,41 +1869,32 @@ def _main() -> None:
1817
1869
 
1818
1870
  #
1819
1871
 
1820
- bs_src = pyremote_build_bootstrap_cmd(__package__ or 'manage')
1821
-
1822
- #
1823
-
1824
1872
  spawner = PySpawner(
1825
- bs_src,
1873
+ pyremote_build_bootstrap_cmd(__package__ or 'manage'),
1826
1874
  shell=args.shell,
1827
1875
  shell_quote=args.shell_quote,
1828
1876
  python=args.python,
1829
1877
  )
1878
+
1830
1879
  with spawner.spawn() as proc:
1831
1880
  res = PyremoteBootstrapDriver( # noqa
1832
1881
  remote_src,
1833
1882
  PyremoteBootstrapOptions(
1834
1883
  debug=args.debug,
1835
1884
  ),
1836
- ).run(proc.stdin, proc.stdout)
1837
- # print(res)
1885
+ ).run(proc.stdout, proc.stdin)
1886
+
1887
+ chan = Channel(proc.stdout, proc.stdin)
1838
1888
 
1839
1889
  #
1840
1890
 
1841
1891
  for ci in [
1842
- SubprocessCommand(
1843
- args=['python3', '-'],
1844
- input=b'print(1)\n',
1845
- capture_stdout=True,
1846
- ),
1847
- SubprocessCommand(
1848
- args=['uname'],
1849
- capture_stdout=True,
1850
- ),
1892
+ SubprocessCommand(['python3', '-'], input=b'print(1)\n'),
1893
+ SubprocessCommand(['uname']),
1851
1894
  ]:
1852
- _send_obj(proc.stdin, ci, Command)
1895
+ chan.send_obj(ci, Command)
1853
1896
 
1854
- o = _recv_obj(proc.stdout, Command.Output)
1897
+ o = chan.recv_obj(Command.Output)
1855
1898
 
1856
1899
  print(o)
1857
1900