diff --git a/pymongo/daemon.py b/pymongo/daemon.py index f066a02c23..82502b30de 100644 --- a/pymongo/daemon.py +++ b/pymongo/daemon.py @@ -23,11 +23,14 @@ import subprocess import sys import time +import warnings + # The maximum amount of time to wait for the intermediate subprocess. _WAIT_TIMEOUT = 10 _THIS_FILE = os.path.realpath(__file__) + if sys.version_info[0] < 3: def _popen_wait(popen, timeout): """Implement wait timeout support for Python 2.""" @@ -66,7 +69,9 @@ def _silence_resource_warning(popen): # "ResourceWarning: subprocess XXX is still running". # See https://bugs.python.org/issue38890 and # https://bugs.python.org/issue26741. - popen.returncode = 0 + # popen is None when mongocryptd spawning fails + if popen is not None: + popen.returncode = 0 if sys.platform == 'win32': @@ -75,12 +80,17 @@ def _silence_resource_warning(popen): def _spawn_daemon(args): """Spawn a daemon process (Windows).""" - with open(os.devnull, 'r+b') as devnull: - popen = subprocess.Popen( - args, - creationflags=_DETACHED_PROCESS, - stdin=devnull, stderr=devnull, stdout=devnull) - _silence_resource_warning(popen) + try: + with open(os.devnull, 'r+b') as devnull: + popen = subprocess.Popen( + args, + creationflags=_DETACHED_PROCESS, + stdin=devnull, stderr=devnull, stdout=devnull) + _silence_resource_warning(popen) + except FileNotFoundError as exc: + warnings.warn('Failed to start %s: is it on your $PATH?\n' + 'Original exception: %s' % (args[0], exc), + RuntimeWarning, stacklevel=2) else: # On Unix we spawn the daemon process with a double Popen. # 1) The first Popen runs this file as a Python script using the current @@ -95,12 +105,16 @@ def _spawn_daemon(args): # we spawn the mongocryptd daemon process. def _spawn(args): """Spawn the process and silence stdout/stderr.""" - with open(os.devnull, 'r+b') as devnull: - return subprocess.Popen( - args, - close_fds=True, - stdin=devnull, stderr=devnull, stdout=devnull) - + try: + with open(os.devnull, 'r+b') as devnull: + return subprocess.Popen( + args, + close_fds=True, + stdin=devnull, stderr=devnull, stdout=devnull) + except FileNotFoundError as exc: + warnings.warn('Failed to start %s: is it on your $PATH?\n' + 'Original exception: %s' % (args[0], exc), + RuntimeWarning, stacklevel=2) def _spawn_daemon_double_popen(args): """Spawn a daemon process using a double subprocess.Popen."""