omdev 0.0.0.dev154__py3-none-any.whl → 0.0.0.dev156__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.

Potentially problematic release.


This version of omdev might be problematic. Click here for more details.

omdev/scripts/interp.py CHANGED
@@ -560,8 +560,6 @@ def async_cached_nullary(fn): # ta.Callable[..., T]) -> ta.Callable[..., T]:
560
560
  """
561
561
  TODO:
562
562
  - def maybe(v: lang.Maybe[T])
563
- - patch / override lite.check ?
564
- - checker interface?
565
563
  """
566
564
 
567
565
 
@@ -2082,209 +2080,226 @@ SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
2082
2080
  _SUBPROCESS_SHELL_WRAP_EXECS = False
2083
2081
 
2084
2082
 
2085
- def subprocess_shell_wrap_exec(*args: str) -> ta.Tuple[str, ...]:
2086
- return ('sh', '-c', ' '.join(map(shlex.quote, args)))
2083
+ def subprocess_shell_wrap_exec(*cmd: str) -> ta.Tuple[str, ...]:
2084
+ return ('sh', '-c', ' '.join(map(shlex.quote, cmd)))
2087
2085
 
2088
2086
 
2089
- def subprocess_maybe_shell_wrap_exec(*args: str) -> ta.Tuple[str, ...]:
2087
+ def subprocess_maybe_shell_wrap_exec(*cmd: str) -> ta.Tuple[str, ...]:
2090
2088
  if _SUBPROCESS_SHELL_WRAP_EXECS or is_debugger_attached():
2091
- return subprocess_shell_wrap_exec(*args)
2089
+ return subprocess_shell_wrap_exec(*cmd)
2092
2090
  else:
2093
- return args
2094
-
2095
-
2096
- def prepare_subprocess_invocation(
2097
- *args: str,
2098
- env: ta.Optional[ta.Mapping[str, ta.Any]] = None,
2099
- extra_env: ta.Optional[ta.Mapping[str, ta.Any]] = None,
2100
- quiet: bool = False,
2101
- shell: bool = False,
2102
- **kwargs: ta.Any,
2103
- ) -> ta.Tuple[ta.Tuple[ta.Any, ...], ta.Dict[str, ta.Any]]:
2104
- log.debug('prepare_subprocess_invocation: args=%r', args)
2105
- if extra_env:
2106
- log.debug('prepare_subprocess_invocation: extra_env=%r', extra_env)
2107
-
2108
- if extra_env:
2109
- env = {**(env if env is not None else os.environ), **extra_env}
2110
-
2111
- if quiet and 'stderr' not in kwargs:
2112
- if not log.isEnabledFor(logging.DEBUG):
2113
- kwargs['stderr'] = subprocess.DEVNULL
2114
-
2115
- if not shell:
2116
- args = subprocess_maybe_shell_wrap_exec(*args)
2117
-
2118
- return args, dict(
2119
- env=env,
2120
- shell=shell,
2121
- **kwargs,
2122
- )
2091
+ return cmd
2123
2092
 
2124
2093
 
2125
2094
  ##
2126
2095
 
2127
2096
 
2128
- @contextlib.contextmanager
2129
- def subprocess_common_context(*args: ta.Any, **kwargs: ta.Any) -> ta.Iterator[None]:
2130
- start_time = time.time()
2131
- try:
2132
- log.debug('subprocess_common_context.try: args=%r', args)
2133
- yield
2134
-
2135
- except Exception as exc: # noqa
2136
- log.debug('subprocess_common_context.except: exc=%r', exc)
2137
- raise
2097
+ def subprocess_close(
2098
+ proc: subprocess.Popen,
2099
+ timeout: ta.Optional[float] = None,
2100
+ ) -> None:
2101
+ # TODO: terminate, sleep, kill
2102
+ if proc.stdout:
2103
+ proc.stdout.close()
2104
+ if proc.stderr:
2105
+ proc.stderr.close()
2106
+ if proc.stdin:
2107
+ proc.stdin.close()
2138
2108
 
2139
- finally:
2140
- end_time = time.time()
2141
- elapsed_s = end_time - start_time
2142
- log.debug('subprocess_common_context.finally: elapsed_s=%f args=%r', elapsed_s, args)
2109
+ proc.wait(timeout)
2143
2110
 
2144
2111
 
2145
2112
  ##
2146
2113
 
2147
2114
 
2148
- def subprocess_check_call(
2149
- *args: str,
2150
- stdout: ta.Any = sys.stderr,
2151
- **kwargs: ta.Any,
2152
- ) -> None:
2153
- args, kwargs = prepare_subprocess_invocation(*args, stdout=stdout, **kwargs)
2154
- with subprocess_common_context(*args, **kwargs):
2155
- return subprocess.check_call(args, **kwargs) # type: ignore
2115
+ class AbstractSubprocesses(abc.ABC): # noqa
2116
+ DEFAULT_LOGGER: ta.ClassVar[ta.Optional[logging.Logger]] = log
2156
2117
 
2118
+ def __init__(
2119
+ self,
2120
+ *,
2121
+ log: ta.Optional[logging.Logger] = None,
2122
+ try_exceptions: ta.Optional[ta.Tuple[ta.Type[Exception], ...]] = None,
2123
+ ) -> None:
2124
+ super().__init__()
2157
2125
 
2158
- def subprocess_check_output(
2159
- *args: str,
2160
- **kwargs: ta.Any,
2161
- ) -> bytes:
2162
- args, kwargs = prepare_subprocess_invocation(*args, **kwargs)
2163
- with subprocess_common_context(*args, **kwargs):
2164
- return subprocess.check_output(args, **kwargs)
2126
+ self._log = log if log is not None else self.DEFAULT_LOGGER
2127
+ self._try_exceptions = try_exceptions if try_exceptions is not None else self.DEFAULT_TRY_EXCEPTIONS
2165
2128
 
2129
+ #
2166
2130
 
2167
- def subprocess_check_output_str(*args: str, **kwargs: ta.Any) -> str:
2168
- return subprocess_check_output(*args, **kwargs).decode().strip()
2131
+ def prepare_args(
2132
+ self,
2133
+ *cmd: str,
2134
+ env: ta.Optional[ta.Mapping[str, ta.Any]] = None,
2135
+ extra_env: ta.Optional[ta.Mapping[str, ta.Any]] = None,
2136
+ quiet: bool = False,
2137
+ shell: bool = False,
2138
+ **kwargs: ta.Any,
2139
+ ) -> ta.Tuple[ta.Tuple[ta.Any, ...], ta.Dict[str, ta.Any]]:
2140
+ if self._log:
2141
+ self._log.debug('Subprocesses.prepare_args: cmd=%r', cmd)
2142
+ if extra_env:
2143
+ self._log.debug('Subprocesses.prepare_args: extra_env=%r', extra_env)
2144
+
2145
+ if extra_env:
2146
+ env = {**(env if env is not None else os.environ), **extra_env}
2147
+
2148
+ if quiet and 'stderr' not in kwargs:
2149
+ if self._log and not self._log.isEnabledFor(logging.DEBUG):
2150
+ kwargs['stderr'] = subprocess.DEVNULL
2151
+
2152
+ if not shell:
2153
+ cmd = subprocess_maybe_shell_wrap_exec(*cmd)
2154
+
2155
+ return cmd, dict(
2156
+ env=env,
2157
+ shell=shell,
2158
+ **kwargs,
2159
+ )
2169
2160
 
2161
+ @contextlib.contextmanager
2162
+ def wrap_call(self, *cmd: ta.Any, **kwargs: ta.Any) -> ta.Iterator[None]:
2163
+ start_time = time.time()
2164
+ try:
2165
+ if self._log:
2166
+ self._log.debug('Subprocesses.wrap_call.try: cmd=%r', cmd)
2167
+ yield
2170
2168
 
2171
- ##
2169
+ except Exception as exc: # noqa
2170
+ if self._log:
2171
+ self._log.debug('Subprocesses.wrap_call.except: exc=%r', exc)
2172
+ raise
2172
2173
 
2174
+ finally:
2175
+ end_time = time.time()
2176
+ elapsed_s = end_time - start_time
2177
+ if self._log:
2178
+ self._log.debug('sSubprocesses.wrap_call.finally: elapsed_s=%f cmd=%r', elapsed_s, cmd)
2173
2179
 
2174
- DEFAULT_SUBPROCESS_TRY_EXCEPTIONS: ta.Tuple[ta.Type[Exception], ...] = (
2175
- FileNotFoundError,
2176
- subprocess.CalledProcessError,
2177
- )
2180
+ @contextlib.contextmanager
2181
+ def prepare_and_wrap(
2182
+ self,
2183
+ *cmd: ta.Any,
2184
+ **kwargs: ta.Any,
2185
+ ) -> ta.Iterator[ta.Tuple[
2186
+ ta.Tuple[ta.Any, ...],
2187
+ ta.Dict[str, ta.Any],
2188
+ ]]:
2189
+ cmd, kwargs = self.prepare_args(*cmd, **kwargs)
2190
+ with self.wrap_call(*cmd, **kwargs):
2191
+ yield cmd, kwargs
2178
2192
 
2193
+ #
2179
2194
 
2180
- def _subprocess_try_run(
2181
- fn: ta.Callable[..., T],
2182
- *args: ta.Any,
2183
- try_exceptions: ta.Tuple[ta.Type[Exception], ...] = DEFAULT_SUBPROCESS_TRY_EXCEPTIONS,
2184
- **kwargs: ta.Any,
2185
- ) -> ta.Union[T, Exception]:
2186
- try:
2187
- return fn(*args, **kwargs)
2188
- except try_exceptions as e: # noqa
2189
- if log.isEnabledFor(logging.DEBUG):
2190
- log.exception('command failed')
2191
- return e
2192
-
2193
-
2194
- def subprocess_try_call(
2195
- *args: str,
2196
- try_exceptions: ta.Tuple[ta.Type[Exception], ...] = DEFAULT_SUBPROCESS_TRY_EXCEPTIONS,
2197
- **kwargs: ta.Any,
2198
- ) -> bool:
2199
- if isinstance(_subprocess_try_run(
2200
- subprocess_check_call,
2201
- *args,
2202
- try_exceptions=try_exceptions,
2203
- **kwargs,
2204
- ), Exception):
2205
- return False
2206
- else:
2207
- return True
2195
+ DEFAULT_TRY_EXCEPTIONS: ta.Tuple[ta.Type[Exception], ...] = (
2196
+ FileNotFoundError,
2197
+ subprocess.CalledProcessError,
2198
+ )
2208
2199
 
2200
+ def try_fn(
2201
+ self,
2202
+ fn: ta.Callable[..., T],
2203
+ *cmd: str,
2204
+ try_exceptions: ta.Optional[ta.Tuple[ta.Type[Exception], ...]] = None,
2205
+ **kwargs: ta.Any,
2206
+ ) -> ta.Union[T, Exception]:
2207
+ if try_exceptions is None:
2208
+ try_exceptions = self._try_exceptions
2209
2209
 
2210
- def subprocess_try_output(
2211
- *args: str,
2212
- try_exceptions: ta.Tuple[ta.Type[Exception], ...] = DEFAULT_SUBPROCESS_TRY_EXCEPTIONS,
2213
- **kwargs: ta.Any,
2214
- ) -> ta.Optional[bytes]:
2215
- if isinstance(ret := _subprocess_try_run(
2216
- subprocess_check_output,
2217
- *args,
2218
- try_exceptions=try_exceptions,
2219
- **kwargs,
2220
- ), Exception):
2221
- return None
2222
- else:
2223
- return ret
2210
+ try:
2211
+ return fn(*cmd, **kwargs)
2224
2212
 
2213
+ except try_exceptions as e: # noqa
2214
+ if self._log and self._log.isEnabledFor(logging.DEBUG):
2215
+ self._log.exception('command failed')
2216
+ return e
2225
2217
 
2226
- def subprocess_try_output_str(*args: str, **kwargs: ta.Any) -> ta.Optional[str]:
2227
- out = subprocess_try_output(*args, **kwargs)
2228
- return out.decode().strip() if out is not None else None
2218
+ async def async_try_fn(
2219
+ self,
2220
+ fn: ta.Callable[..., ta.Awaitable[T]],
2221
+ *cmd: ta.Any,
2222
+ try_exceptions: ta.Optional[ta.Tuple[ta.Type[Exception], ...]] = None,
2223
+ **kwargs: ta.Any,
2224
+ ) -> ta.Union[T, Exception]:
2225
+ if try_exceptions is None:
2226
+ try_exceptions = self._try_exceptions
2227
+
2228
+ try:
2229
+ return await fn(*cmd, **kwargs)
2230
+
2231
+ except try_exceptions as e: # noqa
2232
+ if self._log and self._log.isEnabledFor(logging.DEBUG):
2233
+ self._log.exception('command failed')
2234
+ return e
2229
2235
 
2230
2236
 
2231
2237
  ##
2232
2238
 
2233
2239
 
2234
- def subprocess_close(
2235
- proc: subprocess.Popen,
2236
- timeout: ta.Optional[float] = None,
2237
- ) -> None:
2238
- # TODO: terminate, sleep, kill
2239
- if proc.stdout:
2240
- proc.stdout.close()
2241
- if proc.stderr:
2242
- proc.stderr.close()
2243
- if proc.stdin:
2244
- proc.stdin.close()
2240
+ class Subprocesses(AbstractSubprocesses):
2241
+ def check_call(
2242
+ self,
2243
+ *cmd: str,
2244
+ stdout: ta.Any = sys.stderr,
2245
+ **kwargs: ta.Any,
2246
+ ) -> None:
2247
+ with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
2248
+ subprocess.check_call(cmd, **kwargs)
2245
2249
 
2246
- proc.wait(timeout)
2250
+ def check_output(
2251
+ self,
2252
+ *cmd: str,
2253
+ **kwargs: ta.Any,
2254
+ ) -> bytes:
2255
+ with self.prepare_and_wrap(*cmd, **kwargs) as (cmd, kwargs): # noqa
2256
+ return subprocess.check_output(cmd, **kwargs)
2247
2257
 
2258
+ def check_output_str(
2259
+ self,
2260
+ *cmd: str,
2261
+ **kwargs: ta.Any,
2262
+ ) -> str:
2263
+ return self.check_output(*cmd, **kwargs).decode().strip()
2248
2264
 
2249
- ########################################
2250
- # ../../../omlish/lite/asyncio/subprocesses.py
2265
+ #
2251
2266
 
2267
+ def try_call(
2268
+ self,
2269
+ *cmd: str,
2270
+ **kwargs: ta.Any,
2271
+ ) -> bool:
2272
+ if isinstance(self.try_fn(self.check_call, *cmd, **kwargs), Exception):
2273
+ return False
2274
+ else:
2275
+ return True
2252
2276
 
2253
- ##
2277
+ def try_output(
2278
+ self,
2279
+ *cmd: str,
2280
+ **kwargs: ta.Any,
2281
+ ) -> ta.Optional[bytes]:
2282
+ if isinstance(ret := self.try_fn(self.check_output, *cmd, **kwargs), Exception):
2283
+ return None
2284
+ else:
2285
+ return ret
2254
2286
 
2287
+ def try_output_str(
2288
+ self,
2289
+ *cmd: str,
2290
+ **kwargs: ta.Any,
2291
+ ) -> ta.Optional[str]:
2292
+ if (ret := self.try_output(*cmd, **kwargs)) is None:
2293
+ return None
2294
+ else:
2295
+ return ret.decode().strip()
2255
2296
 
2256
- @contextlib.asynccontextmanager
2257
- async def asyncio_subprocess_popen(
2258
- *cmd: str,
2259
- shell: bool = False,
2260
- timeout: ta.Optional[float] = None,
2261
- **kwargs: ta.Any,
2262
- ) -> ta.AsyncGenerator[asyncio.subprocess.Process, None]:
2263
- fac: ta.Any
2264
- if shell:
2265
- fac = functools.partial(
2266
- asyncio.create_subprocess_shell,
2267
- check.single(cmd),
2268
- )
2269
- else:
2270
- fac = functools.partial(
2271
- asyncio.create_subprocess_exec,
2272
- *cmd,
2273
- )
2274
2297
 
2275
- with subprocess_common_context(
2276
- *cmd,
2277
- shell=shell,
2278
- timeout=timeout,
2279
- **kwargs,
2280
- ):
2281
- proc: asyncio.subprocess.Process
2282
- proc = await fac(**kwargs)
2283
- try:
2284
- yield proc
2298
+ subprocesses = Subprocesses()
2285
2299
 
2286
- finally:
2287
- await asyncio_maybe_timeout(proc.wait(), timeout)
2300
+
2301
+ ########################################
2302
+ # ../../../omlish/lite/asyncio/subprocesses.py
2288
2303
 
2289
2304
 
2290
2305
  ##
@@ -2400,137 +2415,147 @@ class AsyncioProcessCommunicator:
2400
2415
  return await asyncio_maybe_timeout(self._communicate(input), timeout)
2401
2416
 
2402
2417
 
2403
- async def asyncio_subprocess_communicate(
2404
- proc: asyncio.subprocess.Process,
2405
- input: ta.Any = None, # noqa
2406
- timeout: ta.Optional[float] = None,
2407
- ) -> ta.Tuple[ta.Optional[bytes], ta.Optional[bytes]]:
2408
- return await AsyncioProcessCommunicator(proc).communicate(input, timeout) # noqa
2418
+ ##
2409
2419
 
2410
2420
 
2411
- async def asyncio_subprocess_run(
2412
- *args: str,
2413
- input: ta.Any = None, # noqa
2414
- timeout: ta.Optional[float] = None,
2415
- check: bool = False, # noqa
2416
- capture_output: ta.Optional[bool] = None,
2417
- **kwargs: ta.Any,
2418
- ) -> ta.Tuple[ta.Optional[bytes], ta.Optional[bytes]]:
2419
- if capture_output:
2420
- kwargs.setdefault('stdout', subprocess.PIPE)
2421
- kwargs.setdefault('stderr', subprocess.PIPE)
2422
-
2423
- args, kwargs = prepare_subprocess_invocation(*args, **kwargs)
2424
-
2425
- proc: asyncio.subprocess.Process
2426
- async with asyncio_subprocess_popen(*args, **kwargs) as proc:
2427
- stdout, stderr = await asyncio_subprocess_communicate(proc, input, timeout)
2428
-
2429
- if check and proc.returncode:
2430
- raise subprocess.CalledProcessError(
2431
- proc.returncode,
2432
- args,
2433
- output=stdout,
2434
- stderr=stderr,
2435
- )
2421
+ class AsyncioSubprocesses(AbstractSubprocesses):
2422
+ async def communicate(
2423
+ self,
2424
+ proc: asyncio.subprocess.Process,
2425
+ input: ta.Any = None, # noqa
2426
+ timeout: ta.Optional[float] = None,
2427
+ ) -> ta.Tuple[ta.Optional[bytes], ta.Optional[bytes]]:
2428
+ return await AsyncioProcessCommunicator(proc).communicate(input, timeout) # noqa
2436
2429
 
2437
- return stdout, stderr
2430
+ #
2438
2431
 
2432
+ @contextlib.asynccontextmanager
2433
+ async def popen(
2434
+ self,
2435
+ *cmd: str,
2436
+ shell: bool = False,
2437
+ timeout: ta.Optional[float] = None,
2438
+ **kwargs: ta.Any,
2439
+ ) -> ta.AsyncGenerator[asyncio.subprocess.Process, None]:
2440
+ fac: ta.Any
2441
+ if shell:
2442
+ fac = functools.partial(
2443
+ asyncio.create_subprocess_shell,
2444
+ check.single(cmd),
2445
+ )
2446
+ else:
2447
+ fac = functools.partial(
2448
+ asyncio.create_subprocess_exec,
2449
+ *cmd,
2450
+ )
2439
2451
 
2440
- ##
2452
+ with self.prepare_and_wrap( *cmd, shell=shell, **kwargs) as (cmd, kwargs): # noqa
2453
+ proc: asyncio.subprocess.Process = await fac(**kwargs)
2454
+ try:
2455
+ yield proc
2441
2456
 
2457
+ finally:
2458
+ await asyncio_maybe_timeout(proc.wait(), timeout)
2442
2459
 
2443
- async def asyncio_subprocess_check_call(
2444
- *args: str,
2445
- stdout: ta.Any = sys.stderr,
2446
- input: ta.Any = None, # noqa
2447
- timeout: ta.Optional[float] = None,
2448
- **kwargs: ta.Any,
2449
- ) -> None:
2450
- _, _ = await asyncio_subprocess_run(
2451
- *args,
2452
- stdout=stdout,
2453
- input=input,
2454
- timeout=timeout,
2455
- check=True,
2456
- **kwargs,
2457
- )
2460
+ #
2458
2461
 
2462
+ @dc.dataclass(frozen=True)
2463
+ class RunOutput:
2464
+ proc: asyncio.subprocess.Process
2465
+ stdout: ta.Optional[bytes]
2466
+ stderr: ta.Optional[bytes]
2459
2467
 
2460
- async def asyncio_subprocess_check_output(
2461
- *args: str,
2462
- input: ta.Any = None, # noqa
2463
- timeout: ta.Optional[float] = None,
2464
- **kwargs: ta.Any,
2465
- ) -> bytes:
2466
- stdout, stderr = await asyncio_subprocess_run(
2467
- *args,
2468
- stdout=asyncio.subprocess.PIPE,
2469
- input=input,
2470
- timeout=timeout,
2471
- check=True,
2472
- **kwargs,
2473
- )
2468
+ async def run(
2469
+ self,
2470
+ *cmd: str,
2471
+ input: ta.Any = None, # noqa
2472
+ timeout: ta.Optional[float] = None,
2473
+ check: bool = False, # noqa
2474
+ capture_output: ta.Optional[bool] = None,
2475
+ **kwargs: ta.Any,
2476
+ ) -> RunOutput:
2477
+ if capture_output:
2478
+ kwargs.setdefault('stdout', subprocess.PIPE)
2479
+ kwargs.setdefault('stderr', subprocess.PIPE)
2474
2480
 
2475
- return check.not_none(stdout)
2481
+ proc: asyncio.subprocess.Process
2482
+ async with self.popen(*cmd, **kwargs) as proc:
2483
+ stdout, stderr = await self.communicate(proc, input, timeout)
2484
+
2485
+ if check and proc.returncode:
2486
+ raise subprocess.CalledProcessError(
2487
+ proc.returncode,
2488
+ cmd,
2489
+ output=stdout,
2490
+ stderr=stderr,
2491
+ )
2476
2492
 
2493
+ return self.RunOutput(
2494
+ proc,
2495
+ stdout,
2496
+ stderr,
2497
+ )
2477
2498
 
2478
- async def asyncio_subprocess_check_output_str(*args: str, **kwargs: ta.Any) -> str:
2479
- return (await asyncio_subprocess_check_output(*args, **kwargs)).decode().strip()
2499
+ #
2480
2500
 
2501
+ async def check_call(
2502
+ self,
2503
+ *cmd: str,
2504
+ stdout: ta.Any = sys.stderr,
2505
+ **kwargs: ta.Any,
2506
+ ) -> None:
2507
+ with self.prepare_and_wrap(*cmd, stdout=stdout, check=True, **kwargs) as (cmd, kwargs): # noqa
2508
+ await self.run(*cmd, **kwargs)
2481
2509
 
2482
- ##
2510
+ async def check_output(
2511
+ self,
2512
+ *cmd: str,
2513
+ **kwargs: ta.Any,
2514
+ ) -> bytes:
2515
+ with self.prepare_and_wrap(*cmd, stdout=subprocess.PIPE, check=True, **kwargs) as (cmd, kwargs): # noqa
2516
+ return check.not_none((await self.run(*cmd, **kwargs)).stdout)
2483
2517
 
2518
+ async def check_output_str(
2519
+ self,
2520
+ *cmd: str,
2521
+ **kwargs: ta.Any,
2522
+ ) -> str:
2523
+ return (await self.check_output(*cmd, **kwargs)).decode().strip()
2484
2524
 
2485
- async def _asyncio_subprocess_try_run(
2486
- fn: ta.Callable[..., ta.Awaitable[T]],
2487
- *args: ta.Any,
2488
- try_exceptions: ta.Tuple[ta.Type[Exception], ...] = DEFAULT_SUBPROCESS_TRY_EXCEPTIONS,
2489
- **kwargs: ta.Any,
2490
- ) -> ta.Union[T, Exception]:
2491
- try:
2492
- return await fn(*args, **kwargs)
2493
- except try_exceptions as e: # noqa
2494
- if log.isEnabledFor(logging.DEBUG):
2495
- log.exception('command failed')
2496
- return e
2497
-
2498
-
2499
- async def asyncio_subprocess_try_call(
2500
- *args: str,
2501
- try_exceptions: ta.Tuple[ta.Type[Exception], ...] = DEFAULT_SUBPROCESS_TRY_EXCEPTIONS,
2502
- **kwargs: ta.Any,
2503
- ) -> bool:
2504
- if isinstance(await _asyncio_subprocess_try_run(
2505
- asyncio_subprocess_check_call,
2506
- *args,
2507
- try_exceptions=try_exceptions,
2508
- **kwargs,
2509
- ), Exception):
2510
- return False
2511
- else:
2512
- return True
2525
+ #
2513
2526
 
2527
+ async def try_call(
2528
+ self,
2529
+ *cmd: str,
2530
+ **kwargs: ta.Any,
2531
+ ) -> bool:
2532
+ if isinstance(await self.async_try_fn(self.check_call, *cmd, **kwargs), Exception):
2533
+ return False
2534
+ else:
2535
+ return True
2514
2536
 
2515
- async def asyncio_subprocess_try_output(
2516
- *args: str,
2517
- try_exceptions: ta.Tuple[ta.Type[Exception], ...] = DEFAULT_SUBPROCESS_TRY_EXCEPTIONS,
2518
- **kwargs: ta.Any,
2519
- ) -> ta.Optional[bytes]:
2520
- if isinstance(ret := await _asyncio_subprocess_try_run(
2521
- asyncio_subprocess_check_output,
2522
- *args,
2523
- try_exceptions=try_exceptions,
2524
- **kwargs,
2525
- ), Exception):
2526
- return None
2527
- else:
2528
- return ret
2537
+ async def try_output(
2538
+ self,
2539
+ *cmd: str,
2540
+ **kwargs: ta.Any,
2541
+ ) -> ta.Optional[bytes]:
2542
+ if isinstance(ret := await self.async_try_fn(self.check_output, *cmd, **kwargs), Exception):
2543
+ return None
2544
+ else:
2545
+ return ret
2546
+
2547
+ async def try_output_str(
2548
+ self,
2549
+ *cmd: str,
2550
+ **kwargs: ta.Any,
2551
+ ) -> ta.Optional[str]:
2552
+ if (ret := await self.try_output(*cmd, **kwargs)) is None:
2553
+ return None
2554
+ else:
2555
+ return ret.decode().strip()
2529
2556
 
2530
2557
 
2531
- async def asyncio_subprocess_try_output_str(*args: str, **kwargs: ta.Any) -> ta.Optional[str]:
2532
- out = await asyncio_subprocess_try_output(*args, **kwargs)
2533
- return out.decode().strip() if out is not None else None
2558
+ asyncio_subprocesses = AsyncioSubprocesses()
2534
2559
 
2535
2560
 
2536
2561
  ########################################
@@ -2607,7 +2632,7 @@ class InterpInspector:
2607
2632
  return cls._build_inspection(sys.executable, eval(cls._INSPECTION_CODE)) # noqa
2608
2633
 
2609
2634
  async def _inspect(self, exe: str) -> InterpInspection:
2610
- output = await asyncio_subprocess_check_output(exe, '-c', f'print({self._INSPECTION_CODE})', quiet=True)
2635
+ output = await asyncio_subprocesses.check_output(exe, '-c', f'print({self._INSPECTION_CODE})', quiet=True)
2611
2636
  return self._build_inspection(exe, output.decode())
2612
2637
 
2613
2638
  async def inspect(self, exe: str) -> ta.Optional[InterpInspection]:
@@ -2726,7 +2751,7 @@ class Pyenv:
2726
2751
  return self._root_kw
2727
2752
 
2728
2753
  if shutil.which('pyenv'):
2729
- return await asyncio_subprocess_check_output_str('pyenv', 'root')
2754
+ return await asyncio_subprocesses.check_output_str('pyenv', 'root')
2730
2755
 
2731
2756
  d = os.path.expanduser('~/.pyenv')
2732
2757
  if os.path.isdir(d) and os.path.isfile(os.path.join(d, 'bin', 'pyenv')):
@@ -2755,7 +2780,7 @@ class Pyenv:
2755
2780
  if await self.root() is None:
2756
2781
  return []
2757
2782
  ret = []
2758
- s = await asyncio_subprocess_check_output_str(await self.exe(), 'install', '--list')
2783
+ s = await asyncio_subprocesses.check_output_str(await self.exe(), 'install', '--list')
2759
2784
  for l in s.splitlines():
2760
2785
  if not l.startswith(' '):
2761
2786
  continue
@@ -2770,7 +2795,7 @@ class Pyenv:
2770
2795
  return False
2771
2796
  if not os.path.isdir(os.path.join(root, '.git')):
2772
2797
  return False
2773
- await asyncio_subprocess_check_call('git', 'pull', cwd=root)
2798
+ await asyncio_subprocesses.check_call('git', 'pull', cwd=root)
2774
2799
  return True
2775
2800
 
2776
2801
 
@@ -2861,7 +2886,7 @@ class DarwinPyenvInstallOpts(PyenvInstallOptsProvider):
2861
2886
  cflags = []
2862
2887
  ldflags = []
2863
2888
  for dep in self.BREW_DEPS:
2864
- dep_prefix = await asyncio_subprocess_check_output_str('brew', '--prefix', dep)
2889
+ dep_prefix = await asyncio_subprocesses.check_output_str('brew', '--prefix', dep)
2865
2890
  cflags.append(f'-I{dep_prefix}/include')
2866
2891
  ldflags.append(f'-L{dep_prefix}/lib')
2867
2892
  return PyenvInstallOpts(
@@ -2871,11 +2896,11 @@ class DarwinPyenvInstallOpts(PyenvInstallOptsProvider):
2871
2896
 
2872
2897
  @async_cached_nullary
2873
2898
  async def brew_tcl_opts(self) -> PyenvInstallOpts:
2874
- if await asyncio_subprocess_try_output('brew', '--prefix', 'tcl-tk') is None:
2899
+ if await asyncio_subprocesses.try_output('brew', '--prefix', 'tcl-tk') is None:
2875
2900
  return PyenvInstallOpts()
2876
2901
 
2877
- tcl_tk_prefix = await asyncio_subprocess_check_output_str('brew', '--prefix', 'tcl-tk')
2878
- tcl_tk_ver_str = await asyncio_subprocess_check_output_str('brew', 'ls', '--versions', 'tcl-tk')
2902
+ tcl_tk_prefix = await asyncio_subprocesses.check_output_str('brew', '--prefix', 'tcl-tk')
2903
+ tcl_tk_ver_str = await asyncio_subprocesses.check_output_str('brew', 'ls', '--versions', 'tcl-tk')
2879
2904
  tcl_tk_ver = '.'.join(tcl_tk_ver_str.split()[1].split('.')[:2])
2880
2905
 
2881
2906
  return PyenvInstallOpts(conf_opts=[
@@ -2996,7 +3021,7 @@ class PyenvVersionInstaller:
2996
3021
  *conf_args,
2997
3022
  ]
2998
3023
 
2999
- await asyncio_subprocess_check_call(
3024
+ await asyncio_subprocesses.check_call(
3000
3025
  *full_args,
3001
3026
  env=env,
3002
3027
  )