mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	asyncio, Tulip issue 130: Add more checks on subprocess_exec/subprocess_shell
parameters
This commit is contained in:
		
							parent
							
								
									a125497ea3
								
							
						
					
					
						commit
						4e8d2f25e2
					
				
					 3 changed files with 64 additions and 7 deletions
				
			
		|  | @ -558,7 +558,7 @@ def subprocess_shell(self, protocol_factory, cmd, *, stdin=subprocess.PIPE, | ||||||
|                          stdout=subprocess.PIPE, stderr=subprocess.PIPE, |                          stdout=subprocess.PIPE, stderr=subprocess.PIPE, | ||||||
|                          universal_newlines=False, shell=True, bufsize=0, |                          universal_newlines=False, shell=True, bufsize=0, | ||||||
|                          **kwargs): |                          **kwargs): | ||||||
|         if not isinstance(cmd, str): |         if not isinstance(cmd, (bytes, str)): | ||||||
|             raise ValueError("cmd must be a string") |             raise ValueError("cmd must be a string") | ||||||
|         if universal_newlines: |         if universal_newlines: | ||||||
|             raise ValueError("universal_newlines must be False") |             raise ValueError("universal_newlines must be False") | ||||||
|  | @ -572,7 +572,7 @@ def subprocess_shell(self, protocol_factory, cmd, *, stdin=subprocess.PIPE, | ||||||
|         return transport, protocol |         return transport, protocol | ||||||
| 
 | 
 | ||||||
|     @tasks.coroutine |     @tasks.coroutine | ||||||
|     def subprocess_exec(self, protocol_factory, *args, stdin=subprocess.PIPE, |     def subprocess_exec(self, protocol_factory, program, *args, stdin=subprocess.PIPE, | ||||||
|                         stdout=subprocess.PIPE, stderr=subprocess.PIPE, |                         stdout=subprocess.PIPE, stderr=subprocess.PIPE, | ||||||
|                         universal_newlines=False, shell=False, bufsize=0, |                         universal_newlines=False, shell=False, bufsize=0, | ||||||
|                         **kwargs): |                         **kwargs): | ||||||
|  | @ -582,9 +582,15 @@ def subprocess_exec(self, protocol_factory, *args, stdin=subprocess.PIPE, | ||||||
|             raise ValueError("shell must be False") |             raise ValueError("shell must be False") | ||||||
|         if bufsize != 0: |         if bufsize != 0: | ||||||
|             raise ValueError("bufsize must be 0") |             raise ValueError("bufsize must be 0") | ||||||
|  |         popen_args = (program,) + args | ||||||
|  |         for arg in popen_args: | ||||||
|  |             if not isinstance(arg, (str, bytes)): | ||||||
|  |                 raise TypeError("program arguments must be " | ||||||
|  |                                 "a bytes or text string, not %s" | ||||||
|  |                                 % type(arg).__name__) | ||||||
|         protocol = protocol_factory() |         protocol = protocol_factory() | ||||||
|         transport = yield from self._make_subprocess_transport( |         transport = yield from self._make_subprocess_transport( | ||||||
|             protocol, args, False, stdin, stdout, stderr, bufsize, **kwargs) |             protocol, popen_args, False, stdin, stdout, stderr, bufsize, **kwargs) | ||||||
|         return transport, protocol |         return transport, protocol | ||||||
| 
 | 
 | ||||||
|     def _add_callback(self, handle): |     def _add_callback(self, handle): | ||||||
|  |  | ||||||
|  | @ -180,7 +180,7 @@ def create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None, | ||||||
|     return Process(transport, protocol, loop) |     return Process(transport, protocol, loop) | ||||||
| 
 | 
 | ||||||
| @tasks.coroutine | @tasks.coroutine | ||||||
| def create_subprocess_exec(*args, stdin=None, stdout=None, stderr=None, | def create_subprocess_exec(program, *args, stdin=None, stdout=None, stderr=None, | ||||||
|                            loop=None, limit=streams._DEFAULT_LIMIT, **kwds): |                            loop=None, limit=streams._DEFAULT_LIMIT, **kwds): | ||||||
|     if loop is None: |     if loop is None: | ||||||
|         loop = events.get_event_loop() |         loop = events.get_event_loop() | ||||||
|  | @ -188,7 +188,8 @@ def create_subprocess_exec(*args, stdin=None, stdout=None, stderr=None, | ||||||
|                                                         loop=loop) |                                                         loop=loop) | ||||||
|     transport, protocol = yield from loop.subprocess_exec( |     transport, protocol = yield from loop.subprocess_exec( | ||||||
|                                             protocol_factory, |                                             protocol_factory, | ||||||
|                                             *args, stdin=stdin, stdout=stdout, |                                             program, *args, | ||||||
|  |                                             stdin=stdin, stdout=stdout, | ||||||
|                                             stderr=stderr, **kwds) |                                             stderr=stderr, **kwds) | ||||||
|     yield from protocol.waiter |     yield from protocol.waiter | ||||||
|     return Process(transport, protocol, loop) |     return Process(transport, protocol, loop) | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| import errno | import errno | ||||||
| import logging | import logging | ||||||
| import socket | import socket | ||||||
|  | import sys | ||||||
| import time | import time | ||||||
| import unittest | import unittest | ||||||
| import unittest.mock | import unittest.mock | ||||||
|  | @ -234,8 +235,57 @@ def cb(loop): | ||||||
|         self.assertEqual([handle], list(self.loop._ready)) |         self.assertEqual([handle], list(self.loop._ready)) | ||||||
| 
 | 
 | ||||||
|     def test_run_until_complete_type_error(self): |     def test_run_until_complete_type_error(self): | ||||||
|         self.assertRaises( |         self.assertRaises(TypeError, | ||||||
|             TypeError, self.loop.run_until_complete, 'blah') |             self.loop.run_until_complete, 'blah') | ||||||
|  | 
 | ||||||
|  |     def test_subprocess_exec_invalid_args(self): | ||||||
|  |         args = [sys.executable, '-c', 'pass'] | ||||||
|  | 
 | ||||||
|  |         # missing program parameter (empty args) | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_exec, | ||||||
|  |             asyncio.SubprocessProtocol) | ||||||
|  | 
 | ||||||
|  |         # exepected multiple arguments, not a list | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_exec, | ||||||
|  |             asyncio.SubprocessProtocol, args) | ||||||
|  | 
 | ||||||
|  |         # program arguments must be strings, not int | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_exec, | ||||||
|  |             asyncio.SubprocessProtocol, sys.executable, 123) | ||||||
|  | 
 | ||||||
|  |         # universal_newlines, shell, bufsize must not be set | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |         self.loop.run_until_complete, self.loop.subprocess_exec, | ||||||
|  |             asyncio.SubprocessProtocol, *args, universal_newlines=True) | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_exec, | ||||||
|  |             asyncio.SubprocessProtocol, *args, shell=True) | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_exec, | ||||||
|  |             asyncio.SubprocessProtocol, *args, bufsize=4096) | ||||||
|  | 
 | ||||||
|  |     def test_subprocess_shell_invalid_args(self): | ||||||
|  |         # exepected a string, not an int or a list | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_shell, | ||||||
|  |             asyncio.SubprocessProtocol, 123) | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_shell, | ||||||
|  |             asyncio.SubprocessProtocol, [sys.executable, '-c', 'pass']) | ||||||
|  | 
 | ||||||
|  |         # universal_newlines, shell, bufsize must not be set | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_shell, | ||||||
|  |             asyncio.SubprocessProtocol, 'exit 0', universal_newlines=True) | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_shell, | ||||||
|  |             asyncio.SubprocessProtocol, 'exit 0', shell=True) | ||||||
|  |         self.assertRaises(TypeError, | ||||||
|  |             self.loop.run_until_complete, self.loop.subprocess_shell, | ||||||
|  |             asyncio.SubprocessProtocol, 'exit 0', bufsize=4096) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class MyProto(asyncio.Protocol): | class MyProto(asyncio.Protocol): | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner