Commit 9f687e5e authored by Jason Madden's avatar Jason Madden

It might be simple to make subprocess more-or-less work under Windows/Py3....

It might be simple to make subprocess more-or-less work under Windows/Py3. First step is to import the moved names from the right place. Fixes #668. Fixes #669.
parent 7c716778
# Copyright (c) 2009-2012 Denis Bilenko. See LICENSE for details.
# pylint: disable=redefined-outer-name
"""
Make the standard library cooperative.
......@@ -15,8 +16,9 @@ patching to certain modules, but most programs will want to use the
default values as they receive the most wide-spread testing.
Patching *should be done as early as possible* in the lifecycle of the
program. For example, the main module (the one that tests against ``__main__``
or is otherwise the first imported) should begin with this code::
program. For example, the main module (the one that tests against
``__main__`` or is otherwise the first imported) should begin with
this code, ideally before any other imports::
from gevent import monkey
monkey.patch_all()
......@@ -44,7 +46,6 @@ Sometimes it is useful to run existing python scripts or modules that
were not built to be gevent aware under gevent. To do so, this module
can be run as the main module, passing the script and its arguments.
For details, see the :func:`main` function.
"""
from __future__ import absolute_import
from __future__ import print_function
......@@ -52,15 +53,17 @@ import sys
__all__ = [
'patch_all',
'patch_socket',
'patch_ssl',
'patch_builtins',
'patch_dns',
'patch_os',
'patch_time',
'patch_select',
'patch_thread',
'patch_signal',
'patch_socket',
'patch_ssl',
'patch_subprocess',
'patch_sys',
'patch_signal',
'patch_thread',
'patch_time',
# query functions
'get_original',
'is_module_patched',
......@@ -78,6 +81,10 @@ else:
string_types = __builtin__.basestring
PY3 = False
if sys.platform.startswith("win"):
WIN = True
else:
WIN = False
# maps module name -> attribute name -> original item
# e.g. "time" -> "sleep" -> built-in function sleep
......@@ -406,16 +413,30 @@ def patch_select(aggressive=True):
def patch_subprocess():
"""Replace :func:`subprocess.call`, :func:`subprocess.check_call`,
:func:`subprocess.check_output` and :class:`subprocess.Popen` with cooperative versions."""
"""
Replace :func:`subprocess.call`, :func:`subprocess.check_call`,
:func:`subprocess.check_output` and :class:`subprocess.Popen` with
:mod:`cooperative versions <gevent.subprocess>`.
.. note::
On Windows under Python 3, the API support may not completely match
the standard library.
"""
patch_module('subprocess')
def patch_builtins():
"""Make the builtin __import__ function greenlet safe under Python 2"""
# https://github.com/gevent/gevent/issues/108
# Note that this is only needed in Python 2; under Python 3 (at least the versions
# we support) import locks are not global, they're per-module.
"""
Make the builtin __import__ function `greenlet safe`_ under Python 2.
.. note::
This does nothing under Python 3 as it is not necessary. Python 3 features
improved import locks that are per-module, not global.
.. _greenlet safe: https://github.com/gevent/gevent/issues/108
"""
if sys.version_info[:2] < (3, 3):
patch_module('builtins')
......
......@@ -62,6 +62,7 @@ __extra__ = [
'pywintypes',
'list2cmdline',
'_subprocess',
'_winapi',
# Python 2.5 does not have _subprocess, so we don't use it
# XXX We don't run on Py 2.5 anymore; can/could/should we use _subprocess?
'WAIT_OBJECT_0',
......@@ -114,27 +115,29 @@ if sys.version_info[:2] <= (2, 6):
__implements__.remove('check_output')
__extra__.append('check_output')
_subprocess = getattr(__subprocess__, '_subprocess', None)
# In Python 3 on Windows, a lot of the functions previously
# in _subprocess moved to _winapi
_NONE = object()
_subprocess = getattr(__subprocess__, '_subprocess', _NONE)
_winapi = getattr(__subprocess__, '_winapi', _NONE)
for name in __extra__[:]:
_attr_resolution_order = [__subprocess__, _subprocess, _winapi]
for name in list(__extra__):
if name in globals():
continue
value = _NONE
try:
value = getattr(__subprocess__, name)
except AttributeError:
if _subprocess is not None:
try:
value = getattr(_subprocess, name)
except AttributeError:
pass
for place in _attr_resolution_order:
value = getattr(place, name, _NONE)
if value is not _NONE:
break
if value is _NONE:
__extra__.remove(name)
else:
globals()[name] = value
del _attr_resolution_order
__all__ = __implements__ + __imports__
......@@ -742,7 +745,7 @@ class Popen(object):
env,
cwd,
startupinfo)
except pywintypes.error as e:
except IOError as e: # From 2.6 on, pywintypes.error was defined as IOError
# Translate pywintypes.error to WindowsError, which is
# a subclass of OSError. FIXME: We should really
# translate errno using _sys_errlist (or similar), but
......
......@@ -90,17 +90,25 @@ if sys.platform == 'win32':
FAILING_TESTS.append('test_ftplib.py')
if PY3:
# Lets see how close we get
#FAILING_TESTS += [
# We don't have an implementation of subprocess
# on PY3/Windows...
#'test__subprocess_poll.py',
# Therefore we don't monkey-patch it by default because
# it breaks subprocess completely
#'test_subprocess.py',
#]
# XXX need investigating
FAILING_TESTS += [
'test__example_portforwarder.py',
'test__socket_ex.py',
'test__examples.py',
'test_subprocess.py',
'test__issue600.py',
'test__subprocess.py',
'test_threading_2.py',
'FLAKY test__api_timeout.py',
'test__subprocess_poll.py',
'test__example_udp_client.py'
]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment