From de62278ab38ca5927e47794ef21034043e87a08d Mon Sep 17 00:00:00 2001 From: Jakub Stasiak Date: Mon, 11 Jul 2016 14:56:06 +0200 Subject: [PATCH] subprocess: Fix patched functions with optional arguments Since [1] we monkey patch subprocess module and it uncovered one issue - the previous patched_function implementation would produce functions with all optional arguments lacking their default values which made them required. This is an issue on Python 3 where there's at least one optional explicit argument in at least one of the functions (check_call), on Python 2 the function signature has *args and **kwargs so it wasn't an issue. This patch is contributed by Smarkets Limited. [1] 614a20462aebfe85a54ce35a7daaf1a7dbde44a7 --- eventlet/green/subprocess.py | 6 +++++- tests/subprocess_test.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/eventlet/green/subprocess.py b/eventlet/green/subprocess.py index 597dfdf..d639cd5 100644 --- a/eventlet/green/subprocess.py +++ b/eventlet/green/subprocess.py @@ -119,7 +119,11 @@ class Popen(subprocess_orig.Popen): # Borrow subprocess.call() and check_call(), but patch them so they reference # OUR Popen class rather than subprocess.Popen. def patched_function(function): - return FunctionType(six.get_function_code(function), globals()) + new_function = FunctionType(six.get_function_code(function), globals()) + if six.PY3: + new_function.__kwdefaults__ = function.__kwdefaults__ + new_function.__defaults__ = function.__defaults__ + return new_function call = patched_function(subprocess_orig.call) diff --git a/tests/subprocess_test.py b/tests/subprocess_test.py index 1f07518..d18c623 100644 --- a/tests/subprocess_test.py +++ b/tests/subprocess_test.py @@ -83,3 +83,13 @@ def test_patched_communicate_290(): # with AttributeError module `select` has no `poll` on Linux # unpatched methods are removed for safety reasons in commit f63165c0e3 tests.run_isolated('subprocess_patched_communicate.py') + + +def test_check_call_without_timeout_works(): + # There was a regression that'd result in the following exception: + # TypeError: check_call() missing 1 required keyword-only argument: 'timeout' + subprocess.check_call( + ['ls'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + )