MCPcopy Create free account
hub / github.com/pyinvoke/invoke / Local

Class Local

invoke/runners.py:1234–1431  ·  view source on GitHub ↗

Execute a command on the local system in a subprocess. .. note:: When Invoke itself is executed without a controlling terminal (e.g. when ``sys.stdin`` lacks a useful ``fileno``), it's not possible to present a handle on our PTY to local subprocesses. In such situat

Source from the content-addressed store, hash-verified

1232
1233
1234class Local(Runner):
1235 """
1236 Execute a command on the local system in a subprocess.
1237
1238 .. note::
1239 When Invoke itself is executed without a controlling terminal (e.g.
1240 when ``sys.stdin`` lacks a useful ``fileno``), it's not possible to
1241 present a handle on our PTY to local subprocesses. In such situations,
1242 `Local` will fallback to behaving as if ``pty=False`` (on the theory
1243 that degraded execution is better than none at all) as well as printing
1244 a warning to stderr.
1245
1246 To disable this behavior, say ``fallback=False``.
1247
1248 .. versionadded:: 1.0
1249 """
1250
1251 def __init__(self, context: "Context") -> None:
1252 super().__init__(context)
1253 # Bookkeeping var for pty use case
1254 self.status = 0
1255
1256 def should_use_pty(self, pty: bool = False, fallback: bool = True) -> bool:
1257 use_pty = False
1258 if pty:
1259 use_pty = True
1260 # TODO: pass in & test in_stream, not sys.stdin
1261 if not has_fileno(sys.stdin) and fallback:
1262 if not self.warned_about_pty_fallback:
1263 err = "WARNING: stdin has no fileno; falling back to non-pty execution!\n" # noqa
1264 sys.stderr.write(err)
1265 self.warned_about_pty_fallback = True
1266 use_pty = False
1267 return use_pty
1268
1269 def read_proc_stdout(self, num_bytes: int) -> Optional[bytes]:
1270 # Obtain useful read-some-bytes function
1271 if self.using_pty:
1272 # Need to handle spurious OSErrors on some Linux platforms.
1273 try:
1274 data = os.read(self.parent_fd, num_bytes)
1275 except OSError as e:
1276 # Only eat I/O specific OSErrors so we don't hide others
1277 stringified = str(e)
1278 io_errors = (
1279 # The typical default
1280 "Input/output error",
1281 # Some less common platforms phrase it this way
1282 "I/O error",
1283 )
1284 if not any(error in stringified for error in io_errors):
1285 raise
1286 # The bad OSErrors happen after all expected output has
1287 # appeared, so we return a falsey value, which triggers the
1288 # "end of output" logic in code using reader functions.
1289 data = None
1290 elif self.process and self.process.stdout:
1291 data = os.read(self.process.stdout.fileno(), num_bytes)

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…