public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-portage-dev] [PATCH] Use asyncio.subprocess.Process directly
@ 2021-03-04 19:24 Matt Turner
  2021-03-06  9:40 ` Zac Medico
  0 siblings, 1 reply; 2+ messages in thread
From: Matt Turner @ 2021-03-04 19:24 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Matt Turner

With no need to support Python 2, we can remove our private
implementation.

Signed-off-by: Matt Turner <mattst88@gentoo.org>
---
I don't know how to test this. I intentionally broke the return value of
create_subprocess_exec and didn't see any bad results.

 lib/portage/util/futures/_asyncio/__init__.py |   8 +-
 lib/portage/util/futures/_asyncio/process.py  | 116 ------------------
 2 files changed, 4 insertions(+), 120 deletions(-)
 delete mode 100644 lib/portage/util/futures/_asyncio/process.py

diff --git a/lib/portage/util/futures/_asyncio/__init__.py b/lib/portage/util/futures/_asyncio/__init__.py
index 5590963f1..207e7205d 100644
--- a/lib/portage/util/futures/_asyncio/__init__.py
+++ b/lib/portage/util/futures/_asyncio/__init__.py
@@ -25,6 +25,7 @@ import types
 import weakref
 
 import asyncio as _real_asyncio
+from asyncio.subprocess import Process
 
 try:
 	import threading
@@ -45,7 +46,6 @@ from portage.util.futures.futures import (
 	TimeoutError,
 )
 # pylint: enable=redefined-builtin
-from portage.util.futures._asyncio.process import _Process
 from portage.util.futures._asyncio.tasks import (
 	ALL_COMPLETED,
 	FIRST_COMPLETED,
@@ -124,8 +124,8 @@ def create_subprocess_exec(*args, **kwargs):
 	@type loop: event loop
 	@type kwargs: varies
 	@param kwargs: subprocess.Popen parameters
-	@rtype: asyncio.Future (or compatible)
-	@return: subset of asyncio.subprocess.Process interface
+	@rtype: asyncio.subprocess.Process (or compatible)
+	@return: asyncio.subprocess.Process interface
 	"""
 	loop = _wrap_loop(kwargs.pop('loop', None))
 	# Python 3.4 and later implement PEP 446, which makes newly
@@ -138,7 +138,7 @@ def create_subprocess_exec(*args, **kwargs):
 
 	result = loop.create_future()
 
-	result.set_result(_Process(subprocess.Popen(
+	result.set_result(Process(subprocess.Popen(
 		args,
 		stdin=kwargs.pop('stdin', None),
 		stdout=kwargs.pop('stdout', None),
diff --git a/lib/portage/util/futures/_asyncio/process.py b/lib/portage/util/futures/_asyncio/process.py
deleted file mode 100644
index 275c9031a..000000000
--- a/lib/portage/util/futures/_asyncio/process.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright 2018-2020 Gentoo Authors
-# Distributed under the terms of the GNU General Public License v2
-
-import os
-
-import portage
-portage.proxy.lazyimport.lazyimport(globals(),
-	'portage.util.futures:asyncio',
-	'portage.util.futures.unix_events:_set_nonblocking',
-)
-from portage.util.futures._asyncio.streams import _reader, _writer
-from portage.util.futures.compat_coroutine import coroutine, coroutine_return
-
-
-class _Process:
-	"""
-	Emulate a subset of the asyncio.subprocess.Process interface,
-	for python2.
-	"""
-	def __init__(self, proc, loop):
-		"""
-		@param proc: process instance
-		@type proc: subprocess.Popen
-		@param loop: asyncio.AbstractEventLoop (or compatible)
-		@type loop: event loop
-		"""
-		self._proc = proc
-		self._loop = loop
-		self.terminate = proc.terminate
-		self.kill = proc.kill
-		self.send_signal = proc.send_signal
-		self.pid = proc.pid
-		self._waiters = []
-		loop._asyncio_child_watcher.\
-			add_child_handler(self.pid, self._proc_exit)
-
-	@property
-	def returncode(self):
-		return self._proc.returncode
-
-	@coroutine
-	def communicate(self, input=None, loop=None): # pylint: disable=redefined-builtin
-		"""
-		Read data from stdout and stderr, until end-of-file is reached.
-		Wait for process to terminate.
-
-		@param input: stdin content to write
-		@type input: bytes
-		@return: tuple (stdout_data, stderr_data)
-		@rtype: asyncio.Future (or compatible)
-		"""
-		loop = asyncio._wrap_loop(loop or self._loop)
-		futures = []
-		for input_file in (self._proc.stdout, self._proc.stderr):
-			if input_file is None:
-				future = loop.create_future()
-				future.set_result(None)
-			else:
-				future = _reader(input_file, loop=loop)
-			futures.append(future)
-
-		writer = None
-		if input is not None:
-			if self._proc.stdin is None:
-				raise TypeError('communicate: expected file or int, got {}'.format(type(self._proc.stdin)))
-			stdin = self._proc.stdin
-			stdin = os.fdopen(stdin, 'wb', 0) if isinstance(stdin, int) else stdin
-			_set_nonblocking(stdin.fileno())
-			writer = asyncio.ensure_future(_writer(stdin, input, loop=loop), loop=loop)
-			writer.add_done_callback(lambda writer: stdin.close())
-
-		try:
-			yield asyncio.wait(futures + [self.wait(loop=loop)], loop=loop)
-		finally:
-			if writer is not None:
-				if writer.done():
-					# Consume expected exceptions.
-					try:
-						writer.result()
-					except EnvironmentError:
-						# This is normal if the other end of the pipe was closed.
-						pass
-				else:
-					writer.cancel()
-
-		coroutine_return(tuple(future.result() for future in futures))
-
-	def wait(self, loop=None):
-		"""
-		Wait for child process to terminate. Set and return returncode attribute.
-
-		@return: returncode
-		@rtype: asyncio.Future (or compatible)
-		"""
-		loop = asyncio._wrap_loop(loop or self._loop)
-		waiter = loop.create_future()
-		if self.returncode is None:
-			self._waiters.append(waiter)
-			waiter.add_done_callback(self._waiter_cancel)
-		else:
-			waiter.set_result(self.returncode)
-		return waiter
-
-	def _waiter_cancel(self, waiter):
-		if waiter.cancelled():
-			try:
-				self._waiters.remove(waiter)
-			except ValueError:
-				pass
-
-	def _proc_exit(self, pid, returncode):
-		self._proc.returncode = returncode
-		waiters = self._waiters
-		self._waiters = []
-		for waiter in waiters:
-			waiter.set_result(returncode)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [gentoo-portage-dev] [PATCH] Use asyncio.subprocess.Process directly
  2021-03-04 19:24 [gentoo-portage-dev] [PATCH] Use asyncio.subprocess.Process directly Matt Turner
@ 2021-03-06  9:40 ` Zac Medico
  0 siblings, 0 replies; 2+ messages in thread
From: Zac Medico @ 2021-03-06  9:40 UTC (permalink / raw
  To: gentoo-portage-dev, Matt Turner


[-- Attachment #1.1: Type: text/plain, Size: 1609 bytes --]

On 3/4/21 11:24 AM, Matt Turner wrote:
> With no need to support Python 2, we can remove our private
> implementation.
> 
> Signed-off-by: Matt Turner <mattst88@gentoo.org>
> ---
> I don't know how to test this. I intentionally broke the return value of
> create_subprocess_exec and didn't see any bad results.
> 
>  lib/portage/util/futures/_asyncio/__init__.py |   8 +-
>  lib/portage/util/futures/_asyncio/process.py  | 116 ------------------
>  2 files changed, 4 insertions(+), 120 deletions(-)
>  delete mode 100644 lib/portage/util/futures/_asyncio/process.py

Merged, thanks!

https://gitweb.gentoo.org/proj/portage.git/commit/?id=1e843f853a9afe82d599e6ab09064147ddc1d271


> diff --git a/lib/portage/util/futures/_asyncio/__init__.py b/lib/portage/util/futures/_asyncio/__init__.py
> index 5590963f1..207e7205d 100644
> --- a/lib/portage/util/futures/_asyncio/__init__.py
> +++ b/lib/portage/util/futures/_asyncio/__init__.py
> @@ -25,6 +25,7 @@ import types
>  import weakref
>  
>  import asyncio as _real_asyncio
> +from asyncio.subprocess import Process
>  
>  try:
>  	import threading
> @@ -138,7 +138,7 @@ def create_subprocess_exec(*args, **kwargs):
>  
>  	result = loop.create_future()
>  
> -	result.set_result(_Process(subprocess.Popen(
> +	result.set_result(Process(subprocess.Popen(
>  		args,
>  		stdin=kwargs.pop('stdin', None),
>  		stdout=kwargs.pop('stdout', None),

The above area is actually no longer used, since we should always have a
_AsyncioEventLoop instance here, and we can remove the EventLoop class now.
-- 
Thanks,
Zac


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 981 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-03-06  9:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-04 19:24 [gentoo-portage-dev] [PATCH] Use asyncio.subprocess.Process directly Matt Turner
2021-03-06  9:40 ` Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox