1 |
With no need to support Python 2, we can remove our private |
2 |
implementation. |
3 |
|
4 |
Signed-off-by: Matt Turner <mattst88@g.o> |
5 |
--- |
6 |
I don't know how to test this. I intentionally broke the return value of |
7 |
create_subprocess_exec and didn't see any bad results. |
8 |
|
9 |
lib/portage/util/futures/_asyncio/__init__.py | 8 +- |
10 |
lib/portage/util/futures/_asyncio/process.py | 116 ------------------ |
11 |
2 files changed, 4 insertions(+), 120 deletions(-) |
12 |
delete mode 100644 lib/portage/util/futures/_asyncio/process.py |
13 |
|
14 |
diff --git a/lib/portage/util/futures/_asyncio/__init__.py b/lib/portage/util/futures/_asyncio/__init__.py |
15 |
index 5590963f1..207e7205d 100644 |
16 |
--- a/lib/portage/util/futures/_asyncio/__init__.py |
17 |
+++ b/lib/portage/util/futures/_asyncio/__init__.py |
18 |
@@ -25,6 +25,7 @@ import types |
19 |
import weakref |
20 |
|
21 |
import asyncio as _real_asyncio |
22 |
+from asyncio.subprocess import Process |
23 |
|
24 |
try: |
25 |
import threading |
26 |
@@ -45,7 +46,6 @@ from portage.util.futures.futures import ( |
27 |
TimeoutError, |
28 |
) |
29 |
# pylint: enable=redefined-builtin |
30 |
-from portage.util.futures._asyncio.process import _Process |
31 |
from portage.util.futures._asyncio.tasks import ( |
32 |
ALL_COMPLETED, |
33 |
FIRST_COMPLETED, |
34 |
@@ -124,8 +124,8 @@ def create_subprocess_exec(*args, **kwargs): |
35 |
@type loop: event loop |
36 |
@type kwargs: varies |
37 |
@param kwargs: subprocess.Popen parameters |
38 |
- @rtype: asyncio.Future (or compatible) |
39 |
- @return: subset of asyncio.subprocess.Process interface |
40 |
+ @rtype: asyncio.subprocess.Process (or compatible) |
41 |
+ @return: asyncio.subprocess.Process interface |
42 |
""" |
43 |
loop = _wrap_loop(kwargs.pop('loop', None)) |
44 |
# Python 3.4 and later implement PEP 446, which makes newly |
45 |
@@ -138,7 +138,7 @@ def create_subprocess_exec(*args, **kwargs): |
46 |
|
47 |
result = loop.create_future() |
48 |
|
49 |
- result.set_result(_Process(subprocess.Popen( |
50 |
+ result.set_result(Process(subprocess.Popen( |
51 |
args, |
52 |
stdin=kwargs.pop('stdin', None), |
53 |
stdout=kwargs.pop('stdout', None), |
54 |
diff --git a/lib/portage/util/futures/_asyncio/process.py b/lib/portage/util/futures/_asyncio/process.py |
55 |
deleted file mode 100644 |
56 |
index 275c9031a..000000000 |
57 |
--- a/lib/portage/util/futures/_asyncio/process.py |
58 |
+++ /dev/null |
59 |
@@ -1,116 +0,0 @@ |
60 |
-# Copyright 2018-2020 Gentoo Authors |
61 |
-# Distributed under the terms of the GNU General Public License v2 |
62 |
- |
63 |
-import os |
64 |
- |
65 |
-import portage |
66 |
-portage.proxy.lazyimport.lazyimport(globals(), |
67 |
- 'portage.util.futures:asyncio', |
68 |
- 'portage.util.futures.unix_events:_set_nonblocking', |
69 |
-) |
70 |
-from portage.util.futures._asyncio.streams import _reader, _writer |
71 |
-from portage.util.futures.compat_coroutine import coroutine, coroutine_return |
72 |
- |
73 |
- |
74 |
-class _Process: |
75 |
- """ |
76 |
- Emulate a subset of the asyncio.subprocess.Process interface, |
77 |
- for python2. |
78 |
- """ |
79 |
- def __init__(self, proc, loop): |
80 |
- """ |
81 |
- @param proc: process instance |
82 |
- @type proc: subprocess.Popen |
83 |
- @param loop: asyncio.AbstractEventLoop (or compatible) |
84 |
- @type loop: event loop |
85 |
- """ |
86 |
- self._proc = proc |
87 |
- self._loop = loop |
88 |
- self.terminate = proc.terminate |
89 |
- self.kill = proc.kill |
90 |
- self.send_signal = proc.send_signal |
91 |
- self.pid = proc.pid |
92 |
- self._waiters = [] |
93 |
- loop._asyncio_child_watcher.\ |
94 |
- add_child_handler(self.pid, self._proc_exit) |
95 |
- |
96 |
- @property |
97 |
- def returncode(self): |
98 |
- return self._proc.returncode |
99 |
- |
100 |
- @coroutine |
101 |
- def communicate(self, input=None, loop=None): # pylint: disable=redefined-builtin |
102 |
- """ |
103 |
- Read data from stdout and stderr, until end-of-file is reached. |
104 |
- Wait for process to terminate. |
105 |
- |
106 |
- @param input: stdin content to write |
107 |
- @type input: bytes |
108 |
- @return: tuple (stdout_data, stderr_data) |
109 |
- @rtype: asyncio.Future (or compatible) |
110 |
- """ |
111 |
- loop = asyncio._wrap_loop(loop or self._loop) |
112 |
- futures = [] |
113 |
- for input_file in (self._proc.stdout, self._proc.stderr): |
114 |
- if input_file is None: |
115 |
- future = loop.create_future() |
116 |
- future.set_result(None) |
117 |
- else: |
118 |
- future = _reader(input_file, loop=loop) |
119 |
- futures.append(future) |
120 |
- |
121 |
- writer = None |
122 |
- if input is not None: |
123 |
- if self._proc.stdin is None: |
124 |
- raise TypeError('communicate: expected file or int, got {}'.format(type(self._proc.stdin))) |
125 |
- stdin = self._proc.stdin |
126 |
- stdin = os.fdopen(stdin, 'wb', 0) if isinstance(stdin, int) else stdin |
127 |
- _set_nonblocking(stdin.fileno()) |
128 |
- writer = asyncio.ensure_future(_writer(stdin, input, loop=loop), loop=loop) |
129 |
- writer.add_done_callback(lambda writer: stdin.close()) |
130 |
- |
131 |
- try: |
132 |
- yield asyncio.wait(futures + [self.wait(loop=loop)], loop=loop) |
133 |
- finally: |
134 |
- if writer is not None: |
135 |
- if writer.done(): |
136 |
- # Consume expected exceptions. |
137 |
- try: |
138 |
- writer.result() |
139 |
- except EnvironmentError: |
140 |
- # This is normal if the other end of the pipe was closed. |
141 |
- pass |
142 |
- else: |
143 |
- writer.cancel() |
144 |
- |
145 |
- coroutine_return(tuple(future.result() for future in futures)) |
146 |
- |
147 |
- def wait(self, loop=None): |
148 |
- """ |
149 |
- Wait for child process to terminate. Set and return returncode attribute. |
150 |
- |
151 |
- @return: returncode |
152 |
- @rtype: asyncio.Future (or compatible) |
153 |
- """ |
154 |
- loop = asyncio._wrap_loop(loop or self._loop) |
155 |
- waiter = loop.create_future() |
156 |
- if self.returncode is None: |
157 |
- self._waiters.append(waiter) |
158 |
- waiter.add_done_callback(self._waiter_cancel) |
159 |
- else: |
160 |
- waiter.set_result(self.returncode) |
161 |
- return waiter |
162 |
- |
163 |
- def _waiter_cancel(self, waiter): |
164 |
- if waiter.cancelled(): |
165 |
- try: |
166 |
- self._waiters.remove(waiter) |
167 |
- except ValueError: |
168 |
- pass |
169 |
- |
170 |
- def _proc_exit(self, pid, returncode): |
171 |
- self._proc.returncode = returncode |
172 |
- waiters = self._waiters |
173 |
- self._waiters = [] |
174 |
- for waiter in waiters: |
175 |
- waiter.set_result(returncode) |
176 |
-- |
177 |
2.26.2 |