Commit 436f6557 authored by Jason Madden's avatar Jason Madden

Remove a duplicate warning on re-patching and don't use a global variable to track the state.

parent 4eed30f2
...@@ -164,21 +164,19 @@ def patch_module(name, items=None): ...@@ -164,21 +164,19 @@ def patch_module(name, items=None):
return module return module
_warnings = list() def _queue_warning(message, _warnings):
def _queue_warning(message):
# Queues a warning to show after the monkey-patching process is all done. # Queues a warning to show after the monkey-patching process is all done.
# Done this way to avoid extra imports during the process itself, just # Done this way to avoid extra imports during the process itself, just
# in case # in case. If we're calling a function one-off (unusual) go ahead and do it
_warnings.append(message) if _warnings is None:
_process_warnings([message])
else:
_warnings.append(message)
def _process_warnings(): def _process_warnings(_warnings):
import warnings import warnings
_w = list(_warnings) for warning in _warnings:
del _warnings[:]
for warning in _w:
warnings.warn(warning, RuntimeWarning, stacklevel=3) warnings.warn(warning, RuntimeWarning, stacklevel=3)
...@@ -271,7 +269,8 @@ def _patch_existing_locks(threading): ...@@ -271,7 +269,8 @@ def _patch_existing_locks(threading):
def patch_thread(threading=True, _threading_local=True, Event=False, logging=True, def patch_thread(threading=True, _threading_local=True, Event=False, logging=True,
existing_locks=True): existing_locks=True,
_warnings=None):
""" """
Replace the standard :mod:`thread` module to make it greenlet-based. Replace the standard :mod:`thread` module to make it greenlet-based.
...@@ -389,7 +388,8 @@ def patch_thread(threading=True, _threading_local=True, Event=False, logging=Tru ...@@ -389,7 +388,8 @@ def patch_thread(threading=True, _threading_local=True, Event=False, logging=Tru
del threading._active[oldid] del threading._active[oldid]
else: else:
_queue_warning("Monkey-patching not on the main thread; " _queue_warning("Monkey-patching not on the main thread; "
"threading.main_thread().join() will hang from a greenlet") "threading.main_thread().join() will hang from a greenlet",
_warnings)
def patch_socket(dns=True, aggressive=True): def patch_socket(dns=True, aggressive=True):
...@@ -519,19 +519,30 @@ def patch_signal(): ...@@ -519,19 +519,30 @@ def patch_signal():
""" """
patch_module("signal") patch_module("signal")
def _check_repatching(**module_settings): def _check_repatching(**module_settings):
if saved.get('_gevent_saved_patch_all', module_settings) != module_settings: _warnings = []
key = '_gevent_saved_patch_all'
if saved.get(key, module_settings) != module_settings:
_queue_warning("Patching more than once will result in the union of all True" _queue_warning("Patching more than once will result in the union of all True"
" parameters being patched") " parameters being patched",
_warnings)
first_time = key not in saved
saved[key] = module_settings
return _warnings, first_time
saved['_gevent_saved_patch_all'] = module_settings
def patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=True, ssl=True, httplib=False, def patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=True, ssl=True, httplib=False,
subprocess=True, sys=False, aggressive=True, Event=False, subprocess=True, sys=False, aggressive=True, Event=False,
builtins=True, signal=True): builtins=True, signal=True):
"""Do all of the default monkey patching (calls every other applicable function in this module).""" """Do all of the default monkey patching (calls every other applicable function in this module)."""
# Check to see if they're changing the patched list # Check to see if they're changing the patched list
_check_repatching(**locals()) _warnings, first_time = _check_repatching(**locals())
if not _warnings and not first_time:
# Nothing to do, identical args to what we just
# did
return
# order is important # order is important
if os: if os:
...@@ -561,10 +572,11 @@ def patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=Tru ...@@ -561,10 +572,11 @@ def patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=Tru
_queue_warning('Patching signal but not os will result in SIGCHLD handlers' _queue_warning('Patching signal but not os will result in SIGCHLD handlers'
' installed after this not being called and os.waitpid may not' ' installed after this not being called and os.waitpid may not'
' function correctly if gevent.subprocess is used. This may raise an' ' function correctly if gevent.subprocess is used. This may raise an'
' error in the future.') ' error in the future.',
_warnings)
patch_signal() patch_signal()
_process_warnings() _process_warnings(_warnings)
def main(): def main():
......
...@@ -54,17 +54,16 @@ with warnings.catch_warnings(record=True) as issued_warnings: ...@@ -54,17 +54,16 @@ with warnings.catch_warnings(record=True) as issued_warnings:
assert 'more than once' in str(issued_warnings[0].message), issued_warnings[0] assert 'more than once' in str(issued_warnings[0].message), issued_warnings[0]
# Patching with the exact same argument doesn't issue a second warning. # Patching with the exact same argument doesn't issue a second warning.
# (just repeats the signal warning) # in fact, it doesn't do anything
del issued_warnings[:] del issued_warnings[:]
monkey.patch_all(os=False) monkey.patch_all(os=False)
orig_saved['_gevent_saved_patch_all'] = monkey.saved['_gevent_saved_patch_all'] orig_saved['_gevent_saved_patch_all'] = monkey.saved['_gevent_saved_patch_all']
assert len(issued_warnings) == 1, len(issued_warnings) assert len(issued_warnings) == 0, len(issued_warnings)
assert 'SIGCHLD' in str(issued_warnings[-1].message), issued_warnings[-1]
# Make sure that re-patching did not change the monkey.saved # Make sure that re-patching did not change the monkey.saved
# attribute, overwriting the original functions # attribute, overwriting the original functions.
assert orig_saved == monkey.saved assert orig_saved == monkey.saved, (orig_saved, monkey.saved)
# Make sure some problematic attributes stayed correct. # Make sure some problematic attributes stayed correct.
# NOTE: This was only a problem if threading was not previously imported. # NOTE: This was only a problem if threading was not previously imported.
......
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