bpo-31370: Remove support for threads-less builds (#3385)
* Remove Setup.config * Always define WITH_THREAD for compatibility.
This commit is contained in:
parent
1f06a680de
commit
a6a4dc816d
|
@ -344,6 +344,9 @@ Build and C API Changes
|
||||||
download a copy of 32-bit Python for this purpose. (Contributed by Zachary
|
download a copy of 32-bit Python for this purpose. (Contributed by Zachary
|
||||||
Ware in :issue:`30450`.)
|
Ware in :issue:`30450`.)
|
||||||
|
|
||||||
|
* Support for building ``--without-threads`` is removed.
|
||||||
|
(Contributed by Antoine Pitrou in :issue:`31370`.).
|
||||||
|
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
==========
|
==========
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#error "Python's source code assumes C's unsigned char is an 8-bit type."
|
#error "Python's source code assumes C's unsigned char is an 8-bit type."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
|
#if defined(__sgi) && !defined(_SGI_MP_SOURCE)
|
||||||
#define _SGI_MP_SOURCE
|
#define _SGI_MP_SOURCE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -183,8 +183,6 @@ PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(struct _frame *f, int exc);
|
||||||
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
|
PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void);
|
||||||
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
|
PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *);
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
|
|
||||||
PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
|
PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
|
||||||
PyAPI_FUNC(void) PyEval_InitThreads(void);
|
PyAPI_FUNC(void) PyEval_InitThreads(void);
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
|
@ -213,15 +211,6 @@ PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
|
||||||
#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
|
#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !WITH_THREAD */
|
|
||||||
|
|
||||||
#define Py_BEGIN_ALLOW_THREADS {
|
|
||||||
#define Py_BLOCK_THREADS
|
|
||||||
#define Py_UNBLOCK_THREADS
|
|
||||||
#define Py_END_ALLOW_THREADS }
|
|
||||||
|
|
||||||
#endif /* !WITH_THREAD */
|
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
|
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
|
||||||
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
|
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
|
||||||
|
|
|
@ -100,13 +100,8 @@ PyAPI_FUNC(int) PyImport_ImportFrozenModule(
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyAPI_FUNC(void) _PyImport_AcquireLock(void);
|
PyAPI_FUNC(void) _PyImport_AcquireLock(void);
|
||||||
PyAPI_FUNC(int) _PyImport_ReleaseLock(void);
|
PyAPI_FUNC(int) _PyImport_ReleaseLock(void);
|
||||||
#else
|
|
||||||
#define _PyImport_AcquireLock()
|
|
||||||
#define _PyImport_ReleaseLock() 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyAPI_FUNC(void) _PyImport_ReInitLock(void);
|
PyAPI_FUNC(void) _PyImport_ReInitLock(void);
|
||||||
|
|
||||||
|
|
|
@ -797,4 +797,12 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler;
|
||||||
#include <android/api-level.h>
|
#include <android/api-level.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This macro used to tell whether Python was built with multithreading
|
||||||
|
* enabled. Now multithreading is always enabled, but keep the macro
|
||||||
|
* for compatibility.
|
||||||
|
*/
|
||||||
|
#ifndef WITH_THREAD
|
||||||
|
#define WITH_THREAD
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* Py_PYPORT_H */
|
#endif /* Py_PYPORT_H */
|
||||||
|
|
|
@ -218,12 +218,10 @@ PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *);
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
|
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
|
||||||
#endif /* !Py_LIMITED_API */
|
#endif /* !Py_LIMITED_API */
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
|
PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
|
||||||
#ifndef Py_LIMITED_API
|
#ifndef Py_LIMITED_API
|
||||||
PyAPI_FUNC(void) _PyGILState_Reinit(void);
|
PyAPI_FUNC(void) _PyGILState_Reinit(void);
|
||||||
#endif /* !Py_LIMITED_API */
|
#endif /* !Py_LIMITED_API */
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Return the current thread state. The global interpreter lock must be held.
|
/* Return the current thread state. The global interpreter lock must be held.
|
||||||
* When the current thread state is NULL, this issues a fatal error (so that
|
* When the current thread state is NULL, this issues a fatal error (so that
|
||||||
|
@ -257,7 +255,6 @@ typedef
|
||||||
enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
|
enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
|
||||||
PyGILState_STATE;
|
PyGILState_STATE;
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
|
|
||||||
/* Ensure that the current thread is ready to call the Python
|
/* Ensure that the current thread is ready to call the Python
|
||||||
C API, regardless of the current state of Python, or of its
|
C API, regardless of the current state of Python, or of its
|
||||||
|
@ -319,7 +316,6 @@ PyAPI_FUNC(int) PyGILState_Check(void);
|
||||||
PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
|
PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* #ifdef WITH_THREAD */
|
|
||||||
|
|
||||||
/* The implementation of sys._current_frames() Returns a dict mapping
|
/* The implementation of sys._current_frames() Returns a dict mapping
|
||||||
thread id to that thread's current frame.
|
thread id to that thread's current frame.
|
||||||
|
|
|
@ -1,163 +0,0 @@
|
||||||
"""Drop-in replacement for the thread module.
|
|
||||||
|
|
||||||
Meant to be used as a brain-dead substitute so that threaded code does
|
|
||||||
not need to be rewritten for when the thread module is not present.
|
|
||||||
|
|
||||||
Suggested usage is::
|
|
||||||
|
|
||||||
try:
|
|
||||||
import _thread
|
|
||||||
except ImportError:
|
|
||||||
import _dummy_thread as _thread
|
|
||||||
|
|
||||||
"""
|
|
||||||
# Exports only things specified by thread documentation;
|
|
||||||
# skipping obsolete synonyms allocate(), start_new(), exit_thread().
|
|
||||||
__all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock',
|
|
||||||
'interrupt_main', 'LockType']
|
|
||||||
|
|
||||||
# A dummy value
|
|
||||||
TIMEOUT_MAX = 2**31
|
|
||||||
|
|
||||||
# NOTE: this module can be imported early in the extension building process,
|
|
||||||
# and so top level imports of other modules should be avoided. Instead, all
|
|
||||||
# imports are done when needed on a function-by-function basis. Since threads
|
|
||||||
# are disabled, the import lock should not be an issue anyway (??).
|
|
||||||
|
|
||||||
error = RuntimeError
|
|
||||||
|
|
||||||
def start_new_thread(function, args, kwargs={}):
|
|
||||||
"""Dummy implementation of _thread.start_new_thread().
|
|
||||||
|
|
||||||
Compatibility is maintained by making sure that ``args`` is a
|
|
||||||
tuple and ``kwargs`` is a dictionary. If an exception is raised
|
|
||||||
and it is SystemExit (which can be done by _thread.exit()) it is
|
|
||||||
caught and nothing is done; all other exceptions are printed out
|
|
||||||
by using traceback.print_exc().
|
|
||||||
|
|
||||||
If the executed function calls interrupt_main the KeyboardInterrupt will be
|
|
||||||
raised when the function returns.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if type(args) != type(tuple()):
|
|
||||||
raise TypeError("2nd arg must be a tuple")
|
|
||||||
if type(kwargs) != type(dict()):
|
|
||||||
raise TypeError("3rd arg must be a dict")
|
|
||||||
global _main
|
|
||||||
_main = False
|
|
||||||
try:
|
|
||||||
function(*args, **kwargs)
|
|
||||||
except SystemExit:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
_main = True
|
|
||||||
global _interrupt
|
|
||||||
if _interrupt:
|
|
||||||
_interrupt = False
|
|
||||||
raise KeyboardInterrupt
|
|
||||||
|
|
||||||
def exit():
|
|
||||||
"""Dummy implementation of _thread.exit()."""
|
|
||||||
raise SystemExit
|
|
||||||
|
|
||||||
def get_ident():
|
|
||||||
"""Dummy implementation of _thread.get_ident().
|
|
||||||
|
|
||||||
Since this module should only be used when _threadmodule is not
|
|
||||||
available, it is safe to assume that the current process is the
|
|
||||||
only thread. Thus a constant can be safely returned.
|
|
||||||
"""
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def allocate_lock():
|
|
||||||
"""Dummy implementation of _thread.allocate_lock()."""
|
|
||||||
return LockType()
|
|
||||||
|
|
||||||
def stack_size(size=None):
|
|
||||||
"""Dummy implementation of _thread.stack_size()."""
|
|
||||||
if size is not None:
|
|
||||||
raise error("setting thread stack size not supported")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def _set_sentinel():
|
|
||||||
"""Dummy implementation of _thread._set_sentinel()."""
|
|
||||||
return LockType()
|
|
||||||
|
|
||||||
class LockType(object):
|
|
||||||
"""Class implementing dummy implementation of _thread.LockType.
|
|
||||||
|
|
||||||
Compatibility is maintained by maintaining self.locked_status
|
|
||||||
which is a boolean that stores the state of the lock. Pickling of
|
|
||||||
the lock, though, should not be done since if the _thread module is
|
|
||||||
then used with an unpickled ``lock()`` from here problems could
|
|
||||||
occur from this class not having atomic methods.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.locked_status = False
|
|
||||||
|
|
||||||
def acquire(self, waitflag=None, timeout=-1):
|
|
||||||
"""Dummy implementation of acquire().
|
|
||||||
|
|
||||||
For blocking calls, self.locked_status is automatically set to
|
|
||||||
True and returned appropriately based on value of
|
|
||||||
``waitflag``. If it is non-blocking, then the value is
|
|
||||||
actually checked and not set if it is already acquired. This
|
|
||||||
is all done so that threading.Condition's assert statements
|
|
||||||
aren't triggered and throw a little fit.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if waitflag is None or waitflag:
|
|
||||||
self.locked_status = True
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
if not self.locked_status:
|
|
||||||
self.locked_status = True
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
if timeout > 0:
|
|
||||||
import time
|
|
||||||
time.sleep(timeout)
|
|
||||||
return False
|
|
||||||
|
|
||||||
__enter__ = acquire
|
|
||||||
|
|
||||||
def __exit__(self, typ, val, tb):
|
|
||||||
self.release()
|
|
||||||
|
|
||||||
def release(self):
|
|
||||||
"""Release the dummy lock."""
|
|
||||||
# XXX Perhaps shouldn't actually bother to test? Could lead
|
|
||||||
# to problems for complex, threaded code.
|
|
||||||
if not self.locked_status:
|
|
||||||
raise error
|
|
||||||
self.locked_status = False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def locked(self):
|
|
||||||
return self.locked_status
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<%s %s.%s object at %s>" % (
|
|
||||||
"locked" if self.locked_status else "unlocked",
|
|
||||||
self.__class__.__module__,
|
|
||||||
self.__class__.__qualname__,
|
|
||||||
hex(id(self))
|
|
||||||
)
|
|
||||||
|
|
||||||
# Used to signal that interrupt_main was called in a "thread"
|
|
||||||
_interrupt = False
|
|
||||||
# True when not executing in a "thread"
|
|
||||||
_main = True
|
|
||||||
|
|
||||||
def interrupt_main():
|
|
||||||
"""Set _interrupt flag to True to have start_new_thread raise
|
|
||||||
KeyboardInterrupt upon exiting."""
|
|
||||||
if _main:
|
|
||||||
raise KeyboardInterrupt
|
|
||||||
else:
|
|
||||||
global _interrupt
|
|
||||||
_interrupt = True
|
|
|
@ -436,75 +436,34 @@ _rounding_modes = (ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN, ROUND_CEILING,
|
||||||
# work for older Pythons. If threads are not part of the build, create a
|
# work for older Pythons. If threads are not part of the build, create a
|
||||||
# mock threading object with threading.local() returning the module namespace.
|
# mock threading object with threading.local() returning the module namespace.
|
||||||
|
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
# Python was compiled without threads; create a mock object instead
|
|
||||||
class MockThreading(object):
|
|
||||||
def local(self, sys=sys):
|
|
||||||
return sys.modules[__xname__]
|
|
||||||
threading = MockThreading()
|
|
||||||
del MockThreading
|
|
||||||
|
|
||||||
try:
|
local = threading.local()
|
||||||
threading.local
|
if hasattr(local, '__decimal_context__'):
|
||||||
|
del local.__decimal_context__
|
||||||
|
|
||||||
except AttributeError:
|
def getcontext(_local=local):
|
||||||
|
"""Returns this thread's context.
|
||||||
|
|
||||||
# To fix reloading, force it to create a new context
|
If this thread does not yet have a context, returns
|
||||||
# Old contexts have different exceptions in their dicts, making problems.
|
a new context and sets this thread's context.
|
||||||
if hasattr(threading.current_thread(), '__decimal_context__'):
|
New contexts are copies of DefaultContext.
|
||||||
del threading.current_thread().__decimal_context__
|
"""
|
||||||
|
try:
|
||||||
def setcontext(context):
|
return _local.__decimal_context__
|
||||||
"""Set this thread's context to context."""
|
except AttributeError:
|
||||||
if context in (DefaultContext, BasicContext, ExtendedContext):
|
context = Context()
|
||||||
context = context.copy()
|
|
||||||
context.clear_flags()
|
|
||||||
threading.current_thread().__decimal_context__ = context
|
|
||||||
|
|
||||||
def getcontext():
|
|
||||||
"""Returns this thread's context.
|
|
||||||
|
|
||||||
If this thread does not yet have a context, returns
|
|
||||||
a new context and sets this thread's context.
|
|
||||||
New contexts are copies of DefaultContext.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return threading.current_thread().__decimal_context__
|
|
||||||
except AttributeError:
|
|
||||||
context = Context()
|
|
||||||
threading.current_thread().__decimal_context__ = context
|
|
||||||
return context
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
local = threading.local()
|
|
||||||
if hasattr(local, '__decimal_context__'):
|
|
||||||
del local.__decimal_context__
|
|
||||||
|
|
||||||
def getcontext(_local=local):
|
|
||||||
"""Returns this thread's context.
|
|
||||||
|
|
||||||
If this thread does not yet have a context, returns
|
|
||||||
a new context and sets this thread's context.
|
|
||||||
New contexts are copies of DefaultContext.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return _local.__decimal_context__
|
|
||||||
except AttributeError:
|
|
||||||
context = Context()
|
|
||||||
_local.__decimal_context__ = context
|
|
||||||
return context
|
|
||||||
|
|
||||||
def setcontext(context, _local=local):
|
|
||||||
"""Set this thread's context to context."""
|
|
||||||
if context in (DefaultContext, BasicContext, ExtendedContext):
|
|
||||||
context = context.copy()
|
|
||||||
context.clear_flags()
|
|
||||||
_local.__decimal_context__ = context
|
_local.__decimal_context__ = context
|
||||||
|
return context
|
||||||
|
|
||||||
del threading, local # Don't contaminate the namespace
|
def setcontext(context, _local=local):
|
||||||
|
"""Set this thread's context to context."""
|
||||||
|
if context in (DefaultContext, BasicContext, ExtendedContext):
|
||||||
|
context = context.copy()
|
||||||
|
context.clear_flags()
|
||||||
|
_local.__decimal_context__ = context
|
||||||
|
|
||||||
|
del threading, local # Don't contaminate the namespace
|
||||||
|
|
||||||
def localcontext(ctx=None):
|
def localcontext(ctx=None):
|
||||||
"""Return a context manager for a copy of the supplied context
|
"""Return a context manager for a copy of the supplied context
|
||||||
|
|
|
@ -9,10 +9,7 @@ import errno
|
||||||
import stat
|
import stat
|
||||||
import sys
|
import sys
|
||||||
# Import _thread instead of threading to reduce startup cost
|
# Import _thread instead of threading to reduce startup cost
|
||||||
try:
|
from _thread import allocate_lock as Lock
|
||||||
from _thread import allocate_lock as Lock
|
|
||||||
except ImportError:
|
|
||||||
from _dummy_thread import allocate_lock as Lock
|
|
||||||
if sys.platform in {'win32', 'cygwin'}:
|
if sys.platform in {'win32', 'cygwin'}:
|
||||||
from msvcrt import setmode as _setmode
|
from msvcrt import setmode as _setmode
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -19,10 +19,7 @@ from re import escape as re_escape
|
||||||
from datetime import (date as datetime_date,
|
from datetime import (date as datetime_date,
|
||||||
timedelta as datetime_timedelta,
|
timedelta as datetime_timedelta,
|
||||||
timezone as datetime_timezone)
|
timezone as datetime_timezone)
|
||||||
try:
|
from _thread import allocate_lock as _thread_allocate_lock
|
||||||
from _thread import allocate_lock as _thread_allocate_lock
|
|
||||||
except ImportError:
|
|
||||||
from _dummy_thread import allocate_lock as _thread_allocate_lock
|
|
||||||
|
|
||||||
__all__ = []
|
__all__ = []
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,7 @@ import io
|
||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
import _compression
|
import _compression
|
||||||
|
from threading import RLock
|
||||||
try:
|
|
||||||
from threading import RLock
|
|
||||||
except ImportError:
|
|
||||||
from dummy_threading import RLock
|
|
||||||
|
|
||||||
from _bz2 import BZ2Compressor, BZ2Decompressor
|
from _bz2 import BZ2Compressor, BZ2Decompressor
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import unittest, os, errno
|
import unittest, os, errno
|
||||||
|
import threading
|
||||||
|
|
||||||
from ctypes import *
|
from ctypes import *
|
||||||
from ctypes.util import find_library
|
from ctypes.util import find_library
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
class Test(unittest.TestCase):
|
class Test(unittest.TestCase):
|
||||||
def test_open(self):
|
def test_open(self):
|
||||||
|
@ -25,26 +23,25 @@ class Test(unittest.TestCase):
|
||||||
self.assertEqual(set_errno(32), errno.ENOENT)
|
self.assertEqual(set_errno(32), errno.ENOENT)
|
||||||
self.assertEqual(get_errno(), 32)
|
self.assertEqual(get_errno(), 32)
|
||||||
|
|
||||||
if threading:
|
def _worker():
|
||||||
def _worker():
|
|
||||||
set_errno(0)
|
|
||||||
|
|
||||||
libc = CDLL(libc_name, use_errno=False)
|
|
||||||
if os.name == "nt":
|
|
||||||
libc_open = libc._open
|
|
||||||
else:
|
|
||||||
libc_open = libc.open
|
|
||||||
libc_open.argtypes = c_char_p, c_int
|
|
||||||
self.assertEqual(libc_open(b"", 0), -1)
|
|
||||||
self.assertEqual(get_errno(), 0)
|
|
||||||
|
|
||||||
t = threading.Thread(target=_worker)
|
|
||||||
t.start()
|
|
||||||
t.join()
|
|
||||||
|
|
||||||
self.assertEqual(get_errno(), 32)
|
|
||||||
set_errno(0)
|
set_errno(0)
|
||||||
|
|
||||||
|
libc = CDLL(libc_name, use_errno=False)
|
||||||
|
if os.name == "nt":
|
||||||
|
libc_open = libc._open
|
||||||
|
else:
|
||||||
|
libc_open = libc.open
|
||||||
|
libc_open.argtypes = c_char_p, c_int
|
||||||
|
self.assertEqual(libc_open(b"", 0), -1)
|
||||||
|
self.assertEqual(get_errno(), 0)
|
||||||
|
|
||||||
|
t = threading.Thread(target=_worker)
|
||||||
|
t.start()
|
||||||
|
t.join()
|
||||||
|
|
||||||
|
self.assertEqual(get_errno(), 32)
|
||||||
|
set_errno(0)
|
||||||
|
|
||||||
@unittest.skipUnless(os.name == "nt", 'Test specific to Windows')
|
@unittest.skipUnless(os.name == "nt", 'Test specific to Windows')
|
||||||
def test_GetLastError(self):
|
def test_GetLastError(self):
|
||||||
dll = WinDLL("kernel32", use_last_error=True)
|
dll = WinDLL("kernel32", use_last_error=True)
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
"""Faux ``threading`` version using ``dummy_thread`` instead of ``thread``.
|
|
||||||
|
|
||||||
The module ``_dummy_threading`` is added to ``sys.modules`` in order
|
|
||||||
to not have ``threading`` considered imported. Had ``threading`` been
|
|
||||||
directly imported it would have made all subsequent imports succeed
|
|
||||||
regardless of whether ``_thread`` was available which is not desired.
|
|
||||||
|
|
||||||
"""
|
|
||||||
from sys import modules as sys_modules
|
|
||||||
|
|
||||||
import _dummy_thread
|
|
||||||
|
|
||||||
# Declaring now so as to not have to nest ``try``s to get proper clean-up.
|
|
||||||
holding_thread = False
|
|
||||||
holding_threading = False
|
|
||||||
holding__threading_local = False
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Could have checked if ``_thread`` was not in sys.modules and gone
|
|
||||||
# a different route, but decided to mirror technique used with
|
|
||||||
# ``threading`` below.
|
|
||||||
if '_thread' in sys_modules:
|
|
||||||
held_thread = sys_modules['_thread']
|
|
||||||
holding_thread = True
|
|
||||||
# Must have some module named ``_thread`` that implements its API
|
|
||||||
# in order to initially import ``threading``.
|
|
||||||
sys_modules['_thread'] = sys_modules['_dummy_thread']
|
|
||||||
|
|
||||||
if 'threading' in sys_modules:
|
|
||||||
# If ``threading`` is already imported, might as well prevent
|
|
||||||
# trying to import it more than needed by saving it if it is
|
|
||||||
# already imported before deleting it.
|
|
||||||
held_threading = sys_modules['threading']
|
|
||||||
holding_threading = True
|
|
||||||
del sys_modules['threading']
|
|
||||||
|
|
||||||
if '_threading_local' in sys_modules:
|
|
||||||
# If ``_threading_local`` is already imported, might as well prevent
|
|
||||||
# trying to import it more than needed by saving it if it is
|
|
||||||
# already imported before deleting it.
|
|
||||||
held__threading_local = sys_modules['_threading_local']
|
|
||||||
holding__threading_local = True
|
|
||||||
del sys_modules['_threading_local']
|
|
||||||
|
|
||||||
import threading
|
|
||||||
# Need a copy of the code kept somewhere...
|
|
||||||
sys_modules['_dummy_threading'] = sys_modules['threading']
|
|
||||||
del sys_modules['threading']
|
|
||||||
sys_modules['_dummy__threading_local'] = sys_modules['_threading_local']
|
|
||||||
del sys_modules['_threading_local']
|
|
||||||
from _dummy_threading import *
|
|
||||||
from _dummy_threading import __all__
|
|
||||||
|
|
||||||
finally:
|
|
||||||
# Put back ``threading`` if we overwrote earlier
|
|
||||||
|
|
||||||
if holding_threading:
|
|
||||||
sys_modules['threading'] = held_threading
|
|
||||||
del held_threading
|
|
||||||
del holding_threading
|
|
||||||
|
|
||||||
# Put back ``_threading_local`` if we overwrote earlier
|
|
||||||
|
|
||||||
if holding__threading_local:
|
|
||||||
sys_modules['_threading_local'] = held__threading_local
|
|
||||||
del held__threading_local
|
|
||||||
del holding__threading_local
|
|
||||||
|
|
||||||
# Put back ``thread`` if we overwrote, else del the entry we made
|
|
||||||
if holding_thread:
|
|
||||||
sys_modules['_thread'] = held_thread
|
|
||||||
del held_thread
|
|
||||||
else:
|
|
||||||
del sys_modules['_thread']
|
|
||||||
del holding_thread
|
|
||||||
|
|
||||||
del _dummy_thread
|
|
||||||
del sys_modules
|
|
|
@ -22,13 +22,7 @@ from collections import namedtuple
|
||||||
from types import MappingProxyType
|
from types import MappingProxyType
|
||||||
from weakref import WeakKeyDictionary
|
from weakref import WeakKeyDictionary
|
||||||
from reprlib import recursive_repr
|
from reprlib import recursive_repr
|
||||||
try:
|
from _thread import RLock
|
||||||
from _thread import RLock
|
|
||||||
except ImportError:
|
|
||||||
class RLock:
|
|
||||||
'Dummy reentrant lock for builds without threads'
|
|
||||||
def __enter__(self): pass
|
|
||||||
def __exit__(self, exctype, excinst, exctb): pass
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
|
@ -33,10 +33,7 @@ import datetime
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
import urllib.parse, urllib.request
|
import urllib.parse, urllib.request
|
||||||
try:
|
import threading as _threading
|
||||||
import threading as _threading
|
|
||||||
except ImportError:
|
|
||||||
import dummy_threading as _threading
|
|
||||||
import http.client # only for the default HTTP port
|
import http.client # only for the default HTTP port
|
||||||
from calendar import timegm
|
from calendar import timegm
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,7 @@ __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
|
||||||
'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory',
|
'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory',
|
||||||
'lastResort', 'raiseExceptions']
|
'lastResort', 'raiseExceptions']
|
||||||
|
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError: #pragma: no cover
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
|
__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
|
||||||
__status__ = "production"
|
__status__ = "production"
|
||||||
|
@ -210,11 +207,7 @@ def _checkLevel(level):
|
||||||
#the lock would already have been acquired - so we need an RLock.
|
#the lock would already have been acquired - so we need an RLock.
|
||||||
#The same argument applies to Loggers and Manager.loggerDict.
|
#The same argument applies to Loggers and Manager.loggerDict.
|
||||||
#
|
#
|
||||||
if threading:
|
_lock = threading.RLock()
|
||||||
_lock = threading.RLock()
|
|
||||||
else: #pragma: no cover
|
|
||||||
_lock = None
|
|
||||||
|
|
||||||
|
|
||||||
def _acquireLock():
|
def _acquireLock():
|
||||||
"""
|
"""
|
||||||
|
@ -295,7 +288,7 @@ class LogRecord(object):
|
||||||
self.created = ct
|
self.created = ct
|
||||||
self.msecs = (ct - int(ct)) * 1000
|
self.msecs = (ct - int(ct)) * 1000
|
||||||
self.relativeCreated = (self.created - _startTime) * 1000
|
self.relativeCreated = (self.created - _startTime) * 1000
|
||||||
if logThreads and threading:
|
if logThreads:
|
||||||
self.thread = threading.get_ident()
|
self.thread = threading.get_ident()
|
||||||
self.threadName = threading.current_thread().name
|
self.threadName = threading.current_thread().name
|
||||||
else: # pragma: no cover
|
else: # pragma: no cover
|
||||||
|
@ -799,10 +792,7 @@ class Handler(Filterer):
|
||||||
"""
|
"""
|
||||||
Acquire a thread lock for serializing access to the underlying I/O.
|
Acquire a thread lock for serializing access to the underlying I/O.
|
||||||
"""
|
"""
|
||||||
if threading:
|
self.lock = threading.RLock()
|
||||||
self.lock = threading.RLock()
|
|
||||||
else: #pragma: no cover
|
|
||||||
self.lock = None
|
|
||||||
|
|
||||||
def acquire(self):
|
def acquire(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -31,14 +31,9 @@ import logging.handlers
|
||||||
import re
|
import re
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
try:
|
|
||||||
import _thread as thread
|
|
||||||
import threading
|
|
||||||
except ImportError: #pragma: no cover
|
|
||||||
thread = None
|
|
||||||
|
|
||||||
from socketserver import ThreadingTCPServer, StreamRequestHandler
|
from socketserver import ThreadingTCPServer, StreamRequestHandler
|
||||||
|
|
||||||
|
|
||||||
|
@ -816,8 +811,6 @@ def listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None):
|
||||||
normal. Note that you can return transformed bytes, e.g. by decrypting
|
normal. Note that you can return transformed bytes, e.g. by decrypting
|
||||||
the bytes passed in.
|
the bytes passed in.
|
||||||
"""
|
"""
|
||||||
if not thread: #pragma: no cover
|
|
||||||
raise NotImplementedError("listen() needs threading to work")
|
|
||||||
|
|
||||||
class ConfigStreamHandler(StreamRequestHandler):
|
class ConfigStreamHandler(StreamRequestHandler):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -26,10 +26,7 @@ To use, simply 'import logging.handlers' and log away!
|
||||||
import logging, socket, os, pickle, struct, time, re
|
import logging, socket, os, pickle, struct, time, re
|
||||||
from stat import ST_DEV, ST_INO, ST_MTIME
|
from stat import ST_DEV, ST_INO, ST_MTIME
|
||||||
import queue
|
import queue
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError: #pragma: no cover
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Some constants...
|
# Some constants...
|
||||||
|
@ -1395,110 +1392,110 @@ class QueueHandler(logging.Handler):
|
||||||
except Exception:
|
except Exception:
|
||||||
self.handleError(record)
|
self.handleError(record)
|
||||||
|
|
||||||
if threading:
|
|
||||||
class QueueListener(object):
|
class QueueListener(object):
|
||||||
|
"""
|
||||||
|
This class implements an internal threaded listener which watches for
|
||||||
|
LogRecords being added to a queue, removes them and passes them to a
|
||||||
|
list of handlers for processing.
|
||||||
|
"""
|
||||||
|
_sentinel = None
|
||||||
|
|
||||||
|
def __init__(self, queue, *handlers, respect_handler_level=False):
|
||||||
"""
|
"""
|
||||||
This class implements an internal threaded listener which watches for
|
Initialise an instance with the specified queue and
|
||||||
LogRecords being added to a queue, removes them and passes them to a
|
handlers.
|
||||||
list of handlers for processing.
|
|
||||||
"""
|
"""
|
||||||
_sentinel = None
|
self.queue = queue
|
||||||
|
self.handlers = handlers
|
||||||
|
self._thread = None
|
||||||
|
self.respect_handler_level = respect_handler_level
|
||||||
|
|
||||||
def __init__(self, queue, *handlers, respect_handler_level=False):
|
def dequeue(self, block):
|
||||||
"""
|
"""
|
||||||
Initialise an instance with the specified queue and
|
Dequeue a record and return it, optionally blocking.
|
||||||
handlers.
|
|
||||||
"""
|
|
||||||
self.queue = queue
|
|
||||||
self.handlers = handlers
|
|
||||||
self._thread = None
|
|
||||||
self.respect_handler_level = respect_handler_level
|
|
||||||
|
|
||||||
def dequeue(self, block):
|
The base implementation uses get. You may want to override this method
|
||||||
"""
|
if you want to use timeouts or work with custom queue implementations.
|
||||||
Dequeue a record and return it, optionally blocking.
|
"""
|
||||||
|
return self.queue.get(block)
|
||||||
|
|
||||||
The base implementation uses get. You may want to override this method
|
def start(self):
|
||||||
if you want to use timeouts or work with custom queue implementations.
|
"""
|
||||||
"""
|
Start the listener.
|
||||||
return self.queue.get(block)
|
|
||||||
|
|
||||||
def start(self):
|
This starts up a background thread to monitor the queue for
|
||||||
"""
|
LogRecords to process.
|
||||||
Start the listener.
|
"""
|
||||||
|
self._thread = t = threading.Thread(target=self._monitor)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
|
||||||
This starts up a background thread to monitor the queue for
|
def prepare(self , record):
|
||||||
LogRecords to process.
|
"""
|
||||||
"""
|
Prepare a record for handling.
|
||||||
self._thread = t = threading.Thread(target=self._monitor)
|
|
||||||
t.daemon = True
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
def prepare(self , record):
|
This method just returns the passed-in record. You may want to
|
||||||
"""
|
override this method if you need to do any custom marshalling or
|
||||||
Prepare a record for handling.
|
manipulation of the record before passing it to the handlers.
|
||||||
|
"""
|
||||||
|
return record
|
||||||
|
|
||||||
This method just returns the passed-in record. You may want to
|
def handle(self, record):
|
||||||
override this method if you need to do any custom marshalling or
|
"""
|
||||||
manipulation of the record before passing it to the handlers.
|
Handle a record.
|
||||||
"""
|
|
||||||
return record
|
|
||||||
|
|
||||||
def handle(self, record):
|
This just loops through the handlers offering them the record
|
||||||
"""
|
to handle.
|
||||||
Handle a record.
|
"""
|
||||||
|
record = self.prepare(record)
|
||||||
|
for handler in self.handlers:
|
||||||
|
if not self.respect_handler_level:
|
||||||
|
process = True
|
||||||
|
else:
|
||||||
|
process = record.levelno >= handler.level
|
||||||
|
if process:
|
||||||
|
handler.handle(record)
|
||||||
|
|
||||||
This just loops through the handlers offering them the record
|
def _monitor(self):
|
||||||
to handle.
|
"""
|
||||||
"""
|
Monitor the queue for records, and ask the handler
|
||||||
record = self.prepare(record)
|
to deal with them.
|
||||||
for handler in self.handlers:
|
|
||||||
if not self.respect_handler_level:
|
|
||||||
process = True
|
|
||||||
else:
|
|
||||||
process = record.levelno >= handler.level
|
|
||||||
if process:
|
|
||||||
handler.handle(record)
|
|
||||||
|
|
||||||
def _monitor(self):
|
This method runs on a separate, internal thread.
|
||||||
"""
|
The thread will terminate if it sees a sentinel object in the queue.
|
||||||
Monitor the queue for records, and ask the handler
|
"""
|
||||||
to deal with them.
|
q = self.queue
|
||||||
|
has_task_done = hasattr(q, 'task_done')
|
||||||
This method runs on a separate, internal thread.
|
while True:
|
||||||
The thread will terminate if it sees a sentinel object in the queue.
|
try:
|
||||||
"""
|
record = self.dequeue(True)
|
||||||
q = self.queue
|
if record is self._sentinel:
|
||||||
has_task_done = hasattr(q, 'task_done')
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
record = self.dequeue(True)
|
|
||||||
if record is self._sentinel:
|
|
||||||
break
|
|
||||||
self.handle(record)
|
|
||||||
if has_task_done:
|
|
||||||
q.task_done()
|
|
||||||
except queue.Empty:
|
|
||||||
break
|
break
|
||||||
|
self.handle(record)
|
||||||
|
if has_task_done:
|
||||||
|
q.task_done()
|
||||||
|
except queue.Empty:
|
||||||
|
break
|
||||||
|
|
||||||
def enqueue_sentinel(self):
|
def enqueue_sentinel(self):
|
||||||
"""
|
"""
|
||||||
This is used to enqueue the sentinel record.
|
This is used to enqueue the sentinel record.
|
||||||
|
|
||||||
The base implementation uses put_nowait. You may want to override this
|
The base implementation uses put_nowait. You may want to override this
|
||||||
method if you want to use timeouts or work with custom queue
|
method if you want to use timeouts or work with custom queue
|
||||||
implementations.
|
implementations.
|
||||||
"""
|
"""
|
||||||
self.queue.put_nowait(self._sentinel)
|
self.queue.put_nowait(self._sentinel)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Stop the listener.
|
Stop the listener.
|
||||||
|
|
||||||
This asks the thread to terminate, and then waits for it to do so.
|
This asks the thread to terminate, and then waits for it to do so.
|
||||||
Note that if you don't call this before your application exits, there
|
Note that if you don't call this before your application exits, there
|
||||||
may be some records still left on the queue, which won't be processed.
|
may be some records still left on the queue, which won't be processed.
|
||||||
"""
|
"""
|
||||||
self.enqueue_sentinel()
|
self.enqueue_sentinel()
|
||||||
self._thread.join()
|
self._thread.join()
|
||||||
self._thread = None
|
self._thread = None
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
'''A multi-producer, multi-consumer queue.'''
|
'''A multi-producer, multi-consumer queue.'''
|
||||||
|
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
import dummy_threading as threading
|
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from heapq import heappush, heappop
|
from heapq import heappush, heappop
|
||||||
from time import monotonic as time
|
from time import monotonic as time
|
||||||
|
|
|
@ -4,10 +4,7 @@ __all__ = ["Repr", "repr", "recursive_repr"]
|
||||||
|
|
||||||
import builtins
|
import builtins
|
||||||
from itertools import islice
|
from itertools import islice
|
||||||
try:
|
from _thread import get_ident
|
||||||
from _thread import get_ident
|
|
||||||
except ImportError:
|
|
||||||
from _dummy_thread import get_ident
|
|
||||||
|
|
||||||
def recursive_repr(fillvalue='...'):
|
def recursive_repr(fillvalue='...'):
|
||||||
'Decorator to make a repr function return fillvalue for a recursive call'
|
'Decorator to make a repr function return fillvalue for a recursive call'
|
||||||
|
|
|
@ -26,10 +26,7 @@ has another way to reference private data (besides global variables).
|
||||||
import time
|
import time
|
||||||
import heapq
|
import heapq
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
import dummy_threading as threading
|
|
||||||
from time import monotonic as _time
|
from time import monotonic as _time
|
||||||
|
|
||||||
__all__ = ["scheduler"]
|
__all__ = ["scheduler"]
|
||||||
|
|
|
@ -127,10 +127,7 @@ import socket
|
||||||
import selectors
|
import selectors
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
import dummy_threading as threading
|
|
||||||
from io import BufferedIOBase
|
from io import BufferedIOBase
|
||||||
from time import monotonic as time
|
from time import monotonic as time
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,9 @@
|
||||||
# misrepresented as being the original software.
|
# misrepresented as being the original software.
|
||||||
# 3. This notice may not be removed or altered from any source distribution.
|
# 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
import sqlite3 as sqlite
|
import sqlite3 as sqlite
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
from test.support import TESTFN, unlink
|
from test.support import TESTFN, unlink
|
||||||
|
|
||||||
|
@ -503,7 +500,6 @@ class CursorTests(unittest.TestCase):
|
||||||
self.assertEqual(results, expected)
|
self.assertEqual(results, expected)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'This test requires threading.')
|
|
||||||
class ThreadTests(unittest.TestCase):
|
class ThreadTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.con = sqlite.connect(":memory:")
|
self.con = sqlite.connect(":memory:")
|
||||||
|
|
|
@ -138,10 +138,7 @@ else:
|
||||||
import _posixsubprocess
|
import _posixsubprocess
|
||||||
import select
|
import select
|
||||||
import selectors
|
import selectors
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
import dummy_threading as threading
|
|
||||||
|
|
||||||
# When select or poll has indicated that the file is writable,
|
# When select or poll has indicated that the file is writable,
|
||||||
# we can write up to _PIPE_BUF bytes without risk of blocking.
|
# we can write up to _PIPE_BUF bytes without risk of blocking.
|
||||||
|
|
|
@ -44,11 +44,7 @@ import shutil as _shutil
|
||||||
import errno as _errno
|
import errno as _errno
|
||||||
from random import Random as _Random
|
from random import Random as _Random
|
||||||
import weakref as _weakref
|
import weakref as _weakref
|
||||||
|
import _thread
|
||||||
try:
|
|
||||||
import _thread
|
|
||||||
except ImportError:
|
|
||||||
import _dummy_thread as _thread
|
|
||||||
_allocate_lock = _thread.allocate_lock
|
_allocate_lock = _thread.allocate_lock
|
||||||
|
|
||||||
_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
|
_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
|
||||||
|
|
|
@ -10,9 +10,9 @@ active threads survive in the child after a fork(); this is an error.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os, sys, time, unittest
|
import os, sys, time, unittest
|
||||||
|
import threading
|
||||||
import test.support as support
|
import test.support as support
|
||||||
|
|
||||||
threading = support.import_module('threading')
|
|
||||||
|
|
||||||
LONGSLEEP = 2
|
LONGSLEEP = 2
|
||||||
SHORTSLEEP = 0.5
|
SHORTSLEEP = 0.5
|
||||||
|
|
|
@ -3,15 +3,11 @@ import json
|
||||||
import os
|
import os
|
||||||
import queue
|
import queue
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import types
|
import types
|
||||||
from test import support
|
from test import support
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
print("Multiprocess option requires thread support")
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
from test.libregrtest.runtest import (
|
from test.libregrtest.runtest import (
|
||||||
runtest, INTERRUPTED, CHILD_ERROR, PROGRESS_MIN_TIME,
|
runtest, INTERRUPTED, CHILD_ERROR, PROGRESS_MIN_TIME,
|
||||||
|
|
|
@ -5,12 +5,9 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
|
import threading
|
||||||
import warnings
|
import warnings
|
||||||
from test import support
|
from test import support
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
try:
|
try:
|
||||||
import _multiprocessing, multiprocessing.process
|
import _multiprocessing, multiprocessing.process
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -181,13 +178,9 @@ class saved_test_environment:
|
||||||
# Controlling dangling references to Thread objects can make it easier
|
# Controlling dangling references to Thread objects can make it easier
|
||||||
# to track reference leaks.
|
# to track reference leaks.
|
||||||
def get_threading__dangling(self):
|
def get_threading__dangling(self):
|
||||||
if not threading:
|
|
||||||
return None
|
|
||||||
# This copies the weakrefs without making any strong reference
|
# This copies the weakrefs without making any strong reference
|
||||||
return threading._dangling.copy()
|
return threading._dangling.copy()
|
||||||
def restore_threading__dangling(self, saved):
|
def restore_threading__dangling(self, saved):
|
||||||
if not threading:
|
|
||||||
return
|
|
||||||
threading._dangling.clear()
|
threading._dangling.clear()
|
||||||
threading._dangling.update(saved)
|
threading._dangling.update(saved)
|
||||||
|
|
||||||
|
|
|
@ -25,17 +25,14 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import _thread
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import types
|
import types
|
||||||
import unittest
|
import unittest
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
try:
|
|
||||||
import _thread, threading
|
|
||||||
except ImportError:
|
|
||||||
_thread = None
|
|
||||||
threading = None
|
|
||||||
try:
|
try:
|
||||||
import multiprocessing.process
|
import multiprocessing.process
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -2028,16 +2025,11 @@ environment_altered = False
|
||||||
# at the end of a test run.
|
# at the end of a test run.
|
||||||
|
|
||||||
def threading_setup():
|
def threading_setup():
|
||||||
if _thread:
|
return _thread._count(), threading._dangling.copy()
|
||||||
return _thread._count(), threading._dangling.copy()
|
|
||||||
else:
|
|
||||||
return 1, ()
|
|
||||||
|
|
||||||
def threading_cleanup(*original_values):
|
def threading_cleanup(*original_values):
|
||||||
global environment_altered
|
global environment_altered
|
||||||
|
|
||||||
if not _thread:
|
|
||||||
return
|
|
||||||
_MAX_COUNT = 100
|
_MAX_COUNT = 100
|
||||||
t0 = time.monotonic()
|
t0 = time.monotonic()
|
||||||
for count in range(_MAX_COUNT):
|
for count in range(_MAX_COUNT):
|
||||||
|
@ -2061,9 +2053,6 @@ def reap_threads(func):
|
||||||
ensure that the threads are cleaned up even when the test fails.
|
ensure that the threads are cleaned up even when the test fails.
|
||||||
If threading is unavailable this function does nothing.
|
If threading is unavailable this function does nothing.
|
||||||
"""
|
"""
|
||||||
if not _thread:
|
|
||||||
return func
|
|
||||||
|
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def decorator(*args):
|
def decorator(*args):
|
||||||
key = threading_setup()
|
key = threading_setup()
|
||||||
|
|
|
@ -2,110 +2,104 @@
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
|
|
||||||
# If this fails, the test will be skipped.
|
|
||||||
thread = support.import_module('_thread')
|
|
||||||
|
|
||||||
import asynchat
|
import asynchat
|
||||||
import asyncore
|
import asyncore
|
||||||
import errno
|
import errno
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
import _thread as thread
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import unittest.mock
|
import unittest.mock
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
HOST = support.HOST
|
HOST = support.HOST
|
||||||
SERVER_QUIT = b'QUIT\n'
|
SERVER_QUIT = b'QUIT\n'
|
||||||
TIMEOUT = 3.0
|
TIMEOUT = 3.0
|
||||||
|
|
||||||
if threading:
|
|
||||||
class echo_server(threading.Thread):
|
|
||||||
# parameter to determine the number of bytes passed back to the
|
|
||||||
# client each send
|
|
||||||
chunk_size = 1
|
|
||||||
|
|
||||||
def __init__(self, event):
|
class echo_server(threading.Thread):
|
||||||
threading.Thread.__init__(self)
|
# parameter to determine the number of bytes passed back to the
|
||||||
self.event = event
|
# client each send
|
||||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
chunk_size = 1
|
||||||
self.port = support.bind_port(self.sock)
|
|
||||||
# This will be set if the client wants us to wait before echoing
|
|
||||||
# data back.
|
|
||||||
self.start_resend_event = None
|
|
||||||
|
|
||||||
def run(self):
|
def __init__(self, event):
|
||||||
self.sock.listen()
|
threading.Thread.__init__(self)
|
||||||
self.event.set()
|
self.event = event
|
||||||
conn, client = self.sock.accept()
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.buffer = b""
|
self.port = support.bind_port(self.sock)
|
||||||
# collect data until quit message is seen
|
# This will be set if the client wants us to wait before echoing
|
||||||
while SERVER_QUIT not in self.buffer:
|
# data back.
|
||||||
data = conn.recv(1)
|
self.start_resend_event = None
|
||||||
if not data:
|
|
||||||
break
|
|
||||||
self.buffer = self.buffer + data
|
|
||||||
|
|
||||||
# remove the SERVER_QUIT message
|
def run(self):
|
||||||
self.buffer = self.buffer.replace(SERVER_QUIT, b'')
|
self.sock.listen()
|
||||||
|
self.event.set()
|
||||||
|
conn, client = self.sock.accept()
|
||||||
|
self.buffer = b""
|
||||||
|
# collect data until quit message is seen
|
||||||
|
while SERVER_QUIT not in self.buffer:
|
||||||
|
data = conn.recv(1)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
self.buffer = self.buffer + data
|
||||||
|
|
||||||
if self.start_resend_event:
|
# remove the SERVER_QUIT message
|
||||||
self.start_resend_event.wait()
|
self.buffer = self.buffer.replace(SERVER_QUIT, b'')
|
||||||
|
|
||||||
# re-send entire set of collected data
|
if self.start_resend_event:
|
||||||
try:
|
self.start_resend_event.wait()
|
||||||
# this may fail on some tests, such as test_close_when_done,
|
|
||||||
# since the client closes the channel when it's done sending
|
# re-send entire set of collected data
|
||||||
while self.buffer:
|
try:
|
||||||
n = conn.send(self.buffer[:self.chunk_size])
|
# this may fail on some tests, such as test_close_when_done,
|
||||||
time.sleep(0.001)
|
# since the client closes the channel when it's done sending
|
||||||
self.buffer = self.buffer[n:]
|
while self.buffer:
|
||||||
except:
|
n = conn.send(self.buffer[:self.chunk_size])
|
||||||
|
time.sleep(0.001)
|
||||||
|
self.buffer = self.buffer[n:]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
self.sock.close()
|
||||||
|
|
||||||
|
class echo_client(asynchat.async_chat):
|
||||||
|
|
||||||
|
def __init__(self, terminator, server_port):
|
||||||
|
asynchat.async_chat.__init__(self)
|
||||||
|
self.contents = []
|
||||||
|
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.connect((HOST, server_port))
|
||||||
|
self.set_terminator(terminator)
|
||||||
|
self.buffer = b""
|
||||||
|
|
||||||
|
def handle_connect(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
# select.poll returns a select.POLLHUP at the end of the tests
|
||||||
|
# on darwin, so just ignore it
|
||||||
|
def handle_expt(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
conn.close()
|
def collect_incoming_data(self, data):
|
||||||
self.sock.close()
|
self.buffer += data
|
||||||
|
|
||||||
class echo_client(asynchat.async_chat):
|
def found_terminator(self):
|
||||||
|
self.contents.append(self.buffer)
|
||||||
|
self.buffer = b""
|
||||||
|
|
||||||
def __init__(self, terminator, server_port):
|
def start_echo_server():
|
||||||
asynchat.async_chat.__init__(self)
|
event = threading.Event()
|
||||||
self.contents = []
|
s = echo_server(event)
|
||||||
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
s.start()
|
||||||
self.connect((HOST, server_port))
|
event.wait()
|
||||||
self.set_terminator(terminator)
|
event.clear()
|
||||||
self.buffer = b""
|
time.sleep(0.01) # Give server time to start accepting.
|
||||||
|
return s, event
|
||||||
def handle_connect(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
if sys.platform == 'darwin':
|
|
||||||
# select.poll returns a select.POLLHUP at the end of the tests
|
|
||||||
# on darwin, so just ignore it
|
|
||||||
def handle_expt(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def collect_incoming_data(self, data):
|
|
||||||
self.buffer += data
|
|
||||||
|
|
||||||
def found_terminator(self):
|
|
||||||
self.contents.append(self.buffer)
|
|
||||||
self.buffer = b""
|
|
||||||
|
|
||||||
def start_echo_server():
|
|
||||||
event = threading.Event()
|
|
||||||
s = echo_server(event)
|
|
||||||
s.start()
|
|
||||||
event.wait()
|
|
||||||
event.clear()
|
|
||||||
time.sleep(0.01) # Give server time to start accepting.
|
|
||||||
return s, event
|
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class TestAsynchat(unittest.TestCase):
|
class TestAsynchat(unittest.TestCase):
|
||||||
usepoll = False
|
usepoll = False
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import os
|
import os
|
||||||
from test.support import load_package_tests, import_module
|
from test.support import load_package_tests, import_module
|
||||||
|
|
||||||
# Skip tests if we don't have threading.
|
|
||||||
import_module('threading')
|
|
||||||
# Skip tests if we don't have concurrent.futures.
|
# Skip tests if we don't have concurrent.futures.
|
||||||
import_module('concurrent.futures')
|
import_module('concurrent.futures')
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
import errno
|
import errno
|
||||||
import struct
|
import struct
|
||||||
|
import threading
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
@ -14,10 +15,6 @@ from io import BytesIO
|
||||||
if support.PGO:
|
if support.PGO:
|
||||||
raise unittest.SkipTest("test is not helpful for PGO")
|
raise unittest.SkipTest("test is not helpful for PGO")
|
||||||
|
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
TIMEOUT = 3
|
TIMEOUT = 3
|
||||||
HAS_UNIX_SOCKETS = hasattr(socket, 'AF_UNIX')
|
HAS_UNIX_SOCKETS = hasattr(socket, 'AF_UNIX')
|
||||||
|
@ -326,7 +323,6 @@ class DispatcherWithSendTests(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
asyncore.close_all()
|
asyncore.close_all()
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
@support.reap_threads
|
@support.reap_threads
|
||||||
def test_send(self):
|
def test_send(self):
|
||||||
evt = threading.Event()
|
evt = threading.Event()
|
||||||
|
@ -776,7 +772,6 @@ class BaseTestAPI:
|
||||||
self.assertTrue(s.socket.getsockopt(socket.SOL_SOCKET,
|
self.assertTrue(s.socket.getsockopt(socket.SOL_SOCKET,
|
||||||
socket.SO_REUSEADDR))
|
socket.SO_REUSEADDR))
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
@support.reap_threads
|
@support.reap_threads
|
||||||
def test_quick_connect(self):
|
def test_quick_connect(self):
|
||||||
# see: http://bugs.python.org/issue10340
|
# see: http://bugs.python.org/issue10340
|
||||||
|
|
|
@ -10,13 +10,10 @@ import pathlib
|
||||||
import random
|
import random
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import threading
|
||||||
from test.support import unlink
|
from test.support import unlink
|
||||||
import _compression
|
import _compression
|
||||||
|
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
# Skip tests if the bz2 module doesn't exist.
|
# Skip tests if the bz2 module doesn't exist.
|
||||||
bz2 = support.import_module('bz2')
|
bz2 = support.import_module('bz2')
|
||||||
|
@ -491,7 +488,6 @@ class BZ2FileTest(BaseTest):
|
||||||
else:
|
else:
|
||||||
self.fail("1/0 didn't raise an exception")
|
self.fail("1/0 didn't raise an exception")
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def testThreading(self):
|
def testThreading(self):
|
||||||
# Issue #7205: Using a BZ2File from several threads shouldn't deadlock.
|
# Issue #7205: Using a BZ2File from several threads shouldn't deadlock.
|
||||||
data = b"1" * 2**20
|
data = b"1" * 2**20
|
||||||
|
@ -504,13 +500,6 @@ class BZ2FileTest(BaseTest):
|
||||||
with support.start_threads(threads):
|
with support.start_threads(threads):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def testWithoutThreading(self):
|
|
||||||
module = support.import_fresh_module("bz2", blocked=("threading",))
|
|
||||||
with module.BZ2File(self.filename, "wb") as f:
|
|
||||||
f.write(b"abc")
|
|
||||||
with module.BZ2File(self.filename, "rb") as f:
|
|
||||||
self.assertEqual(f.read(), b"abc")
|
|
||||||
|
|
||||||
def testMixedIterationAndReads(self):
|
def testMixedIterationAndReads(self):
|
||||||
self.createTempFile()
|
self.createTempFile()
|
||||||
linelen = len(self.TEXT_LINES[0])
|
linelen = len(self.TEXT_LINES[0])
|
||||||
|
|
|
@ -11,6 +11,7 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
from test import support
|
from test import support
|
||||||
|
@ -20,10 +21,7 @@ try:
|
||||||
import _posixsubprocess
|
import _posixsubprocess
|
||||||
except ImportError:
|
except ImportError:
|
||||||
_posixsubprocess = None
|
_posixsubprocess = None
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
# Skip this test if the _testcapi module isn't available.
|
# Skip this test if the _testcapi module isn't available.
|
||||||
_testcapi = support.import_module('_testcapi')
|
_testcapi = support.import_module('_testcapi')
|
||||||
|
|
||||||
|
@ -52,7 +50,6 @@ class CAPITest(unittest.TestCase):
|
||||||
self.assertEqual(testfunction.attribute, "test")
|
self.assertEqual(testfunction.attribute, "test")
|
||||||
self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
|
self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_no_FatalError_infinite_loop(self):
|
def test_no_FatalError_infinite_loop(self):
|
||||||
with support.SuppressCrashReport():
|
with support.SuppressCrashReport():
|
||||||
p = subprocess.Popen([sys.executable, "-c",
|
p = subprocess.Popen([sys.executable, "-c",
|
||||||
|
@ -276,7 +273,6 @@ class CAPITest(unittest.TestCase):
|
||||||
self.assertIn(b'MemoryError 3 30', out)
|
self.assertIn(b'MemoryError 3 30', out)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class TestPendingCalls(unittest.TestCase):
|
class TestPendingCalls(unittest.TestCase):
|
||||||
|
|
||||||
def pendingcalls_submit(self, l, n):
|
def pendingcalls_submit(self, l, n):
|
||||||
|
@ -685,7 +681,6 @@ class SkipitemTest(unittest.TestCase):
|
||||||
parse((1,), {}, 'O|OO', ['', 'a', ''])
|
parse((1,), {}, 'O|OO', ['', 'a', ''])
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class TestThreadState(unittest.TestCase):
|
class TestThreadState(unittest.TestCase):
|
||||||
|
|
||||||
@support.reap_threads
|
@support.reap_threads
|
||||||
|
@ -762,7 +757,6 @@ class PyMemDebugTests(unittest.TestCase):
|
||||||
regex = regex.format(ptr=self.PTR_REGEX)
|
regex = regex.format(ptr=self.PTR_REGEX)
|
||||||
self.assertRegex(out, regex)
|
self.assertRegex(out, regex)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Test requires a GIL (multithreading)')
|
|
||||||
def check_malloc_without_gil(self, code):
|
def check_malloc_without_gil(self, code):
|
||||||
out = self.check(code)
|
out = self.check(code)
|
||||||
expected = ('Fatal Python error: Python memory allocator called '
|
expected = ('Fatal Python error: Python memory allocator called '
|
||||||
|
|
|
@ -4,10 +4,6 @@ import test.support
|
||||||
test.support.import_module('_multiprocessing')
|
test.support.import_module('_multiprocessing')
|
||||||
# Skip tests if sem_open implementation is broken.
|
# Skip tests if sem_open implementation is broken.
|
||||||
test.support.import_module('multiprocessing.synchronize')
|
test.support.import_module('multiprocessing.synchronize')
|
||||||
# import threading after _multiprocessing to raise a more relevant error
|
|
||||||
# message: "No module named _multiprocessing". _multiprocessing is not compiled
|
|
||||||
# without thread support.
|
|
||||||
test.support.import_module('threading')
|
|
||||||
|
|
||||||
from test.support.script_helper import assert_python_ok
|
from test.support.script_helper import assert_python_ok
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,10 @@
|
||||||
import io
|
import io
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
from contextlib import * # Tests __all__
|
from contextlib import * # Tests __all__
|
||||||
from test import support
|
from test import support
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
|
|
||||||
class TestAbstractContextManager(unittest.TestCase):
|
class TestAbstractContextManager(unittest.TestCase):
|
||||||
|
@ -275,7 +272,6 @@ class FileContextTestCase(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
support.unlink(tfn)
|
support.unlink(tfn)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class LockContextTestCase(unittest.TestCase):
|
class LockContextTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def boilerPlate(self, lock, locked):
|
def boilerPlate(self, lock, locked):
|
||||||
|
|
|
@ -38,10 +38,7 @@ from test.support import (import_fresh_module, TestFailed,
|
||||||
run_with_locale, cpython_only)
|
run_with_locale, cpython_only)
|
||||||
import random
|
import random
|
||||||
import inspect
|
import inspect
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
|
|
||||||
C = import_fresh_module('decimal', fresh=['_decimal'])
|
C = import_fresh_module('decimal', fresh=['_decimal'])
|
||||||
|
@ -1625,10 +1622,10 @@ class ThreadingTest(unittest.TestCase):
|
||||||
DefaultContext.Emax = save_emax
|
DefaultContext.Emax = save_emax
|
||||||
DefaultContext.Emin = save_emin
|
DefaultContext.Emin = save_emin
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'threading required')
|
|
||||||
class CThreadingTest(ThreadingTest):
|
class CThreadingTest(ThreadingTest):
|
||||||
decimal = C
|
decimal = C
|
||||||
@unittest.skipUnless(threading, 'threading required')
|
|
||||||
class PyThreadingTest(ThreadingTest):
|
class PyThreadingTest(ThreadingTest):
|
||||||
decimal = P
|
decimal = P
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from xmlrpc.server import DocXMLRPCServer
|
from xmlrpc.server import DocXMLRPCServer
|
||||||
import http.client
|
import http.client
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
from test import support
|
from test import support
|
||||||
threading = support.import_module('threading')
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
def make_request_and_skipIf(condition, reason):
|
def make_request_and_skipIf(condition, reason):
|
||||||
|
|
|
@ -1,255 +0,0 @@
|
||||||
import _dummy_thread as _thread
|
|
||||||
import time
|
|
||||||
import queue
|
|
||||||
import random
|
|
||||||
import unittest
|
|
||||||
from test import support
|
|
||||||
from unittest import mock
|
|
||||||
|
|
||||||
DELAY = 0
|
|
||||||
|
|
||||||
|
|
||||||
class LockTests(unittest.TestCase):
|
|
||||||
"""Test lock objects."""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
# Create a lock
|
|
||||||
self.lock = _thread.allocate_lock()
|
|
||||||
|
|
||||||
def test_initlock(self):
|
|
||||||
#Make sure locks start locked
|
|
||||||
self.assertFalse(self.lock.locked(),
|
|
||||||
"Lock object is not initialized unlocked.")
|
|
||||||
|
|
||||||
def test_release(self):
|
|
||||||
# Test self.lock.release()
|
|
||||||
self.lock.acquire()
|
|
||||||
self.lock.release()
|
|
||||||
self.assertFalse(self.lock.locked(),
|
|
||||||
"Lock object did not release properly.")
|
|
||||||
|
|
||||||
def test_LockType_context_manager(self):
|
|
||||||
with _thread.LockType():
|
|
||||||
pass
|
|
||||||
self.assertFalse(self.lock.locked(),
|
|
||||||
"Acquired Lock was not released")
|
|
||||||
|
|
||||||
def test_improper_release(self):
|
|
||||||
#Make sure release of an unlocked thread raises RuntimeError
|
|
||||||
self.assertRaises(RuntimeError, self.lock.release)
|
|
||||||
|
|
||||||
def test_cond_acquire_success(self):
|
|
||||||
#Make sure the conditional acquiring of the lock works.
|
|
||||||
self.assertTrue(self.lock.acquire(0),
|
|
||||||
"Conditional acquiring of the lock failed.")
|
|
||||||
|
|
||||||
def test_cond_acquire_fail(self):
|
|
||||||
#Test acquiring locked lock returns False
|
|
||||||
self.lock.acquire(0)
|
|
||||||
self.assertFalse(self.lock.acquire(0),
|
|
||||||
"Conditional acquiring of a locked lock incorrectly "
|
|
||||||
"succeeded.")
|
|
||||||
|
|
||||||
def test_uncond_acquire_success(self):
|
|
||||||
#Make sure unconditional acquiring of a lock works.
|
|
||||||
self.lock.acquire()
|
|
||||||
self.assertTrue(self.lock.locked(),
|
|
||||||
"Uncondional locking failed.")
|
|
||||||
|
|
||||||
def test_uncond_acquire_return_val(self):
|
|
||||||
#Make sure that an unconditional locking returns True.
|
|
||||||
self.assertIs(self.lock.acquire(1), True,
|
|
||||||
"Unconditional locking did not return True.")
|
|
||||||
self.assertIs(self.lock.acquire(), True)
|
|
||||||
|
|
||||||
def test_uncond_acquire_blocking(self):
|
|
||||||
#Make sure that unconditional acquiring of a locked lock blocks.
|
|
||||||
def delay_unlock(to_unlock, delay):
|
|
||||||
"""Hold on to lock for a set amount of time before unlocking."""
|
|
||||||
time.sleep(delay)
|
|
||||||
to_unlock.release()
|
|
||||||
|
|
||||||
self.lock.acquire()
|
|
||||||
start_time = int(time.time())
|
|
||||||
_thread.start_new_thread(delay_unlock,(self.lock, DELAY))
|
|
||||||
if support.verbose:
|
|
||||||
print()
|
|
||||||
print("*** Waiting for thread to release the lock "\
|
|
||||||
"(approx. %s sec.) ***" % DELAY)
|
|
||||||
self.lock.acquire()
|
|
||||||
end_time = int(time.time())
|
|
||||||
if support.verbose:
|
|
||||||
print("done")
|
|
||||||
self.assertGreaterEqual(end_time - start_time, DELAY,
|
|
||||||
"Blocking by unconditional acquiring failed.")
|
|
||||||
|
|
||||||
@mock.patch('time.sleep')
|
|
||||||
def test_acquire_timeout(self, mock_sleep):
|
|
||||||
"""Test invoking acquire() with a positive timeout when the lock is
|
|
||||||
already acquired. Ensure that time.sleep() is invoked with the given
|
|
||||||
timeout and that False is returned."""
|
|
||||||
|
|
||||||
self.lock.acquire()
|
|
||||||
retval = self.lock.acquire(waitflag=0, timeout=1)
|
|
||||||
self.assertTrue(mock_sleep.called)
|
|
||||||
mock_sleep.assert_called_once_with(1)
|
|
||||||
self.assertEqual(retval, False)
|
|
||||||
|
|
||||||
def test_lock_representation(self):
|
|
||||||
self.lock.acquire()
|
|
||||||
self.assertIn("locked", repr(self.lock))
|
|
||||||
self.lock.release()
|
|
||||||
self.assertIn("unlocked", repr(self.lock))
|
|
||||||
|
|
||||||
|
|
||||||
class MiscTests(unittest.TestCase):
|
|
||||||
"""Miscellaneous tests."""
|
|
||||||
|
|
||||||
def test_exit(self):
|
|
||||||
self.assertRaises(SystemExit, _thread.exit)
|
|
||||||
|
|
||||||
def test_ident(self):
|
|
||||||
self.assertIsInstance(_thread.get_ident(), int,
|
|
||||||
"_thread.get_ident() returned a non-integer")
|
|
||||||
self.assertGreater(_thread.get_ident(), 0)
|
|
||||||
|
|
||||||
def test_LockType(self):
|
|
||||||
self.assertIsInstance(_thread.allocate_lock(), _thread.LockType,
|
|
||||||
"_thread.LockType is not an instance of what "
|
|
||||||
"is returned by _thread.allocate_lock()")
|
|
||||||
|
|
||||||
def test_set_sentinel(self):
|
|
||||||
self.assertIsInstance(_thread._set_sentinel(), _thread.LockType,
|
|
||||||
"_thread._set_sentinel() did not return a "
|
|
||||||
"LockType instance.")
|
|
||||||
|
|
||||||
def test_interrupt_main(self):
|
|
||||||
#Calling start_new_thread with a function that executes interrupt_main
|
|
||||||
# should raise KeyboardInterrupt upon completion.
|
|
||||||
def call_interrupt():
|
|
||||||
_thread.interrupt_main()
|
|
||||||
|
|
||||||
self.assertRaises(KeyboardInterrupt,
|
|
||||||
_thread.start_new_thread,
|
|
||||||
call_interrupt,
|
|
||||||
tuple())
|
|
||||||
|
|
||||||
def test_interrupt_in_main(self):
|
|
||||||
self.assertRaises(KeyboardInterrupt, _thread.interrupt_main)
|
|
||||||
|
|
||||||
def test_stack_size_None(self):
|
|
||||||
retval = _thread.stack_size(None)
|
|
||||||
self.assertEqual(retval, 0)
|
|
||||||
|
|
||||||
def test_stack_size_not_None(self):
|
|
||||||
with self.assertRaises(_thread.error) as cm:
|
|
||||||
_thread.stack_size("")
|
|
||||||
self.assertEqual(cm.exception.args[0],
|
|
||||||
"setting thread stack size not supported")
|
|
||||||
|
|
||||||
|
|
||||||
class ThreadTests(unittest.TestCase):
|
|
||||||
"""Test thread creation."""
|
|
||||||
|
|
||||||
def test_arg_passing(self):
|
|
||||||
#Make sure that parameter passing works.
|
|
||||||
def arg_tester(queue, arg1=False, arg2=False):
|
|
||||||
"""Use to test _thread.start_new_thread() passes args properly."""
|
|
||||||
queue.put((arg1, arg2))
|
|
||||||
|
|
||||||
testing_queue = queue.Queue(1)
|
|
||||||
_thread.start_new_thread(arg_tester, (testing_queue, True, True))
|
|
||||||
result = testing_queue.get()
|
|
||||||
self.assertTrue(result[0] and result[1],
|
|
||||||
"Argument passing for thread creation "
|
|
||||||
"using tuple failed")
|
|
||||||
|
|
||||||
_thread.start_new_thread(
|
|
||||||
arg_tester,
|
|
||||||
tuple(),
|
|
||||||
{'queue':testing_queue, 'arg1':True, 'arg2':True})
|
|
||||||
|
|
||||||
result = testing_queue.get()
|
|
||||||
self.assertTrue(result[0] and result[1],
|
|
||||||
"Argument passing for thread creation "
|
|
||||||
"using kwargs failed")
|
|
||||||
|
|
||||||
_thread.start_new_thread(
|
|
||||||
arg_tester,
|
|
||||||
(testing_queue, True),
|
|
||||||
{'arg2':True})
|
|
||||||
|
|
||||||
result = testing_queue.get()
|
|
||||||
self.assertTrue(result[0] and result[1],
|
|
||||||
"Argument passing for thread creation using both tuple"
|
|
||||||
" and kwargs failed")
|
|
||||||
|
|
||||||
def test_multi_thread_creation(self):
|
|
||||||
def queue_mark(queue, delay):
|
|
||||||
time.sleep(delay)
|
|
||||||
queue.put(_thread.get_ident())
|
|
||||||
|
|
||||||
thread_count = 5
|
|
||||||
testing_queue = queue.Queue(thread_count)
|
|
||||||
|
|
||||||
if support.verbose:
|
|
||||||
print()
|
|
||||||
print("*** Testing multiple thread creation "
|
|
||||||
"(will take approx. %s to %s sec.) ***" % (
|
|
||||||
DELAY, thread_count))
|
|
||||||
|
|
||||||
for count in range(thread_count):
|
|
||||||
if DELAY:
|
|
||||||
local_delay = round(random.random(), 1)
|
|
||||||
else:
|
|
||||||
local_delay = 0
|
|
||||||
_thread.start_new_thread(queue_mark,
|
|
||||||
(testing_queue, local_delay))
|
|
||||||
time.sleep(DELAY)
|
|
||||||
if support.verbose:
|
|
||||||
print('done')
|
|
||||||
self.assertEqual(testing_queue.qsize(), thread_count,
|
|
||||||
"Not all %s threads executed properly "
|
|
||||||
"after %s sec." % (thread_count, DELAY))
|
|
||||||
|
|
||||||
def test_args_not_tuple(self):
|
|
||||||
"""
|
|
||||||
Test invoking start_new_thread() with a non-tuple value for "args".
|
|
||||||
Expect TypeError with a meaningful error message to be raised.
|
|
||||||
"""
|
|
||||||
with self.assertRaises(TypeError) as cm:
|
|
||||||
_thread.start_new_thread(mock.Mock(), [])
|
|
||||||
self.assertEqual(cm.exception.args[0], "2nd arg must be a tuple")
|
|
||||||
|
|
||||||
def test_kwargs_not_dict(self):
|
|
||||||
"""
|
|
||||||
Test invoking start_new_thread() with a non-dict value for "kwargs".
|
|
||||||
Expect TypeError with a meaningful error message to be raised.
|
|
||||||
"""
|
|
||||||
with self.assertRaises(TypeError) as cm:
|
|
||||||
_thread.start_new_thread(mock.Mock(), tuple(), kwargs=[])
|
|
||||||
self.assertEqual(cm.exception.args[0], "3rd arg must be a dict")
|
|
||||||
|
|
||||||
def test_SystemExit(self):
|
|
||||||
"""
|
|
||||||
Test invoking start_new_thread() with a function that raises
|
|
||||||
SystemExit.
|
|
||||||
The exception should be discarded.
|
|
||||||
"""
|
|
||||||
func = mock.Mock(side_effect=SystemExit())
|
|
||||||
try:
|
|
||||||
_thread.start_new_thread(func, tuple())
|
|
||||||
except SystemExit:
|
|
||||||
self.fail("start_new_thread raised SystemExit.")
|
|
||||||
|
|
||||||
@mock.patch('traceback.print_exc')
|
|
||||||
def test_RaiseException(self, mock_print_exc):
|
|
||||||
"""
|
|
||||||
Test invoking start_new_thread() with a function that raises exception.
|
|
||||||
|
|
||||||
The exception should be discarded and the traceback should be printed
|
|
||||||
via traceback.print_exc()
|
|
||||||
"""
|
|
||||||
func = mock.Mock(side_effect=Exception)
|
|
||||||
_thread.start_new_thread(func, tuple())
|
|
||||||
self.assertTrue(mock_print_exc.called)
|
|
|
@ -1,60 +0,0 @@
|
||||||
from test import support
|
|
||||||
import unittest
|
|
||||||
import dummy_threading as _threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
class DummyThreadingTestCase(unittest.TestCase):
|
|
||||||
|
|
||||||
class TestThread(_threading.Thread):
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
global running
|
|
||||||
global sema
|
|
||||||
global mutex
|
|
||||||
# Uncomment if testing another module, such as the real 'threading'
|
|
||||||
# module.
|
|
||||||
#delay = random.random() * 2
|
|
||||||
delay = 0
|
|
||||||
if support.verbose:
|
|
||||||
print('task', self.name, 'will run for', delay, 'sec')
|
|
||||||
sema.acquire()
|
|
||||||
mutex.acquire()
|
|
||||||
running += 1
|
|
||||||
if support.verbose:
|
|
||||||
print(running, 'tasks are running')
|
|
||||||
mutex.release()
|
|
||||||
time.sleep(delay)
|
|
||||||
if support.verbose:
|
|
||||||
print('task', self.name, 'done')
|
|
||||||
mutex.acquire()
|
|
||||||
running -= 1
|
|
||||||
if support.verbose:
|
|
||||||
print(self.name, 'is finished.', running, 'tasks are running')
|
|
||||||
mutex.release()
|
|
||||||
sema.release()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.numtasks = 10
|
|
||||||
global sema
|
|
||||||
sema = _threading.BoundedSemaphore(value=3)
|
|
||||||
global mutex
|
|
||||||
mutex = _threading.RLock()
|
|
||||||
global running
|
|
||||||
running = 0
|
|
||||||
self.threads = []
|
|
||||||
|
|
||||||
def test_tasks(self):
|
|
||||||
for i in range(self.numtasks):
|
|
||||||
t = self.TestThread(name="<thread %d>"%i)
|
|
||||||
self.threads.append(t)
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
if support.verbose:
|
|
||||||
print('waiting for all tasks to complete')
|
|
||||||
for t in self.threads:
|
|
||||||
t.join()
|
|
||||||
if support.verbose:
|
|
||||||
print('all tasks done')
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
|
@ -12,10 +12,7 @@ from io import StringIO, BytesIO
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from random import choice
|
from random import choice
|
||||||
from socket import getfqdn
|
from socket import getfqdn
|
||||||
try:
|
from threading import Thread
|
||||||
from threading import Thread
|
|
||||||
except ImportError:
|
|
||||||
from dummy_threading import Thread
|
|
||||||
|
|
||||||
import email
|
import email
|
||||||
import email.policy
|
import email.policy
|
||||||
|
|
|
@ -2,15 +2,12 @@ import enum
|
||||||
import inspect
|
import inspect
|
||||||
import pydoc
|
import pydoc
|
||||||
import unittest
|
import unittest
|
||||||
|
import threading
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from enum import Enum, IntEnum, EnumMeta, Flag, IntFlag, unique, auto
|
from enum import Enum, IntEnum, EnumMeta, Flag, IntFlag, unique, auto
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
|
from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
|
||||||
from test import support
|
from test import support
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
|
|
||||||
# for pickle tests
|
# for pickle tests
|
||||||
|
@ -1988,7 +1985,6 @@ class TestFlag(unittest.TestCase):
|
||||||
d = 6
|
d = 6
|
||||||
self.assertEqual(repr(Bizarre(7)), '<Bizarre.d|c|b: 7>')
|
self.assertEqual(repr(Bizarre(7)), '<Bizarre.d|c|b: 7>')
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
@support.reap_threads
|
@support.reap_threads
|
||||||
def test_unique_composite(self):
|
def test_unique_composite(self):
|
||||||
# override __eq__ to be identity only
|
# override __eq__ to be identity only
|
||||||
|
@ -2339,7 +2335,6 @@ class TestIntFlag(unittest.TestCase):
|
||||||
for f in Open:
|
for f in Open:
|
||||||
self.assertEqual(bool(f.value), bool(f))
|
self.assertEqual(bool(f.value), bool(f))
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
@support.reap_threads
|
@support.reap_threads
|
||||||
def test_unique_composite(self):
|
def test_unique_composite(self):
|
||||||
# override __eq__ to be identity only
|
# override __eq__ to be identity only
|
||||||
|
|
|
@ -8,14 +8,10 @@ import sys
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import script_helper, is_android, requires_android_level
|
from test.support import script_helper, is_android, requires_android_level
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
|
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
HAVE_THREADS = True
|
|
||||||
except ImportError:
|
|
||||||
HAVE_THREADS = False
|
|
||||||
try:
|
try:
|
||||||
import _testcapi
|
import _testcapi
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -154,7 +150,6 @@ class FaultHandlerTests(unittest.TestCase):
|
||||||
3,
|
3,
|
||||||
'Segmentation fault')
|
'Segmentation fault')
|
||||||
|
|
||||||
@unittest.skipIf(not HAVE_THREADS, 'need threads')
|
|
||||||
def test_fatal_error_c_thread(self):
|
def test_fatal_error_c_thread(self):
|
||||||
self.check_fatal_error("""
|
self.check_fatal_error("""
|
||||||
import faulthandler
|
import faulthandler
|
||||||
|
@ -231,7 +226,7 @@ class FaultHandlerTests(unittest.TestCase):
|
||||||
2,
|
2,
|
||||||
'xyz')
|
'xyz')
|
||||||
|
|
||||||
@unittest.skipIf(sys.platform.startswith('openbsd') and HAVE_THREADS,
|
@unittest.skipIf(sys.platform.startswith('openbsd'),
|
||||||
"Issue #12868: sigaltstack() doesn't work on "
|
"Issue #12868: sigaltstack() doesn't work on "
|
||||||
"OpenBSD if Python is compiled with pthread")
|
"OpenBSD if Python is compiled with pthread")
|
||||||
@unittest.skipIf(not hasattr(faulthandler, '_stack_overflow'),
|
@unittest.skipIf(not hasattr(faulthandler, '_stack_overflow'),
|
||||||
|
@ -456,7 +451,6 @@ class FaultHandlerTests(unittest.TestCase):
|
||||||
self.assertEqual(trace, expected)
|
self.assertEqual(trace, expected)
|
||||||
self.assertEqual(exitcode, 0)
|
self.assertEqual(exitcode, 0)
|
||||||
|
|
||||||
@unittest.skipIf(not HAVE_THREADS, 'need threads')
|
|
||||||
def check_dump_traceback_threads(self, filename):
|
def check_dump_traceback_threads(self, filename):
|
||||||
"""
|
"""
|
||||||
Call explicitly dump_traceback(all_threads=True) and check the output.
|
Call explicitly dump_traceback(all_threads=True) and check the output.
|
||||||
|
|
|
@ -5,6 +5,7 @@ import _imp as imp
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
@ -12,7 +13,6 @@ from test.fork_wait import ForkWait
|
||||||
from test.support import (reap_children, get_attribute,
|
from test.support import (reap_children, get_attribute,
|
||||||
import_module, verbose)
|
import_module, verbose)
|
||||||
|
|
||||||
threading = import_module('threading')
|
|
||||||
|
|
||||||
# Skip test if fork does not exist.
|
# Skip test if fork does not exist.
|
||||||
get_attribute(os, 'fork')
|
get_attribute(os, 'fork')
|
||||||
|
|
|
@ -10,6 +10,7 @@ import socket
|
||||||
import io
|
import io
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
try:
|
try:
|
||||||
import ssl
|
import ssl
|
||||||
|
@ -19,7 +20,6 @@ except ImportError:
|
||||||
from unittest import TestCase, skipUnless
|
from unittest import TestCase, skipUnless
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import HOST, HOSTv6
|
from test.support import HOST, HOSTv6
|
||||||
threading = support.import_module('threading')
|
|
||||||
|
|
||||||
TIMEOUT = 3
|
TIMEOUT = 3
|
||||||
# the dummy data returned by server over the data channel when
|
# the dummy data returned by server over the data channel when
|
||||||
|
|
|
@ -8,15 +8,12 @@ import pickle
|
||||||
from random import choice
|
from random import choice
|
||||||
import sys
|
import sys
|
||||||
from test import support
|
from test import support
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import unittest.mock
|
import unittest.mock
|
||||||
from weakref import proxy
|
from weakref import proxy
|
||||||
import contextlib
|
import contextlib
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
@ -1406,7 +1403,6 @@ class TestLRU:
|
||||||
for attr in self.module.WRAPPER_ASSIGNMENTS:
|
for attr in self.module.WRAPPER_ASSIGNMENTS:
|
||||||
self.assertEqual(getattr(g, attr), getattr(f, attr))
|
self.assertEqual(getattr(g, attr), getattr(f, attr))
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'This test requires threading.')
|
|
||||||
def test_lru_cache_threaded(self):
|
def test_lru_cache_threaded(self):
|
||||||
n, m = 5, 11
|
n, m = 5, 11
|
||||||
def orig(x, y):
|
def orig(x, y):
|
||||||
|
@ -1455,7 +1451,6 @@ class TestLRU:
|
||||||
finally:
|
finally:
|
||||||
sys.setswitchinterval(orig_si)
|
sys.setswitchinterval(orig_si)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'This test requires threading.')
|
|
||||||
def test_lru_cache_threaded2(self):
|
def test_lru_cache_threaded2(self):
|
||||||
# Simultaneous call with the same arguments
|
# Simultaneous call with the same arguments
|
||||||
n, m = 5, 7
|
n, m = 5, 7
|
||||||
|
@ -1483,7 +1478,6 @@ class TestLRU:
|
||||||
pause.reset()
|
pause.reset()
|
||||||
self.assertEqual(f.cache_info(), (0, (i+1)*n, m*n, i+1))
|
self.assertEqual(f.cache_info(), (0, (i+1)*n, m*n, i+1))
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'This test requires threading.')
|
|
||||||
def test_lru_cache_threaded3(self):
|
def test_lru_cache_threaded3(self):
|
||||||
@self.module.lru_cache(maxsize=2)
|
@self.module.lru_cache(maxsize=2)
|
||||||
def f(x):
|
def f(x):
|
||||||
|
|
|
@ -8,11 +8,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
import gc
|
import gc
|
||||||
import weakref
|
import weakref
|
||||||
|
import threading
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from _testcapi import with_tp_del
|
from _testcapi import with_tp_del
|
||||||
|
@ -352,7 +348,6 @@ class GCTests(unittest.TestCase):
|
||||||
v = {1: v, 2: Ouch()}
|
v = {1: v, 2: Ouch()}
|
||||||
gc.disable()
|
gc.disable()
|
||||||
|
|
||||||
@unittest.skipUnless(threading, "test meaningless on builds without threads")
|
|
||||||
def test_trashcan_threads(self):
|
def test_trashcan_threads(self):
|
||||||
# Issue #13992: trashcan mechanism should be thread-safe
|
# Issue #13992: trashcan mechanism should be thread-safe
|
||||||
NESTING = 60
|
NESTING = 60
|
||||||
|
|
|
@ -12,12 +12,6 @@ import sysconfig
|
||||||
import textwrap
|
import textwrap
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
# Is this Python configured to support threads?
|
|
||||||
try:
|
|
||||||
import _thread
|
|
||||||
except ImportError:
|
|
||||||
_thread = None
|
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import run_unittest, findfile, python_is_optimized
|
from test.support import run_unittest, findfile, python_is_optimized
|
||||||
|
|
||||||
|
@ -755,8 +749,6 @@ Traceback \(most recent call first\):
|
||||||
foo\(1, 2, 3\)
|
foo\(1, 2, 3\)
|
||||||
''')
|
''')
|
||||||
|
|
||||||
@unittest.skipUnless(_thread,
|
|
||||||
"Python was compiled without thread support")
|
|
||||||
def test_threads(self):
|
def test_threads(self):
|
||||||
'Verify that "py-bt" indicates threads that are waiting for the GIL'
|
'Verify that "py-bt" indicates threads that are waiting for the GIL'
|
||||||
cmd = '''
|
cmd = '''
|
||||||
|
@ -794,8 +786,6 @@ id(42)
|
||||||
# Some older versions of gdb will fail with
|
# Some older versions of gdb will fail with
|
||||||
# "Cannot find new threads: generic error"
|
# "Cannot find new threads: generic error"
|
||||||
# unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
|
# unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
|
||||||
@unittest.skipUnless(_thread,
|
|
||||||
"Python was compiled without thread support")
|
|
||||||
def test_gc(self):
|
def test_gc(self):
|
||||||
'Verify that "py-bt" indicates if a thread is garbage-collecting'
|
'Verify that "py-bt" indicates if a thread is garbage-collecting'
|
||||||
cmd = ('from gc import collect\n'
|
cmd = ('from gc import collect\n'
|
||||||
|
@ -822,8 +812,6 @@ id(42)
|
||||||
# Some older versions of gdb will fail with
|
# Some older versions of gdb will fail with
|
||||||
# "Cannot find new threads: generic error"
|
# "Cannot find new threads: generic error"
|
||||||
# unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
|
# unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
|
||||||
@unittest.skipUnless(_thread,
|
|
||||||
"Python was compiled without thread support")
|
|
||||||
def test_pycfunction(self):
|
def test_pycfunction(self):
|
||||||
'Verify that "py-bt" displays invocations of PyCFunction instances'
|
'Verify that "py-bt" displays invocations of PyCFunction instances'
|
||||||
# Tested function must not be defined with METH_NOARGS or METH_O,
|
# Tested function must not be defined with METH_NOARGS or METH_O,
|
||||||
|
|
|
@ -12,10 +12,7 @@ import hashlib
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
import warnings
|
||||||
from test import support
|
from test import support
|
||||||
|
@ -738,7 +735,6 @@ class HashLibTestCase(unittest.TestCase):
|
||||||
m = hashlib.md5(b'x' * gil_minsize)
|
m = hashlib.md5(b'x' * gil_minsize)
|
||||||
self.assertEqual(m.hexdigest(), 'cfb767f225d58469c5de3632a8803958')
|
self.assertEqual(m.hexdigest(), 'cfb767f225d58469c5de3632a8803958')
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
@support.reap_threads
|
@support.reap_threads
|
||||||
def test_threaded_hashing(self):
|
def test_threaded_hashing(self):
|
||||||
# Updating the same hash object from several threads at once
|
# Updating the same hash object from several threads at once
|
||||||
|
|
|
@ -22,12 +22,13 @@ import urllib.parse
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
import threading
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from test import support
|
from test import support
|
||||||
threading = support.import_module('threading')
|
|
||||||
|
|
||||||
class NoLogRequestHandler:
|
class NoLogRequestHandler:
|
||||||
def log_message(self, *args):
|
def log_message(self, *args):
|
||||||
|
|
|
@ -3,7 +3,6 @@ from test.support import import_module
|
||||||
|
|
||||||
# Skip test if _thread or _tkinter wasn't built, if idlelib is missing,
|
# Skip test if _thread or _tkinter wasn't built, if idlelib is missing,
|
||||||
# or if tcl/tk is not the 8.5+ needed for ttk widgets.
|
# or if tcl/tk is not the 8.5+ needed for ttk widgets.
|
||||||
import_module('threading') # imported by PyShell, imports _thread
|
|
||||||
tk = import_module('tkinter') # imports _tkinter
|
tk = import_module('tkinter') # imports _tkinter
|
||||||
if tk.TkVersion < 8.5:
|
if tk.TkVersion < 8.5:
|
||||||
raise unittest.SkipTest("IDLE requires tk 8.5 or later.")
|
raise unittest.SkipTest("IDLE requires tk 8.5 or later.")
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
from test import support
|
from test import support
|
||||||
# If we end up with a significant number of tests that don't require
|
|
||||||
# threading, this test module should be split. Right now we skip
|
|
||||||
# them all if we don't have threading.
|
|
||||||
threading = support.import_module('threading')
|
|
||||||
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
import imaplib
|
import imaplib
|
||||||
|
@ -10,6 +6,7 @@ import os.path
|
||||||
import socketserver
|
import socketserver
|
||||||
import time
|
import time
|
||||||
import calendar
|
import calendar
|
||||||
|
import threading
|
||||||
|
|
||||||
from test.support import (reap_threads, verbose, transient_internet,
|
from test.support import (reap_threads, verbose, transient_internet,
|
||||||
run_with_tz, run_with_locale, cpython_only)
|
run_with_tz, run_with_locale, cpython_only)
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
try:
|
|
||||||
import _thread
|
|
||||||
except ImportError:
|
|
||||||
_thread = None
|
|
||||||
import importlib
|
import importlib
|
||||||
import importlib.util
|
import importlib.util
|
||||||
import os
|
import os
|
||||||
|
@ -23,7 +19,6 @@ def requires_load_dynamic(meth):
|
||||||
'imp.load_dynamic() required')(meth)
|
'imp.load_dynamic() required')(meth)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(_thread is None, '_thread module is required')
|
|
||||||
class LockTests(unittest.TestCase):
|
class LockTests(unittest.TestCase):
|
||||||
|
|
||||||
"""Very basic test of import lock functions."""
|
"""Very basic test of import lock functions."""
|
||||||
|
|
|
@ -3,134 +3,112 @@ from . import util as test_util
|
||||||
init = test_util.import_importlib('importlib')
|
init = test_util.import_importlib('importlib')
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
|
from test import lock_tests
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
else:
|
|
||||||
from test import lock_tests
|
|
||||||
|
|
||||||
if threading is not None:
|
|
||||||
class ModuleLockAsRLockTests:
|
|
||||||
locktype = classmethod(lambda cls: cls.LockType("some_lock"))
|
|
||||||
|
|
||||||
# _is_owned() unsupported
|
|
||||||
test__is_owned = None
|
|
||||||
# acquire(blocking=False) unsupported
|
|
||||||
test_try_acquire = None
|
|
||||||
test_try_acquire_contended = None
|
|
||||||
# `with` unsupported
|
|
||||||
test_with = None
|
|
||||||
# acquire(timeout=...) unsupported
|
|
||||||
test_timeout = None
|
|
||||||
# _release_save() unsupported
|
|
||||||
test_release_save_unacquired = None
|
|
||||||
# lock status in repr unsupported
|
|
||||||
test_repr = None
|
|
||||||
test_locked_repr = None
|
|
||||||
|
|
||||||
LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock
|
|
||||||
for kind, splitinit in init.items()}
|
|
||||||
|
|
||||||
(Frozen_ModuleLockAsRLockTests,
|
|
||||||
Source_ModuleLockAsRLockTests
|
|
||||||
) = test_util.test_both(ModuleLockAsRLockTests, lock_tests.RLockTests,
|
|
||||||
LockType=LOCK_TYPES)
|
|
||||||
else:
|
|
||||||
LOCK_TYPES = {}
|
|
||||||
|
|
||||||
class Frozen_ModuleLockAsRLockTests(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Source_ModuleLockAsRLockTests(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
if threading is not None:
|
class ModuleLockAsRLockTests:
|
||||||
class DeadlockAvoidanceTests:
|
locktype = classmethod(lambda cls: cls.LockType("some_lock"))
|
||||||
|
|
||||||
def setUp(self):
|
# _is_owned() unsupported
|
||||||
|
test__is_owned = None
|
||||||
|
# acquire(blocking=False) unsupported
|
||||||
|
test_try_acquire = None
|
||||||
|
test_try_acquire_contended = None
|
||||||
|
# `with` unsupported
|
||||||
|
test_with = None
|
||||||
|
# acquire(timeout=...) unsupported
|
||||||
|
test_timeout = None
|
||||||
|
# _release_save() unsupported
|
||||||
|
test_release_save_unacquired = None
|
||||||
|
# lock status in repr unsupported
|
||||||
|
test_repr = None
|
||||||
|
test_locked_repr = None
|
||||||
|
|
||||||
|
LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock
|
||||||
|
for kind, splitinit in init.items()}
|
||||||
|
|
||||||
|
(Frozen_ModuleLockAsRLockTests,
|
||||||
|
Source_ModuleLockAsRLockTests
|
||||||
|
) = test_util.test_both(ModuleLockAsRLockTests, lock_tests.RLockTests,
|
||||||
|
LockType=LOCK_TYPES)
|
||||||
|
|
||||||
|
|
||||||
|
class DeadlockAvoidanceTests:
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
try:
|
||||||
|
self.old_switchinterval = sys.getswitchinterval()
|
||||||
|
support.setswitchinterval(0.000001)
|
||||||
|
except AttributeError:
|
||||||
|
self.old_switchinterval = None
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
if self.old_switchinterval is not None:
|
||||||
|
sys.setswitchinterval(self.old_switchinterval)
|
||||||
|
|
||||||
|
def run_deadlock_avoidance_test(self, create_deadlock):
|
||||||
|
NLOCKS = 10
|
||||||
|
locks = [self.LockType(str(i)) for i in range(NLOCKS)]
|
||||||
|
pairs = [(locks[i], locks[(i+1)%NLOCKS]) for i in range(NLOCKS)]
|
||||||
|
if create_deadlock:
|
||||||
|
NTHREADS = NLOCKS
|
||||||
|
else:
|
||||||
|
NTHREADS = NLOCKS - 1
|
||||||
|
barrier = threading.Barrier(NTHREADS)
|
||||||
|
results = []
|
||||||
|
|
||||||
|
def _acquire(lock):
|
||||||
|
"""Try to acquire the lock. Return True on success,
|
||||||
|
False on deadlock."""
|
||||||
try:
|
try:
|
||||||
self.old_switchinterval = sys.getswitchinterval()
|
lock.acquire()
|
||||||
support.setswitchinterval(0.000001)
|
except self.DeadlockError:
|
||||||
except AttributeError:
|
return False
|
||||||
self.old_switchinterval = None
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
if self.old_switchinterval is not None:
|
|
||||||
sys.setswitchinterval(self.old_switchinterval)
|
|
||||||
|
|
||||||
def run_deadlock_avoidance_test(self, create_deadlock):
|
|
||||||
NLOCKS = 10
|
|
||||||
locks = [self.LockType(str(i)) for i in range(NLOCKS)]
|
|
||||||
pairs = [(locks[i], locks[(i+1)%NLOCKS]) for i in range(NLOCKS)]
|
|
||||||
if create_deadlock:
|
|
||||||
NTHREADS = NLOCKS
|
|
||||||
else:
|
else:
|
||||||
NTHREADS = NLOCKS - 1
|
return True
|
||||||
barrier = threading.Barrier(NTHREADS)
|
|
||||||
results = []
|
|
||||||
|
|
||||||
def _acquire(lock):
|
def f():
|
||||||
"""Try to acquire the lock. Return True on success,
|
a, b = pairs.pop()
|
||||||
False on deadlock."""
|
ra = _acquire(a)
|
||||||
try:
|
barrier.wait()
|
||||||
lock.acquire()
|
rb = _acquire(b)
|
||||||
except self.DeadlockError:
|
results.append((ra, rb))
|
||||||
return False
|
if rb:
|
||||||
else:
|
b.release()
|
||||||
return True
|
if ra:
|
||||||
|
a.release()
|
||||||
|
lock_tests.Bunch(f, NTHREADS).wait_for_finished()
|
||||||
|
self.assertEqual(len(results), NTHREADS)
|
||||||
|
return results
|
||||||
|
|
||||||
def f():
|
def test_deadlock(self):
|
||||||
a, b = pairs.pop()
|
results = self.run_deadlock_avoidance_test(True)
|
||||||
ra = _acquire(a)
|
# At least one of the threads detected a potential deadlock on its
|
||||||
barrier.wait()
|
# second acquire() call. It may be several of them, because the
|
||||||
rb = _acquire(b)
|
# deadlock avoidance mechanism is conservative.
|
||||||
results.append((ra, rb))
|
nb_deadlocks = results.count((True, False))
|
||||||
if rb:
|
self.assertGreaterEqual(nb_deadlocks, 1)
|
||||||
b.release()
|
self.assertEqual(results.count((True, True)), len(results) - nb_deadlocks)
|
||||||
if ra:
|
|
||||||
a.release()
|
|
||||||
lock_tests.Bunch(f, NTHREADS).wait_for_finished()
|
|
||||||
self.assertEqual(len(results), NTHREADS)
|
|
||||||
return results
|
|
||||||
|
|
||||||
def test_deadlock(self):
|
def test_no_deadlock(self):
|
||||||
results = self.run_deadlock_avoidance_test(True)
|
results = self.run_deadlock_avoidance_test(False)
|
||||||
# At least one of the threads detected a potential deadlock on its
|
self.assertEqual(results.count((True, False)), 0)
|
||||||
# second acquire() call. It may be several of them, because the
|
self.assertEqual(results.count((True, True)), len(results))
|
||||||
# deadlock avoidance mechanism is conservative.
|
|
||||||
nb_deadlocks = results.count((True, False))
|
|
||||||
self.assertGreaterEqual(nb_deadlocks, 1)
|
|
||||||
self.assertEqual(results.count((True, True)), len(results) - nb_deadlocks)
|
|
||||||
|
|
||||||
def test_no_deadlock(self):
|
|
||||||
results = self.run_deadlock_avoidance_test(False)
|
|
||||||
self.assertEqual(results.count((True, False)), 0)
|
|
||||||
self.assertEqual(results.count((True, True)), len(results))
|
|
||||||
|
|
||||||
|
|
||||||
DEADLOCK_ERRORS = {kind: splitinit._bootstrap._DeadlockError
|
DEADLOCK_ERRORS = {kind: splitinit._bootstrap._DeadlockError
|
||||||
for kind, splitinit in init.items()}
|
for kind, splitinit in init.items()}
|
||||||
|
|
||||||
(Frozen_DeadlockAvoidanceTests,
|
(Frozen_DeadlockAvoidanceTests,
|
||||||
Source_DeadlockAvoidanceTests
|
Source_DeadlockAvoidanceTests
|
||||||
) = test_util.test_both(DeadlockAvoidanceTests,
|
) = test_util.test_both(DeadlockAvoidanceTests,
|
||||||
LockType=LOCK_TYPES,
|
LockType=LOCK_TYPES,
|
||||||
DeadlockError=DEADLOCK_ERRORS)
|
DeadlockError=DEADLOCK_ERRORS)
|
||||||
else:
|
|
||||||
DEADLOCK_ERRORS = {}
|
|
||||||
|
|
||||||
class Frozen_DeadlockAvoidanceTests(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Source_DeadlockAvoidanceTests(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class LifetimeTests:
|
class LifetimeTests:
|
||||||
|
|
|
@ -28,6 +28,7 @@ import pickle
|
||||||
import random
|
import random
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
import warnings
|
||||||
|
@ -40,10 +41,6 @@ from test.support.script_helper import assert_python_ok, run_python_until_end
|
||||||
import codecs
|
import codecs
|
||||||
import io # C implementation of io
|
import io # C implementation of io
|
||||||
import _pyio as pyio # Python implementation of io
|
import _pyio as pyio # Python implementation of io
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import ctypes
|
import ctypes
|
||||||
|
@ -443,8 +440,6 @@ class IOTest(unittest.TestCase):
|
||||||
(self.BytesIO, "rws"), (self.StringIO, "rws"),
|
(self.BytesIO, "rws"), (self.StringIO, "rws"),
|
||||||
)
|
)
|
||||||
for [test, abilities] in tests:
|
for [test, abilities] in tests:
|
||||||
if test is pipe_writer and not threading:
|
|
||||||
continue # Skip subtest that uses a background thread
|
|
||||||
with self.subTest(test), test() as obj:
|
with self.subTest(test), test() as obj:
|
||||||
readable = "r" in abilities
|
readable = "r" in abilities
|
||||||
self.assertEqual(obj.readable(), readable)
|
self.assertEqual(obj.readable(), readable)
|
||||||
|
@ -1337,7 +1332,6 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests):
|
||||||
|
|
||||||
self.assertEqual(b"abcdefg", bufio.read())
|
self.assertEqual(b"abcdefg", bufio.read())
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
@support.requires_resource('cpu')
|
@support.requires_resource('cpu')
|
||||||
def test_threads(self):
|
def test_threads(self):
|
||||||
try:
|
try:
|
||||||
|
@ -1664,7 +1658,6 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests):
|
||||||
with self.open(support.TESTFN, "rb", buffering=0) as f:
|
with self.open(support.TESTFN, "rb", buffering=0) as f:
|
||||||
self.assertEqual(f.read(), b"abc")
|
self.assertEqual(f.read(), b"abc")
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
@support.requires_resource('cpu')
|
@support.requires_resource('cpu')
|
||||||
def test_threads(self):
|
def test_threads(self):
|
||||||
try:
|
try:
|
||||||
|
@ -3053,7 +3046,6 @@ class TextIOWrapperTest(unittest.TestCase):
|
||||||
self.assertEqual(f.errors, "replace")
|
self.assertEqual(f.errors, "replace")
|
||||||
|
|
||||||
@support.no_tracing
|
@support.no_tracing
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_threads_write(self):
|
def test_threads_write(self):
|
||||||
# Issue6750: concurrent writes could duplicate data
|
# Issue6750: concurrent writes could duplicate data
|
||||||
event = threading.Event()
|
event = threading.Event()
|
||||||
|
@ -3804,7 +3796,6 @@ class CMiscIOTest(MiscIOTest):
|
||||||
b = bytearray(2)
|
b = bytearray(2)
|
||||||
self.assertRaises(ValueError, bufio.readinto, b)
|
self.assertRaises(ValueError, bufio.readinto, b)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def check_daemon_threads_shutdown_deadlock(self, stream_name):
|
def check_daemon_threads_shutdown_deadlock(self, stream_name):
|
||||||
# Issue #23309: deadlocks at shutdown should be avoided when a
|
# Issue #23309: deadlocks at shutdown should be avoided when a
|
||||||
# daemon thread and the main thread both write to a file.
|
# daemon thread and the main thread both write to a file.
|
||||||
|
@ -3868,7 +3859,6 @@ class SignalsTest(unittest.TestCase):
|
||||||
def alarm_interrupt(self, sig, frame):
|
def alarm_interrupt(self, sig, frame):
|
||||||
1/0
|
1/0
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def check_interrupted_write(self, item, bytes, **fdopen_kwargs):
|
def check_interrupted_write(self, item, bytes, **fdopen_kwargs):
|
||||||
"""Check that a partial write, when it gets interrupted, properly
|
"""Check that a partial write, when it gets interrupted, properly
|
||||||
invokes the signal handler, and bubbles up the exception raised
|
invokes the signal handler, and bubbles up the exception raised
|
||||||
|
@ -3990,7 +3980,6 @@ class SignalsTest(unittest.TestCase):
|
||||||
self.check_interrupted_read_retry(lambda x: x,
|
self.check_interrupted_read_retry(lambda x: x,
|
||||||
mode="r")
|
mode="r")
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def check_interrupted_write_retry(self, item, **fdopen_kwargs):
|
def check_interrupted_write_retry(self, item, **fdopen_kwargs):
|
||||||
"""Check that a buffered write, when it gets interrupted (either
|
"""Check that a buffered write, when it gets interrupted (either
|
||||||
returning a partial result or EINTR), properly invokes the signal
|
returning a partial result or EINTR), properly invokes the signal
|
||||||
|
|
|
@ -42,22 +42,19 @@ import tempfile
|
||||||
from test.support.script_helper import assert_python_ok
|
from test.support.script_helper import assert_python_ok
|
||||||
from test import support
|
from test import support
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
import warnings
|
||||||
import weakref
|
import weakref
|
||||||
try:
|
|
||||||
import threading
|
import asyncore
|
||||||
# The following imports are needed only for tests which
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||||
# require threading
|
import smtpd
|
||||||
import asyncore
|
from urllib.parse import urlparse, parse_qs
|
||||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
from socketserver import (ThreadingUDPServer, DatagramRequestHandler,
|
||||||
import smtpd
|
ThreadingTCPServer, StreamRequestHandler)
|
||||||
from urllib.parse import urlparse, parse_qs
|
|
||||||
from socketserver import (ThreadingUDPServer, DatagramRequestHandler,
|
|
||||||
ThreadingTCPServer, StreamRequestHandler)
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
try:
|
try:
|
||||||
import win32evtlog, win32evtlogutil, pywintypes
|
import win32evtlog, win32evtlogutil, pywintypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -625,7 +622,6 @@ class HandlerTest(BaseTest):
|
||||||
os.unlink(fn)
|
os.unlink(fn)
|
||||||
|
|
||||||
@unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.')
|
@unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.')
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_race(self):
|
def test_race(self):
|
||||||
# Issue #14632 refers.
|
# Issue #14632 refers.
|
||||||
def remove_loop(fname, tries):
|
def remove_loop(fname, tries):
|
||||||
|
@ -719,276 +715,274 @@ class StreamHandlerTest(BaseTest):
|
||||||
# -- The following section could be moved into a server_helper.py module
|
# -- The following section could be moved into a server_helper.py module
|
||||||
# -- if it proves to be of wider utility than just test_logging
|
# -- if it proves to be of wider utility than just test_logging
|
||||||
|
|
||||||
if threading:
|
class TestSMTPServer(smtpd.SMTPServer):
|
||||||
class TestSMTPServer(smtpd.SMTPServer):
|
"""
|
||||||
"""
|
This class implements a test SMTP server.
|
||||||
This class implements a test SMTP server.
|
|
||||||
|
|
||||||
:param addr: A (host, port) tuple which the server listens on.
|
:param addr: A (host, port) tuple which the server listens on.
|
||||||
You can specify a port value of zero: the server's
|
You can specify a port value of zero: the server's
|
||||||
*port* attribute will hold the actual port number
|
*port* attribute will hold the actual port number
|
||||||
used, which can be used in client connections.
|
used, which can be used in client connections.
|
||||||
:param handler: A callable which will be called to process
|
:param handler: A callable which will be called to process
|
||||||
incoming messages. The handler will be passed
|
incoming messages. The handler will be passed
|
||||||
the client address tuple, who the message is from,
|
the client address tuple, who the message is from,
|
||||||
a list of recipients and the message data.
|
a list of recipients and the message data.
|
||||||
|
:param poll_interval: The interval, in seconds, used in the underlying
|
||||||
|
:func:`select` or :func:`poll` call by
|
||||||
|
:func:`asyncore.loop`.
|
||||||
|
:param sockmap: A dictionary which will be used to hold
|
||||||
|
:class:`asyncore.dispatcher` instances used by
|
||||||
|
:func:`asyncore.loop`. This avoids changing the
|
||||||
|
:mod:`asyncore` module's global state.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, addr, handler, poll_interval, sockmap):
|
||||||
|
smtpd.SMTPServer.__init__(self, addr, None, map=sockmap,
|
||||||
|
decode_data=True)
|
||||||
|
self.port = self.socket.getsockname()[1]
|
||||||
|
self._handler = handler
|
||||||
|
self._thread = None
|
||||||
|
self.poll_interval = poll_interval
|
||||||
|
|
||||||
|
def process_message(self, peer, mailfrom, rcpttos, data):
|
||||||
|
"""
|
||||||
|
Delegates to the handler passed in to the server's constructor.
|
||||||
|
|
||||||
|
Typically, this will be a test case method.
|
||||||
|
:param peer: The client (host, port) tuple.
|
||||||
|
:param mailfrom: The address of the sender.
|
||||||
|
:param rcpttos: The addresses of the recipients.
|
||||||
|
:param data: The message.
|
||||||
|
"""
|
||||||
|
self._handler(peer, mailfrom, rcpttos, data)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""
|
||||||
|
Start the server running on a separate daemon thread.
|
||||||
|
"""
|
||||||
|
self._thread = t = threading.Thread(target=self.serve_forever,
|
||||||
|
args=(self.poll_interval,))
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
def serve_forever(self, poll_interval):
|
||||||
|
"""
|
||||||
|
Run the :mod:`asyncore` loop until normal termination
|
||||||
|
conditions arise.
|
||||||
:param poll_interval: The interval, in seconds, used in the underlying
|
:param poll_interval: The interval, in seconds, used in the underlying
|
||||||
:func:`select` or :func:`poll` call by
|
:func:`select` or :func:`poll` call by
|
||||||
:func:`asyncore.loop`.
|
:func:`asyncore.loop`.
|
||||||
:param sockmap: A dictionary which will be used to hold
|
|
||||||
:class:`asyncore.dispatcher` instances used by
|
|
||||||
:func:`asyncore.loop`. This avoids changing the
|
|
||||||
:mod:`asyncore` module's global state.
|
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
asyncore.loop(poll_interval, map=self._map)
|
||||||
|
except OSError:
|
||||||
|
# On FreeBSD 8, closing the server repeatably
|
||||||
|
# raises this error. We swallow it if the
|
||||||
|
# server has been closed.
|
||||||
|
if self.connected or self.accepting:
|
||||||
|
raise
|
||||||
|
|
||||||
def __init__(self, addr, handler, poll_interval, sockmap):
|
def stop(self, timeout=None):
|
||||||
smtpd.SMTPServer.__init__(self, addr, None, map=sockmap,
|
"""
|
||||||
decode_data=True)
|
Stop the thread by closing the server instance.
|
||||||
self.port = self.socket.getsockname()[1]
|
Wait for the server thread to terminate.
|
||||||
self._handler = handler
|
|
||||||
self._thread = None
|
|
||||||
self.poll_interval = poll_interval
|
|
||||||
|
|
||||||
def process_message(self, peer, mailfrom, rcpttos, data):
|
:param timeout: How long to wait for the server thread
|
||||||
"""
|
to terminate.
|
||||||
Delegates to the handler passed in to the server's constructor.
|
"""
|
||||||
|
self.close()
|
||||||
|
self._thread.join(timeout)
|
||||||
|
asyncore.close_all(map=self._map, ignore_all=True)
|
||||||
|
|
||||||
Typically, this will be a test case method.
|
alive = self._thread.is_alive()
|
||||||
:param peer: The client (host, port) tuple.
|
self._thread = None
|
||||||
:param mailfrom: The address of the sender.
|
if alive:
|
||||||
:param rcpttos: The addresses of the recipients.
|
self.fail("join() timed out")
|
||||||
:param data: The message.
|
|
||||||
"""
|
|
||||||
self._handler(peer, mailfrom, rcpttos, data)
|
|
||||||
|
|
||||||
def start(self):
|
class ControlMixin(object):
|
||||||
"""
|
"""
|
||||||
Start the server running on a separate daemon thread.
|
This mixin is used to start a server on a separate thread, and
|
||||||
"""
|
shut it down programmatically. Request handling is simplified - instead
|
||||||
self._thread = t = threading.Thread(target=self.serve_forever,
|
of needing to derive a suitable RequestHandler subclass, you just
|
||||||
args=(self.poll_interval,))
|
provide a callable which will be passed each received request to be
|
||||||
t.setDaemon(True)
|
processed.
|
||||||
t.start()
|
|
||||||
|
|
||||||
def serve_forever(self, poll_interval):
|
:param handler: A handler callable which will be called with a
|
||||||
"""
|
single parameter - the request - in order to
|
||||||
Run the :mod:`asyncore` loop until normal termination
|
process the request. This handler is called on the
|
||||||
conditions arise.
|
server thread, effectively meaning that requests are
|
||||||
:param poll_interval: The interval, in seconds, used in the underlying
|
processed serially. While not quite Web scale ;-),
|
||||||
:func:`select` or :func:`poll` call by
|
this should be fine for testing applications.
|
||||||
:func:`asyncore.loop`.
|
:param poll_interval: The polling interval in seconds.
|
||||||
"""
|
"""
|
||||||
try:
|
def __init__(self, handler, poll_interval):
|
||||||
asyncore.loop(poll_interval, map=self._map)
|
self._thread = None
|
||||||
except OSError:
|
self.poll_interval = poll_interval
|
||||||
# On FreeBSD 8, closing the server repeatably
|
self._handler = handler
|
||||||
# raises this error. We swallow it if the
|
self.ready = threading.Event()
|
||||||
# server has been closed.
|
|
||||||
if self.connected or self.accepting:
|
|
||||||
raise
|
|
||||||
|
|
||||||
def stop(self, timeout=None):
|
def start(self):
|
||||||
"""
|
"""
|
||||||
Stop the thread by closing the server instance.
|
Create a daemon thread to run the server, and start it.
|
||||||
Wait for the server thread to terminate.
|
"""
|
||||||
|
self._thread = t = threading.Thread(target=self.serve_forever,
|
||||||
|
args=(self.poll_interval,))
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
:param timeout: How long to wait for the server thread
|
def serve_forever(self, poll_interval):
|
||||||
to terminate.
|
"""
|
||||||
"""
|
Run the server. Set the ready flag before entering the
|
||||||
self.close()
|
service loop.
|
||||||
|
"""
|
||||||
|
self.ready.set()
|
||||||
|
super(ControlMixin, self).serve_forever(poll_interval)
|
||||||
|
|
||||||
|
def stop(self, timeout=None):
|
||||||
|
"""
|
||||||
|
Tell the server thread to stop, and wait for it to do so.
|
||||||
|
|
||||||
|
:param timeout: How long to wait for the server thread
|
||||||
|
to terminate.
|
||||||
|
"""
|
||||||
|
self.shutdown()
|
||||||
|
if self._thread is not None:
|
||||||
self._thread.join(timeout)
|
self._thread.join(timeout)
|
||||||
asyncore.close_all(map=self._map, ignore_all=True)
|
|
||||||
|
|
||||||
alive = self._thread.is_alive()
|
alive = self._thread.is_alive()
|
||||||
self._thread = None
|
self._thread = None
|
||||||
if alive:
|
if alive:
|
||||||
self.fail("join() timed out")
|
self.fail("join() timed out")
|
||||||
|
self.server_close()
|
||||||
|
self.ready.clear()
|
||||||
|
|
||||||
class ControlMixin(object):
|
class TestHTTPServer(ControlMixin, HTTPServer):
|
||||||
"""
|
"""
|
||||||
This mixin is used to start a server on a separate thread, and
|
An HTTP server which is controllable using :class:`ControlMixin`.
|
||||||
shut it down programmatically. Request handling is simplified - instead
|
|
||||||
of needing to derive a suitable RequestHandler subclass, you just
|
|
||||||
provide a callable which will be passed each received request to be
|
|
||||||
processed.
|
|
||||||
|
|
||||||
:param handler: A handler callable which will be called with a
|
:param addr: A tuple with the IP address and port to listen on.
|
||||||
single parameter - the request - in order to
|
:param handler: A handler callable which will be called with a
|
||||||
process the request. This handler is called on the
|
single parameter - the request - in order to
|
||||||
server thread, effectively meaning that requests are
|
process the request.
|
||||||
processed serially. While not quite Web scale ;-),
|
:param poll_interval: The polling interval in seconds.
|
||||||
this should be fine for testing applications.
|
:param log: Pass ``True`` to enable log messages.
|
||||||
:param poll_interval: The polling interval in seconds.
|
"""
|
||||||
"""
|
def __init__(self, addr, handler, poll_interval=0.5,
|
||||||
def __init__(self, handler, poll_interval):
|
log=False, sslctx=None):
|
||||||
self._thread = None
|
class DelegatingHTTPRequestHandler(BaseHTTPRequestHandler):
|
||||||
self.poll_interval = poll_interval
|
def __getattr__(self, name, default=None):
|
||||||
self._handler = handler
|
if name.startswith('do_'):
|
||||||
self.ready = threading.Event()
|
return self.process_request
|
||||||
|
raise AttributeError(name)
|
||||||
|
|
||||||
def start(self):
|
def process_request(self):
|
||||||
"""
|
self.server._handler(self)
|
||||||
Create a daemon thread to run the server, and start it.
|
|
||||||
"""
|
|
||||||
self._thread = t = threading.Thread(target=self.serve_forever,
|
|
||||||
args=(self.poll_interval,))
|
|
||||||
t.setDaemon(True)
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
def serve_forever(self, poll_interval):
|
def log_message(self, format, *args):
|
||||||
"""
|
if log:
|
||||||
Run the server. Set the ready flag before entering the
|
super(DelegatingHTTPRequestHandler,
|
||||||
service loop.
|
self).log_message(format, *args)
|
||||||
"""
|
HTTPServer.__init__(self, addr, DelegatingHTTPRequestHandler)
|
||||||
self.ready.set()
|
ControlMixin.__init__(self, handler, poll_interval)
|
||||||
super(ControlMixin, self).serve_forever(poll_interval)
|
self.sslctx = sslctx
|
||||||
|
|
||||||
def stop(self, timeout=None):
|
def get_request(self):
|
||||||
"""
|
try:
|
||||||
Tell the server thread to stop, and wait for it to do so.
|
sock, addr = self.socket.accept()
|
||||||
|
if self.sslctx:
|
||||||
|
sock = self.sslctx.wrap_socket(sock, server_side=True)
|
||||||
|
except OSError as e:
|
||||||
|
# socket errors are silenced by the caller, print them here
|
||||||
|
sys.stderr.write("Got an error:\n%s\n" % e)
|
||||||
|
raise
|
||||||
|
return sock, addr
|
||||||
|
|
||||||
:param timeout: How long to wait for the server thread
|
class TestTCPServer(ControlMixin, ThreadingTCPServer):
|
||||||
to terminate.
|
"""
|
||||||
"""
|
A TCP server which is controllable using :class:`ControlMixin`.
|
||||||
self.shutdown()
|
|
||||||
if self._thread is not None:
|
|
||||||
self._thread.join(timeout)
|
|
||||||
alive = self._thread.is_alive()
|
|
||||||
self._thread = None
|
|
||||||
if alive:
|
|
||||||
self.fail("join() timed out")
|
|
||||||
self.server_close()
|
|
||||||
self.ready.clear()
|
|
||||||
|
|
||||||
class TestHTTPServer(ControlMixin, HTTPServer):
|
:param addr: A tuple with the IP address and port to listen on.
|
||||||
"""
|
:param handler: A handler callable which will be called with a single
|
||||||
An HTTP server which is controllable using :class:`ControlMixin`.
|
parameter - the request - in order to process the request.
|
||||||
|
:param poll_interval: The polling interval in seconds.
|
||||||
|
:bind_and_activate: If True (the default), binds the server and starts it
|
||||||
|
listening. If False, you need to call
|
||||||
|
:meth:`server_bind` and :meth:`server_activate` at
|
||||||
|
some later time before calling :meth:`start`, so that
|
||||||
|
the server will set up the socket and listen on it.
|
||||||
|
"""
|
||||||
|
|
||||||
:param addr: A tuple with the IP address and port to listen on.
|
allow_reuse_address = True
|
||||||
:param handler: A handler callable which will be called with a
|
|
||||||
single parameter - the request - in order to
|
|
||||||
process the request.
|
|
||||||
:param poll_interval: The polling interval in seconds.
|
|
||||||
:param log: Pass ``True`` to enable log messages.
|
|
||||||
"""
|
|
||||||
def __init__(self, addr, handler, poll_interval=0.5,
|
|
||||||
log=False, sslctx=None):
|
|
||||||
class DelegatingHTTPRequestHandler(BaseHTTPRequestHandler):
|
|
||||||
def __getattr__(self, name, default=None):
|
|
||||||
if name.startswith('do_'):
|
|
||||||
return self.process_request
|
|
||||||
raise AttributeError(name)
|
|
||||||
|
|
||||||
def process_request(self):
|
def __init__(self, addr, handler, poll_interval=0.5,
|
||||||
self.server._handler(self)
|
bind_and_activate=True):
|
||||||
|
class DelegatingTCPRequestHandler(StreamRequestHandler):
|
||||||
|
|
||||||
def log_message(self, format, *args):
|
def handle(self):
|
||||||
if log:
|
self.server._handler(self)
|
||||||
super(DelegatingHTTPRequestHandler,
|
ThreadingTCPServer.__init__(self, addr, DelegatingTCPRequestHandler,
|
||||||
self).log_message(format, *args)
|
bind_and_activate)
|
||||||
HTTPServer.__init__(self, addr, DelegatingHTTPRequestHandler)
|
ControlMixin.__init__(self, handler, poll_interval)
|
||||||
ControlMixin.__init__(self, handler, poll_interval)
|
|
||||||
self.sslctx = sslctx
|
|
||||||
|
|
||||||
def get_request(self):
|
def server_bind(self):
|
||||||
try:
|
super(TestTCPServer, self).server_bind()
|
||||||
sock, addr = self.socket.accept()
|
self.port = self.socket.getsockname()[1]
|
||||||
if self.sslctx:
|
|
||||||
sock = self.sslctx.wrap_socket(sock, server_side=True)
|
|
||||||
except OSError as e:
|
|
||||||
# socket errors are silenced by the caller, print them here
|
|
||||||
sys.stderr.write("Got an error:\n%s\n" % e)
|
|
||||||
raise
|
|
||||||
return sock, addr
|
|
||||||
|
|
||||||
class TestTCPServer(ControlMixin, ThreadingTCPServer):
|
class TestUDPServer(ControlMixin, ThreadingUDPServer):
|
||||||
"""
|
"""
|
||||||
A TCP server which is controllable using :class:`ControlMixin`.
|
A UDP server which is controllable using :class:`ControlMixin`.
|
||||||
|
|
||||||
:param addr: A tuple with the IP address and port to listen on.
|
:param addr: A tuple with the IP address and port to listen on.
|
||||||
:param handler: A handler callable which will be called with a single
|
:param handler: A handler callable which will be called with a
|
||||||
parameter - the request - in order to process the request.
|
single parameter - the request - in order to
|
||||||
:param poll_interval: The polling interval in seconds.
|
process the request.
|
||||||
:bind_and_activate: If True (the default), binds the server and starts it
|
:param poll_interval: The polling interval for shutdown requests,
|
||||||
listening. If False, you need to call
|
in seconds.
|
||||||
:meth:`server_bind` and :meth:`server_activate` at
|
:bind_and_activate: If True (the default), binds the server and
|
||||||
some later time before calling :meth:`start`, so that
|
starts it listening. If False, you need to
|
||||||
the server will set up the socket and listen on it.
|
call :meth:`server_bind` and
|
||||||
"""
|
:meth:`server_activate` at some later time
|
||||||
|
before calling :meth:`start`, so that the server will
|
||||||
|
set up the socket and listen on it.
|
||||||
|
"""
|
||||||
|
def __init__(self, addr, handler, poll_interval=0.5,
|
||||||
|
bind_and_activate=True):
|
||||||
|
class DelegatingUDPRequestHandler(DatagramRequestHandler):
|
||||||
|
|
||||||
allow_reuse_address = True
|
def handle(self):
|
||||||
|
self.server._handler(self)
|
||||||
|
|
||||||
def __init__(self, addr, handler, poll_interval=0.5,
|
def finish(self):
|
||||||
bind_and_activate=True):
|
data = self.wfile.getvalue()
|
||||||
class DelegatingTCPRequestHandler(StreamRequestHandler):
|
if data:
|
||||||
|
try:
|
||||||
|
super(DelegatingUDPRequestHandler, self).finish()
|
||||||
|
except OSError:
|
||||||
|
if not self.server._closed:
|
||||||
|
raise
|
||||||
|
|
||||||
def handle(self):
|
ThreadingUDPServer.__init__(self, addr,
|
||||||
self.server._handler(self)
|
DelegatingUDPRequestHandler,
|
||||||
ThreadingTCPServer.__init__(self, addr, DelegatingTCPRequestHandler,
|
bind_and_activate)
|
||||||
bind_and_activate)
|
ControlMixin.__init__(self, handler, poll_interval)
|
||||||
ControlMixin.__init__(self, handler, poll_interval)
|
self._closed = False
|
||||||
|
|
||||||
def server_bind(self):
|
def server_bind(self):
|
||||||
super(TestTCPServer, self).server_bind()
|
super(TestUDPServer, self).server_bind()
|
||||||
self.port = self.socket.getsockname()[1]
|
self.port = self.socket.getsockname()[1]
|
||||||
|
|
||||||
class TestUDPServer(ControlMixin, ThreadingUDPServer):
|
def server_close(self):
|
||||||
"""
|
super(TestUDPServer, self).server_close()
|
||||||
A UDP server which is controllable using :class:`ControlMixin`.
|
self._closed = True
|
||||||
|
|
||||||
:param addr: A tuple with the IP address and port to listen on.
|
if hasattr(socket, "AF_UNIX"):
|
||||||
:param handler: A handler callable which will be called with a
|
class TestUnixStreamServer(TestTCPServer):
|
||||||
single parameter - the request - in order to
|
address_family = socket.AF_UNIX
|
||||||
process the request.
|
|
||||||
:param poll_interval: The polling interval for shutdown requests,
|
|
||||||
in seconds.
|
|
||||||
:bind_and_activate: If True (the default), binds the server and
|
|
||||||
starts it listening. If False, you need to
|
|
||||||
call :meth:`server_bind` and
|
|
||||||
:meth:`server_activate` at some later time
|
|
||||||
before calling :meth:`start`, so that the server will
|
|
||||||
set up the socket and listen on it.
|
|
||||||
"""
|
|
||||||
def __init__(self, addr, handler, poll_interval=0.5,
|
|
||||||
bind_and_activate=True):
|
|
||||||
class DelegatingUDPRequestHandler(DatagramRequestHandler):
|
|
||||||
|
|
||||||
def handle(self):
|
class TestUnixDatagramServer(TestUDPServer):
|
||||||
self.server._handler(self)
|
address_family = socket.AF_UNIX
|
||||||
|
|
||||||
def finish(self):
|
|
||||||
data = self.wfile.getvalue()
|
|
||||||
if data:
|
|
||||||
try:
|
|
||||||
super(DelegatingUDPRequestHandler, self).finish()
|
|
||||||
except OSError:
|
|
||||||
if not self.server._closed:
|
|
||||||
raise
|
|
||||||
|
|
||||||
ThreadingUDPServer.__init__(self, addr,
|
|
||||||
DelegatingUDPRequestHandler,
|
|
||||||
bind_and_activate)
|
|
||||||
ControlMixin.__init__(self, handler, poll_interval)
|
|
||||||
self._closed = False
|
|
||||||
|
|
||||||
def server_bind(self):
|
|
||||||
super(TestUDPServer, self).server_bind()
|
|
||||||
self.port = self.socket.getsockname()[1]
|
|
||||||
|
|
||||||
def server_close(self):
|
|
||||||
super(TestUDPServer, self).server_close()
|
|
||||||
self._closed = True
|
|
||||||
|
|
||||||
if hasattr(socket, "AF_UNIX"):
|
|
||||||
class TestUnixStreamServer(TestTCPServer):
|
|
||||||
address_family = socket.AF_UNIX
|
|
||||||
|
|
||||||
class TestUnixDatagramServer(TestUDPServer):
|
|
||||||
address_family = socket.AF_UNIX
|
|
||||||
|
|
||||||
# - end of server_helper section
|
# - end of server_helper section
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class SMTPHandlerTest(BaseTest):
|
class SMTPHandlerTest(BaseTest):
|
||||||
TIMEOUT = 8.0
|
TIMEOUT = 8.0
|
||||||
|
|
||||||
|
@ -1472,14 +1466,12 @@ class ConfigFileTest(BaseTest):
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(True, "FIXME: bpo-30830")
|
@unittest.skipIf(True, "FIXME: bpo-30830")
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class SocketHandlerTest(BaseTest):
|
class SocketHandlerTest(BaseTest):
|
||||||
|
|
||||||
"""Test for SocketHandler objects."""
|
"""Test for SocketHandler objects."""
|
||||||
|
|
||||||
if threading:
|
server_class = TestTCPServer
|
||||||
server_class = TestTCPServer
|
address = ('localhost', 0)
|
||||||
address = ('localhost', 0)
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Set up a TCP server to receive log messages, and a SocketHandler
|
"""Set up a TCP server to receive log messages, and a SocketHandler
|
||||||
|
@ -1573,12 +1565,11 @@ def _get_temp_domain_socket():
|
||||||
|
|
||||||
@unittest.skipIf(True, "FIXME: bpo-30830")
|
@unittest.skipIf(True, "FIXME: bpo-30830")
|
||||||
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
|
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class UnixSocketHandlerTest(SocketHandlerTest):
|
class UnixSocketHandlerTest(SocketHandlerTest):
|
||||||
|
|
||||||
"""Test for SocketHandler with unix sockets."""
|
"""Test for SocketHandler with unix sockets."""
|
||||||
|
|
||||||
if threading and hasattr(socket, "AF_UNIX"):
|
if hasattr(socket, "AF_UNIX"):
|
||||||
server_class = TestUnixStreamServer
|
server_class = TestUnixStreamServer
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -1591,14 +1582,12 @@ class UnixSocketHandlerTest(SocketHandlerTest):
|
||||||
support.unlink(self.address)
|
support.unlink(self.address)
|
||||||
|
|
||||||
@unittest.skipIf(True, "FIXME: bpo-30830")
|
@unittest.skipIf(True, "FIXME: bpo-30830")
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class DatagramHandlerTest(BaseTest):
|
class DatagramHandlerTest(BaseTest):
|
||||||
|
|
||||||
"""Test for DatagramHandler."""
|
"""Test for DatagramHandler."""
|
||||||
|
|
||||||
if threading:
|
server_class = TestUDPServer
|
||||||
server_class = TestUDPServer
|
address = ('localhost', 0)
|
||||||
address = ('localhost', 0)
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Set up a UDP server to receive log messages, and a DatagramHandler
|
"""Set up a UDP server to receive log messages, and a DatagramHandler
|
||||||
|
@ -1659,12 +1648,11 @@ class DatagramHandlerTest(BaseTest):
|
||||||
|
|
||||||
@unittest.skipIf(True, "FIXME: bpo-30830")
|
@unittest.skipIf(True, "FIXME: bpo-30830")
|
||||||
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
|
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class UnixDatagramHandlerTest(DatagramHandlerTest):
|
class UnixDatagramHandlerTest(DatagramHandlerTest):
|
||||||
|
|
||||||
"""Test for DatagramHandler using Unix sockets."""
|
"""Test for DatagramHandler using Unix sockets."""
|
||||||
|
|
||||||
if threading and hasattr(socket, "AF_UNIX"):
|
if hasattr(socket, "AF_UNIX"):
|
||||||
server_class = TestUnixDatagramServer
|
server_class = TestUnixDatagramServer
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -1676,14 +1664,12 @@ class UnixDatagramHandlerTest(DatagramHandlerTest):
|
||||||
DatagramHandlerTest.tearDown(self)
|
DatagramHandlerTest.tearDown(self)
|
||||||
support.unlink(self.address)
|
support.unlink(self.address)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class SysLogHandlerTest(BaseTest):
|
class SysLogHandlerTest(BaseTest):
|
||||||
|
|
||||||
"""Test for SysLogHandler using UDP."""
|
"""Test for SysLogHandler using UDP."""
|
||||||
|
|
||||||
if threading:
|
server_class = TestUDPServer
|
||||||
server_class = TestUDPServer
|
address = ('localhost', 0)
|
||||||
address = ('localhost', 0)
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Set up a UDP server to receive log messages, and a SysLogHandler
|
"""Set up a UDP server to receive log messages, and a SysLogHandler
|
||||||
|
@ -1747,12 +1733,11 @@ class SysLogHandlerTest(BaseTest):
|
||||||
|
|
||||||
@unittest.skipIf(True, "FIXME: bpo-30830")
|
@unittest.skipIf(True, "FIXME: bpo-30830")
|
||||||
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
|
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class UnixSysLogHandlerTest(SysLogHandlerTest):
|
class UnixSysLogHandlerTest(SysLogHandlerTest):
|
||||||
|
|
||||||
"""Test for SysLogHandler with Unix sockets."""
|
"""Test for SysLogHandler with Unix sockets."""
|
||||||
|
|
||||||
if threading and hasattr(socket, "AF_UNIX"):
|
if hasattr(socket, "AF_UNIX"):
|
||||||
server_class = TestUnixDatagramServer
|
server_class = TestUnixDatagramServer
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -1767,7 +1752,6 @@ class UnixSysLogHandlerTest(SysLogHandlerTest):
|
||||||
@unittest.skipIf(True, "FIXME: bpo-30830")
|
@unittest.skipIf(True, "FIXME: bpo-30830")
|
||||||
@unittest.skipUnless(support.IPV6_ENABLED,
|
@unittest.skipUnless(support.IPV6_ENABLED,
|
||||||
'IPv6 support required for this test.')
|
'IPv6 support required for this test.')
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class IPv6SysLogHandlerTest(SysLogHandlerTest):
|
class IPv6SysLogHandlerTest(SysLogHandlerTest):
|
||||||
|
|
||||||
"""Test for SysLogHandler with IPv6 host."""
|
"""Test for SysLogHandler with IPv6 host."""
|
||||||
|
@ -1783,7 +1767,6 @@ class IPv6SysLogHandlerTest(SysLogHandlerTest):
|
||||||
self.server_class.address_family = socket.AF_INET
|
self.server_class.address_family = socket.AF_INET
|
||||||
super(IPv6SysLogHandlerTest, self).tearDown()
|
super(IPv6SysLogHandlerTest, self).tearDown()
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class HTTPHandlerTest(BaseTest):
|
class HTTPHandlerTest(BaseTest):
|
||||||
"""Test for HTTPHandler."""
|
"""Test for HTTPHandler."""
|
||||||
|
|
||||||
|
@ -2892,7 +2875,6 @@ class ConfigDictTest(BaseTest):
|
||||||
# listen() uses ConfigSocketReceiver which is based
|
# listen() uses ConfigSocketReceiver which is based
|
||||||
# on socketserver.ThreadingTCPServer
|
# on socketserver.ThreadingTCPServer
|
||||||
@unittest.skipIf(True, "FIXME: bpo-30830")
|
@unittest.skipIf(True, "FIXME: bpo-30830")
|
||||||
@unittest.skipUnless(threading, 'listen() needs threading to work')
|
|
||||||
def setup_via_listener(self, text, verify=None):
|
def setup_via_listener(self, text, verify=None):
|
||||||
text = text.encode("utf-8")
|
text = text.encode("utf-8")
|
||||||
# Ask for a randomly assigned port (by using port 0)
|
# Ask for a randomly assigned port (by using port 0)
|
||||||
|
@ -2923,7 +2905,6 @@ class ConfigDictTest(BaseTest):
|
||||||
if t.is_alive():
|
if t.is_alive():
|
||||||
self.fail("join() timed out")
|
self.fail("join() timed out")
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_listen_config_10_ok(self):
|
def test_listen_config_10_ok(self):
|
||||||
with support.captured_stdout() as output:
|
with support.captured_stdout() as output:
|
||||||
self.setup_via_listener(json.dumps(self.config10))
|
self.setup_via_listener(json.dumps(self.config10))
|
||||||
|
@ -2943,7 +2924,6 @@ class ConfigDictTest(BaseTest):
|
||||||
('ERROR', '4'),
|
('ERROR', '4'),
|
||||||
], stream=output)
|
], stream=output)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_listen_config_1_ok(self):
|
def test_listen_config_1_ok(self):
|
||||||
with support.captured_stdout() as output:
|
with support.captured_stdout() as output:
|
||||||
self.setup_via_listener(textwrap.dedent(ConfigFileTest.config1))
|
self.setup_via_listener(textwrap.dedent(ConfigFileTest.config1))
|
||||||
|
@ -2958,7 +2938,6 @@ class ConfigDictTest(BaseTest):
|
||||||
# Original logger output is empty.
|
# Original logger output is empty.
|
||||||
self.assert_log_lines([])
|
self.assert_log_lines([])
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_listen_verify(self):
|
def test_listen_verify(self):
|
||||||
|
|
||||||
def verify_fail(stuff):
|
def verify_fail(stuff):
|
||||||
|
@ -3713,9 +3692,8 @@ class LogRecordTest(BaseTest):
|
||||||
def test_optional(self):
|
def test_optional(self):
|
||||||
r = logging.makeLogRecord({})
|
r = logging.makeLogRecord({})
|
||||||
NOT_NONE = self.assertIsNotNone
|
NOT_NONE = self.assertIsNotNone
|
||||||
if threading:
|
NOT_NONE(r.thread)
|
||||||
NOT_NONE(r.thread)
|
NOT_NONE(r.threadName)
|
||||||
NOT_NONE(r.threadName)
|
|
||||||
NOT_NONE(r.process)
|
NOT_NONE(r.process)
|
||||||
NOT_NONE(r.processName)
|
NOT_NONE(r.processName)
|
||||||
log_threads = logging.logThreads
|
log_threads = logging.logThreads
|
||||||
|
|
|
@ -6,6 +6,8 @@ import unittest
|
||||||
import functools
|
import functools
|
||||||
import contextlib
|
import contextlib
|
||||||
import os.path
|
import os.path
|
||||||
|
import threading
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
from nntplib import NNTP, GroupInfo
|
from nntplib import NNTP, GroupInfo
|
||||||
import nntplib
|
import nntplib
|
||||||
|
@ -14,10 +16,7 @@ try:
|
||||||
import ssl
|
import ssl
|
||||||
except ImportError:
|
except ImportError:
|
||||||
ssl = None
|
ssl = None
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
TIMEOUT = 30
|
TIMEOUT = 30
|
||||||
certfile = os.path.join(os.path.dirname(__file__), 'keycert3.pem')
|
certfile = os.path.join(os.path.dirname(__file__), 'keycert3.pem')
|
||||||
|
@ -1520,7 +1519,7 @@ class MockSslTests(MockSocketTests):
|
||||||
def nntp_class(*pos, **kw):
|
def nntp_class(*pos, **kw):
|
||||||
return nntplib.NNTP_SSL(*pos, ssl_context=bypass_context, **kw)
|
return nntplib.NNTP_SSL(*pos, ssl_context=bypass_context, **kw)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'requires multithreading')
|
|
||||||
class LocalServerTests(unittest.TestCase):
|
class LocalServerTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
sock = socket.socket()
|
sock = socket.socket()
|
||||||
|
|
|
@ -22,15 +22,13 @@ import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
from test import support
|
from test import support
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
try:
|
try:
|
||||||
import resource
|
import resource
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -2516,92 +2514,90 @@ class ProgramPriorityTests(unittest.TestCase):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
if threading is not None:
|
class SendfileTestServer(asyncore.dispatcher, threading.Thread):
|
||||||
class SendfileTestServer(asyncore.dispatcher, threading.Thread):
|
|
||||||
|
|
||||||
class Handler(asynchat.async_chat):
|
class Handler(asynchat.async_chat):
|
||||||
|
|
||||||
def __init__(self, conn):
|
def __init__(self, conn):
|
||||||
asynchat.async_chat.__init__(self, conn)
|
asynchat.async_chat.__init__(self, conn)
|
||||||
self.in_buffer = []
|
self.in_buffer = []
|
||||||
self.closed = False
|
self.closed = False
|
||||||
self.push(b"220 ready\r\n")
|
self.push(b"220 ready\r\n")
|
||||||
|
|
||||||
def handle_read(self):
|
def handle_read(self):
|
||||||
data = self.recv(4096)
|
data = self.recv(4096)
|
||||||
self.in_buffer.append(data)
|
self.in_buffer.append(data)
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
return b''.join(self.in_buffer)
|
return b''.join(self.in_buffer)
|
||||||
|
|
||||||
def handle_close(self):
|
def handle_close(self):
|
||||||
self.close()
|
|
||||||
self.closed = True
|
|
||||||
|
|
||||||
def handle_error(self):
|
|
||||||
raise
|
|
||||||
|
|
||||||
def __init__(self, address):
|
|
||||||
threading.Thread.__init__(self)
|
|
||||||
asyncore.dispatcher.__init__(self)
|
|
||||||
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.bind(address)
|
|
||||||
self.listen(5)
|
|
||||||
self.host, self.port = self.socket.getsockname()[:2]
|
|
||||||
self.handler_instance = None
|
|
||||||
self._active = False
|
|
||||||
self._active_lock = threading.Lock()
|
|
||||||
|
|
||||||
# --- public API
|
|
||||||
|
|
||||||
@property
|
|
||||||
def running(self):
|
|
||||||
return self._active
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
assert not self.running
|
|
||||||
self.__flag = threading.Event()
|
|
||||||
threading.Thread.start(self)
|
|
||||||
self.__flag.wait()
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
assert self.running
|
|
||||||
self._active = False
|
|
||||||
self.join()
|
|
||||||
|
|
||||||
def wait(self):
|
|
||||||
# wait for handler connection to be closed, then stop the server
|
|
||||||
while not getattr(self.handler_instance, "closed", False):
|
|
||||||
time.sleep(0.001)
|
|
||||||
self.stop()
|
|
||||||
|
|
||||||
# --- internals
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self._active = True
|
|
||||||
self.__flag.set()
|
|
||||||
while self._active and asyncore.socket_map:
|
|
||||||
self._active_lock.acquire()
|
|
||||||
asyncore.loop(timeout=0.001, count=1)
|
|
||||||
self._active_lock.release()
|
|
||||||
asyncore.close_all()
|
|
||||||
|
|
||||||
def handle_accept(self):
|
|
||||||
conn, addr = self.accept()
|
|
||||||
self.handler_instance = self.Handler(conn)
|
|
||||||
|
|
||||||
def handle_connect(self):
|
|
||||||
self.close()
|
self.close()
|
||||||
handle_read = handle_connect
|
self.closed = True
|
||||||
|
|
||||||
def writable(self):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def handle_error(self):
|
def handle_error(self):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def __init__(self, address):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
asyncore.dispatcher.__init__(self)
|
||||||
|
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.bind(address)
|
||||||
|
self.listen(5)
|
||||||
|
self.host, self.port = self.socket.getsockname()[:2]
|
||||||
|
self.handler_instance = None
|
||||||
|
self._active = False
|
||||||
|
self._active_lock = threading.Lock()
|
||||||
|
|
||||||
|
# --- public API
|
||||||
|
|
||||||
|
@property
|
||||||
|
def running(self):
|
||||||
|
return self._active
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
assert not self.running
|
||||||
|
self.__flag = threading.Event()
|
||||||
|
threading.Thread.start(self)
|
||||||
|
self.__flag.wait()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
assert self.running
|
||||||
|
self._active = False
|
||||||
|
self.join()
|
||||||
|
|
||||||
|
def wait(self):
|
||||||
|
# wait for handler connection to be closed, then stop the server
|
||||||
|
while not getattr(self.handler_instance, "closed", False):
|
||||||
|
time.sleep(0.001)
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
# --- internals
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self._active = True
|
||||||
|
self.__flag.set()
|
||||||
|
while self._active and asyncore.socket_map:
|
||||||
|
self._active_lock.acquire()
|
||||||
|
asyncore.loop(timeout=0.001, count=1)
|
||||||
|
self._active_lock.release()
|
||||||
|
asyncore.close_all()
|
||||||
|
|
||||||
|
def handle_accept(self):
|
||||||
|
conn, addr = self.accept()
|
||||||
|
self.handler_instance = self.Handler(conn)
|
||||||
|
|
||||||
|
def handle_connect(self):
|
||||||
|
self.close()
|
||||||
|
handle_read = handle_connect
|
||||||
|
|
||||||
|
def writable(self):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def handle_error(self):
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading is not None, "test needs threading module")
|
|
||||||
@unittest.skipUnless(hasattr(os, 'sendfile'), "test needs os.sendfile()")
|
@unittest.skipUnless(hasattr(os, 'sendfile'), "test needs os.sendfile()")
|
||||||
class TestSendfile(unittest.TestCase):
|
class TestSendfile(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -1040,9 +1040,6 @@ class PdbTestCase(unittest.TestCase):
|
||||||
# invoking "continue" on a non-main thread triggered an exception
|
# invoking "continue" on a non-main thread triggered an exception
|
||||||
# inside signal.signal
|
# inside signal.signal
|
||||||
|
|
||||||
# raises SkipTest if python was built without threads
|
|
||||||
support.import_module('threading')
|
|
||||||
|
|
||||||
with open(support.TESTFN, 'wb') as f:
|
with open(support.TESTFN, 'wb') as f:
|
||||||
f.write(textwrap.dedent("""
|
f.write(textwrap.dedent("""
|
||||||
import threading
|
import threading
|
||||||
|
|
|
@ -4,10 +4,7 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import random
|
import random
|
||||||
import select
|
import select
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
from test.support import TESTFN, run_unittest, reap_threads, cpython_only
|
from test.support import TESTFN, run_unittest, reap_threads, cpython_only
|
||||||
|
@ -179,7 +176,6 @@ class PollTests(unittest.TestCase):
|
||||||
self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1)
|
self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1)
|
||||||
self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1)
|
self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
@reap_threads
|
@reap_threads
|
||||||
def test_threaded_poll(self):
|
def test_threaded_poll(self):
|
||||||
r, w = os.pipe()
|
r, w = os.pipe()
|
||||||
|
|
|
@ -9,10 +9,10 @@ import asynchat
|
||||||
import socket
|
import socket
|
||||||
import os
|
import os
|
||||||
import errno
|
import errno
|
||||||
|
import threading
|
||||||
|
|
||||||
from unittest import TestCase, skipUnless
|
from unittest import TestCase, skipUnless
|
||||||
from test import support as test_support
|
from test import support as test_support
|
||||||
threading = test_support.import_module('threading')
|
|
||||||
|
|
||||||
HOST = test_support.HOST
|
HOST = test_support.HOST
|
||||||
PORT = 0
|
PORT = 0
|
||||||
|
|
|
@ -20,6 +20,7 @@ import urllib.parse
|
||||||
import xml.etree
|
import xml.etree
|
||||||
import xml.etree.ElementTree
|
import xml.etree.ElementTree
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import threading
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from test.support.script_helper import assert_python_ok
|
from test.support.script_helper import assert_python_ok
|
||||||
|
@ -30,10 +31,6 @@ from test.support import (
|
||||||
)
|
)
|
||||||
from test import pydoc_mod
|
from test import pydoc_mod
|
||||||
|
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
class nonascii:
|
class nonascii:
|
||||||
'Це не латиниця'
|
'Це не латиниця'
|
||||||
|
@ -902,7 +899,6 @@ class TestDescriptions(unittest.TestCase):
|
||||||
"stat(path, *, dir_fd=None, follow_symlinks=True)")
|
"stat(path, *, dir_fd=None, follow_symlinks=True)")
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class PydocServerTest(unittest.TestCase):
|
class PydocServerTest(unittest.TestCase):
|
||||||
"""Tests for pydoc._start_server"""
|
"""Tests for pydoc._start_server"""
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
# Some simple queue module tests, plus some failure conditions
|
# Some simple queue module tests, plus some failure conditions
|
||||||
# to ensure the Queue locks remain stable.
|
# to ensure the Queue locks remain stable.
|
||||||
import queue
|
import queue
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
from test import support
|
from test import support
|
||||||
threading = support.import_module('threading')
|
|
||||||
|
|
||||||
QUEUE_SIZE = 5
|
QUEUE_SIZE = 5
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import tempfile
|
import tempfile
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
from test import libregrtest
|
from test import libregrtest
|
||||||
from test import support
|
from test import support
|
||||||
|
@ -741,12 +742,7 @@ class ArgsTestCase(BaseTestCase):
|
||||||
code = TEST_INTERRUPTED
|
code = TEST_INTERRUPTED
|
||||||
test = self.create_test("sigint", code=code)
|
test = self.create_test("sigint", code=code)
|
||||||
|
|
||||||
try:
|
for multiprocessing in (False, True):
|
||||||
import threading
|
|
||||||
tests = (False, True)
|
|
||||||
except ImportError:
|
|
||||||
tests = (False,)
|
|
||||||
for multiprocessing in tests:
|
|
||||||
if multiprocessing:
|
if multiprocessing:
|
||||||
args = ("--slowest", "-j2", test)
|
args = ("--slowest", "-j2", test)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
import urllib.robotparser
|
import urllib.robotparser
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from test import support
|
from test import support
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
|
|
||||||
class BaseRobotTest:
|
class BaseRobotTest:
|
||||||
|
@ -255,7 +252,6 @@ class RobotHandler(BaseHTTPRequestHandler):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'threading required for this test')
|
|
||||||
class PasswordProtectedSiteTestCase(unittest.TestCase):
|
class PasswordProtectedSiteTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import queue
|
import queue
|
||||||
import sched
|
import sched
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
TIMEOUT = 10
|
TIMEOUT = 10
|
||||||
|
|
||||||
|
@ -58,7 +56,6 @@ class TestCase(unittest.TestCase):
|
||||||
scheduler.run()
|
scheduler.run()
|
||||||
self.assertEqual(l, [0.01, 0.02, 0.03, 0.04, 0.05])
|
self.assertEqual(l, [0.01, 0.02, 0.03, 0.04, 0.05])
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_enter_concurrent(self):
|
def test_enter_concurrent(self):
|
||||||
q = queue.Queue()
|
q = queue.Queue()
|
||||||
fun = q.put
|
fun = q.put
|
||||||
|
@ -113,7 +110,6 @@ class TestCase(unittest.TestCase):
|
||||||
scheduler.run()
|
scheduler.run()
|
||||||
self.assertEqual(l, [0.02, 0.03, 0.04])
|
self.assertEqual(l, [0.02, 0.03, 0.04])
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_cancel_concurrent(self):
|
def test_cancel_concurrent(self):
|
||||||
q = queue.Queue()
|
q = queue.Queue()
|
||||||
fun = q.put
|
fun = q.put
|
||||||
|
|
|
@ -5,14 +5,11 @@ import socket
|
||||||
import statistics
|
import statistics
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
from test import support
|
from test import support
|
||||||
from test.support.script_helper import assert_python_ok, spawn_python
|
from test.support.script_helper import assert_python_ok, spawn_python
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
try:
|
try:
|
||||||
import _testcapi
|
import _testcapi
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -21,7 +18,6 @@ except ImportError:
|
||||||
|
|
||||||
class GenericTests(unittest.TestCase):
|
class GenericTests(unittest.TestCase):
|
||||||
|
|
||||||
@unittest.skipIf(threading is None, "test needs threading module")
|
|
||||||
def test_enums(self):
|
def test_enums(self):
|
||||||
for name in dir(signal):
|
for name in dir(signal):
|
||||||
sig = getattr(signal, name)
|
sig = getattr(signal, name)
|
||||||
|
@ -807,7 +803,6 @@ class PendingSignalsTests(unittest.TestCase):
|
||||||
'need signal.sigwait()')
|
'need signal.sigwait()')
|
||||||
@unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
|
@unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
|
||||||
'need signal.pthread_sigmask()')
|
'need signal.pthread_sigmask()')
|
||||||
@unittest.skipIf(threading is None, "test needs threading module")
|
|
||||||
def test_sigwait_thread(self):
|
def test_sigwait_thread(self):
|
||||||
# Check that calling sigwait() from a thread doesn't suspend the whole
|
# Check that calling sigwait() from a thread doesn't suspend the whole
|
||||||
# process. A new interpreter is spawned to avoid problems when mixing
|
# process. A new interpreter is spawned to avoid problems when mixing
|
||||||
|
|
|
@ -15,14 +15,11 @@ import time
|
||||||
import select
|
import select
|
||||||
import errno
|
import errno
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import threading
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from test import support, mock_socket
|
from test import support, mock_socket
|
||||||
|
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
HOST = support.HOST
|
HOST = support.HOST
|
||||||
|
|
||||||
|
@ -191,7 +188,6 @@ MSG_END = '------------ END MESSAGE ------------\n'
|
||||||
# test server times out, causing the test to fail.
|
# test server times out, causing the test to fail.
|
||||||
|
|
||||||
# Test behavior of smtpd.DebuggingServer
|
# Test behavior of smtpd.DebuggingServer
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class DebuggingServerTests(unittest.TestCase):
|
class DebuggingServerTests(unittest.TestCase):
|
||||||
|
|
||||||
maxDiff = None
|
maxDiff = None
|
||||||
|
@ -570,7 +566,6 @@ class NonConnectingTests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
# test response of client to a non-successful HELO message
|
# test response of client to a non-successful HELO message
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class BadHELOServerTests(unittest.TestCase):
|
class BadHELOServerTests(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -590,7 +585,6 @@ class BadHELOServerTests(unittest.TestCase):
|
||||||
HOST, self.port, 'localhost', 3)
|
HOST, self.port, 'localhost', 3)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class TooLongLineTests(unittest.TestCase):
|
class TooLongLineTests(unittest.TestCase):
|
||||||
respdata = b'250 OK' + (b'.' * smtplib._MAXLINE * 2) + b'\n'
|
respdata = b'250 OK' + (b'.' * smtplib._MAXLINE * 2) + b'\n'
|
||||||
|
|
||||||
|
@ -835,7 +829,6 @@ class SimSMTPServer(smtpd.SMTPServer):
|
||||||
|
|
||||||
# Test various SMTP & ESMTP commands/behaviors that require a simulated server
|
# Test various SMTP & ESMTP commands/behaviors that require a simulated server
|
||||||
# (i.e., something with more features than DebuggingServer)
|
# (i.e., something with more features than DebuggingServer)
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class SMTPSimTests(unittest.TestCase):
|
class SMTPSimTests(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -1091,7 +1084,6 @@ class SimSMTPUTF8Server(SimSMTPServer):
|
||||||
self.last_rcpt_options = rcpt_options
|
self.last_rcpt_options = rcpt_options
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class SMTPUTF8SimTests(unittest.TestCase):
|
class SMTPUTF8SimTests(unittest.TestCase):
|
||||||
|
|
||||||
maxDiff = None
|
maxDiff = None
|
||||||
|
@ -1227,7 +1219,6 @@ class SimSMTPAUTHInitialResponseServer(SimSMTPServer):
|
||||||
channel_class = SimSMTPAUTHInitialResponseChannel
|
channel_class = SimSMTPAUTHInitialResponseChannel
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class SMTPAUTHInitialResponseSimTests(unittest.TestCase):
|
class SMTPAUTHInitialResponseSimTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.real_getfqdn = socket.getfqdn
|
self.real_getfqdn = socket.getfqdn
|
||||||
|
|
|
@ -21,6 +21,8 @@ import pickle
|
||||||
import struct
|
import struct
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
|
import _thread as thread
|
||||||
|
import threading
|
||||||
try:
|
try:
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -35,12 +37,6 @@ MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') ## test unicode string
|
||||||
|
|
||||||
VSOCKPORT = 1234
|
VSOCKPORT = 1234
|
||||||
|
|
||||||
try:
|
|
||||||
import _thread as thread
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
thread = None
|
|
||||||
threading = None
|
|
||||||
try:
|
try:
|
||||||
import _socket
|
import _socket
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -143,18 +139,17 @@ class ThreadSafeCleanupTestCase(unittest.TestCase):
|
||||||
with a recursive lock.
|
with a recursive lock.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if threading:
|
def __init__(self, *args, **kwargs):
|
||||||
def __init__(self, *args, **kwargs):
|
super().__init__(*args, **kwargs)
|
||||||
super().__init__(*args, **kwargs)
|
self._cleanup_lock = threading.RLock()
|
||||||
self._cleanup_lock = threading.RLock()
|
|
||||||
|
|
||||||
def addCleanup(self, *args, **kwargs):
|
def addCleanup(self, *args, **kwargs):
|
||||||
with self._cleanup_lock:
|
with self._cleanup_lock:
|
||||||
return super().addCleanup(*args, **kwargs)
|
return super().addCleanup(*args, **kwargs)
|
||||||
|
|
||||||
def doCleanups(self, *args, **kwargs):
|
def doCleanups(self, *args, **kwargs):
|
||||||
with self._cleanup_lock:
|
with self._cleanup_lock:
|
||||||
return super().doCleanups(*args, **kwargs)
|
return super().doCleanups(*args, **kwargs)
|
||||||
|
|
||||||
class SocketCANTest(unittest.TestCase):
|
class SocketCANTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -407,7 +402,6 @@ class ThreadedRDSSocketTest(SocketRDSTest, ThreadableTest):
|
||||||
ThreadableTest.clientTearDown(self)
|
ThreadableTest.clientTearDown(self)
|
||||||
|
|
||||||
@unittest.skipIf(fcntl is None, "need fcntl")
|
@unittest.skipIf(fcntl is None, "need fcntl")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
@unittest.skipUnless(HAVE_SOCKET_VSOCK,
|
@unittest.skipUnless(HAVE_SOCKET_VSOCK,
|
||||||
'VSOCK sockets required for this test.')
|
'VSOCK sockets required for this test.')
|
||||||
@unittest.skipUnless(get_cid() != 2,
|
@unittest.skipUnless(get_cid() != 2,
|
||||||
|
@ -1684,7 +1678,6 @@ class BasicCANTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.')
|
@unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.')
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class CANTest(ThreadedCANSocketTest):
|
class CANTest(ThreadedCANSocketTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -1838,7 +1831,6 @@ class BasicRDSTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(HAVE_SOCKET_RDS, 'RDS sockets required for this test.')
|
@unittest.skipUnless(HAVE_SOCKET_RDS, 'RDS sockets required for this test.')
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RDSTest(ThreadedRDSSocketTest):
|
class RDSTest(ThreadedRDSSocketTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -1977,7 +1969,7 @@ class BasicVSOCKTest(unittest.TestCase):
|
||||||
s.getsockopt(socket.AF_VSOCK,
|
s.getsockopt(socket.AF_VSOCK,
|
||||||
socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE))
|
socket.SO_VM_SOCKETS_BUFFER_MIN_SIZE))
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class BasicTCPTest(SocketConnectedTest):
|
class BasicTCPTest(SocketConnectedTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -2100,7 +2092,7 @@ class BasicTCPTest(SocketConnectedTest):
|
||||||
def _testDetach(self):
|
def _testDetach(self):
|
||||||
self.serv_conn.send(MSG)
|
self.serv_conn.send(MSG)
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class BasicUDPTest(ThreadedUDPSocketTest):
|
class BasicUDPTest(ThreadedUDPSocketTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -3697,17 +3689,14 @@ class SendrecvmsgUDPTestBase(SendrecvmsgDgramFlagsBase,
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "sendmsg")
|
@requireAttrs(socket.socket, "sendmsg")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class SendmsgUDPTest(SendmsgConnectionlessTests, SendrecvmsgUDPTestBase):
|
class SendmsgUDPTest(SendmsgConnectionlessTests, SendrecvmsgUDPTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg")
|
@requireAttrs(socket.socket, "recvmsg")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgUDPTest(RecvmsgTests, SendrecvmsgUDPTestBase):
|
class RecvmsgUDPTest(RecvmsgTests, SendrecvmsgUDPTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg_into")
|
@requireAttrs(socket.socket, "recvmsg_into")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgIntoUDPTest(RecvmsgIntoTests, SendrecvmsgUDPTestBase):
|
class RecvmsgIntoUDPTest(RecvmsgIntoTests, SendrecvmsgUDPTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -3724,21 +3713,18 @@ class SendrecvmsgUDP6TestBase(SendrecvmsgDgramFlagsBase,
|
||||||
@requireAttrs(socket.socket, "sendmsg")
|
@requireAttrs(socket.socket, "sendmsg")
|
||||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
||||||
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class SendmsgUDP6Test(SendmsgConnectionlessTests, SendrecvmsgUDP6TestBase):
|
class SendmsgUDP6Test(SendmsgConnectionlessTests, SendrecvmsgUDP6TestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg")
|
@requireAttrs(socket.socket, "recvmsg")
|
||||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
||||||
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgUDP6Test(RecvmsgTests, SendrecvmsgUDP6TestBase):
|
class RecvmsgUDP6Test(RecvmsgTests, SendrecvmsgUDP6TestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg_into")
|
@requireAttrs(socket.socket, "recvmsg_into")
|
||||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
||||||
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgIntoUDP6Test(RecvmsgIntoTests, SendrecvmsgUDP6TestBase):
|
class RecvmsgIntoUDP6Test(RecvmsgIntoTests, SendrecvmsgUDP6TestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -3746,7 +3732,6 @@ class RecvmsgIntoUDP6Test(RecvmsgIntoTests, SendrecvmsgUDP6TestBase):
|
||||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
||||||
@requireAttrs(socket, "IPPROTO_IPV6")
|
@requireAttrs(socket, "IPPROTO_IPV6")
|
||||||
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgRFC3542AncillaryUDP6Test(RFC3542AncillaryTest,
|
class RecvmsgRFC3542AncillaryUDP6Test(RFC3542AncillaryTest,
|
||||||
SendrecvmsgUDP6TestBase):
|
SendrecvmsgUDP6TestBase):
|
||||||
pass
|
pass
|
||||||
|
@ -3755,7 +3740,6 @@ class RecvmsgRFC3542AncillaryUDP6Test(RFC3542AncillaryTest,
|
||||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.')
|
||||||
@requireAttrs(socket, "IPPROTO_IPV6")
|
@requireAttrs(socket, "IPPROTO_IPV6")
|
||||||
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
@requireSocket("AF_INET6", "SOCK_DGRAM")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgIntoRFC3542AncillaryUDP6Test(RecvmsgIntoMixin,
|
class RecvmsgIntoRFC3542AncillaryUDP6Test(RecvmsgIntoMixin,
|
||||||
RFC3542AncillaryTest,
|
RFC3542AncillaryTest,
|
||||||
SendrecvmsgUDP6TestBase):
|
SendrecvmsgUDP6TestBase):
|
||||||
|
@ -3767,18 +3751,15 @@ class SendrecvmsgTCPTestBase(SendrecvmsgConnectedBase,
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "sendmsg")
|
@requireAttrs(socket.socket, "sendmsg")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class SendmsgTCPTest(SendmsgStreamTests, SendrecvmsgTCPTestBase):
|
class SendmsgTCPTest(SendmsgStreamTests, SendrecvmsgTCPTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg")
|
@requireAttrs(socket.socket, "recvmsg")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgTCPTest(RecvmsgTests, RecvmsgGenericStreamTests,
|
class RecvmsgTCPTest(RecvmsgTests, RecvmsgGenericStreamTests,
|
||||||
SendrecvmsgTCPTestBase):
|
SendrecvmsgTCPTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg_into")
|
@requireAttrs(socket.socket, "recvmsg_into")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgIntoTCPTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
|
class RecvmsgIntoTCPTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
|
||||||
SendrecvmsgTCPTestBase):
|
SendrecvmsgTCPTestBase):
|
||||||
pass
|
pass
|
||||||
|
@ -3791,13 +3772,11 @@ class SendrecvmsgSCTPStreamTestBase(SendrecvmsgSCTPFlagsBase,
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "sendmsg")
|
@requireAttrs(socket.socket, "sendmsg")
|
||||||
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
|
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class SendmsgSCTPStreamTest(SendmsgStreamTests, SendrecvmsgSCTPStreamTestBase):
|
class SendmsgSCTPStreamTest(SendmsgStreamTests, SendrecvmsgSCTPStreamTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg")
|
@requireAttrs(socket.socket, "recvmsg")
|
||||||
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
|
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgSCTPStreamTest(RecvmsgTests, RecvmsgGenericStreamTests,
|
class RecvmsgSCTPStreamTest(RecvmsgTests, RecvmsgGenericStreamTests,
|
||||||
SendrecvmsgSCTPStreamTestBase):
|
SendrecvmsgSCTPStreamTestBase):
|
||||||
|
|
||||||
|
@ -3811,7 +3790,6 @@ class RecvmsgSCTPStreamTest(RecvmsgTests, RecvmsgGenericStreamTests,
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg_into")
|
@requireAttrs(socket.socket, "recvmsg_into")
|
||||||
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
|
@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgIntoSCTPStreamTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
|
class RecvmsgIntoSCTPStreamTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
|
||||||
SendrecvmsgSCTPStreamTestBase):
|
SendrecvmsgSCTPStreamTestBase):
|
||||||
|
|
||||||
|
@ -3830,33 +3808,28 @@ class SendrecvmsgUnixStreamTestBase(SendrecvmsgConnectedBase,
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "sendmsg")
|
@requireAttrs(socket.socket, "sendmsg")
|
||||||
@requireAttrs(socket, "AF_UNIX")
|
@requireAttrs(socket, "AF_UNIX")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class SendmsgUnixStreamTest(SendmsgStreamTests, SendrecvmsgUnixStreamTestBase):
|
class SendmsgUnixStreamTest(SendmsgStreamTests, SendrecvmsgUnixStreamTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg")
|
@requireAttrs(socket.socket, "recvmsg")
|
||||||
@requireAttrs(socket, "AF_UNIX")
|
@requireAttrs(socket, "AF_UNIX")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgUnixStreamTest(RecvmsgTests, RecvmsgGenericStreamTests,
|
class RecvmsgUnixStreamTest(RecvmsgTests, RecvmsgGenericStreamTests,
|
||||||
SendrecvmsgUnixStreamTestBase):
|
SendrecvmsgUnixStreamTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "recvmsg_into")
|
@requireAttrs(socket.socket, "recvmsg_into")
|
||||||
@requireAttrs(socket, "AF_UNIX")
|
@requireAttrs(socket, "AF_UNIX")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgIntoUnixStreamTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
|
class RecvmsgIntoUnixStreamTest(RecvmsgIntoTests, RecvmsgGenericStreamTests,
|
||||||
SendrecvmsgUnixStreamTestBase):
|
SendrecvmsgUnixStreamTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "sendmsg", "recvmsg")
|
@requireAttrs(socket.socket, "sendmsg", "recvmsg")
|
||||||
@requireAttrs(socket, "AF_UNIX", "SOL_SOCKET", "SCM_RIGHTS")
|
@requireAttrs(socket, "AF_UNIX", "SOL_SOCKET", "SCM_RIGHTS")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgSCMRightsStreamTest(SCMRightsTest, SendrecvmsgUnixStreamTestBase):
|
class RecvmsgSCMRightsStreamTest(SCMRightsTest, SendrecvmsgUnixStreamTestBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@requireAttrs(socket.socket, "sendmsg", "recvmsg_into")
|
@requireAttrs(socket.socket, "sendmsg", "recvmsg_into")
|
||||||
@requireAttrs(socket, "AF_UNIX", "SOL_SOCKET", "SCM_RIGHTS")
|
@requireAttrs(socket, "AF_UNIX", "SOL_SOCKET", "SCM_RIGHTS")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class RecvmsgIntoSCMRightsStreamTest(RecvmsgIntoMixin, SCMRightsTest,
|
class RecvmsgIntoSCMRightsStreamTest(RecvmsgIntoMixin, SCMRightsTest,
|
||||||
SendrecvmsgUnixStreamTestBase):
|
SendrecvmsgUnixStreamTestBase):
|
||||||
pass
|
pass
|
||||||
|
@ -3944,7 +3917,6 @@ class InterruptedRecvTimeoutTest(InterruptedTimeoutBase, UDPTestBase):
|
||||||
@requireAttrs(signal, "siginterrupt")
|
@requireAttrs(signal, "siginterrupt")
|
||||||
@unittest.skipUnless(hasattr(signal, "alarm") or hasattr(signal, "setitimer"),
|
@unittest.skipUnless(hasattr(signal, "alarm") or hasattr(signal, "setitimer"),
|
||||||
"Don't have signal.alarm or signal.setitimer")
|
"Don't have signal.alarm or signal.setitimer")
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class InterruptedSendTimeoutTest(InterruptedTimeoutBase,
|
class InterruptedSendTimeoutTest(InterruptedTimeoutBase,
|
||||||
ThreadSafeCleanupTestCase,
|
ThreadSafeCleanupTestCase,
|
||||||
SocketListeningTestMixin, TCPTestBase):
|
SocketListeningTestMixin, TCPTestBase):
|
||||||
|
@ -3997,7 +3969,6 @@ class InterruptedSendTimeoutTest(InterruptedTimeoutBase,
|
||||||
self.checkInterruptedSend(self.serv_conn.sendmsg, [b"a"*512])
|
self.checkInterruptedSend(self.serv_conn.sendmsg, [b"a"*512])
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class TCPCloserTest(ThreadedTCPSocketTest):
|
class TCPCloserTest(ThreadedTCPSocketTest):
|
||||||
|
|
||||||
def testClose(self):
|
def testClose(self):
|
||||||
|
@ -4017,7 +3988,7 @@ class TCPCloserTest(ThreadedTCPSocketTest):
|
||||||
self.cli.connect((HOST, self.port))
|
self.cli.connect((HOST, self.port))
|
||||||
time.sleep(1.0)
|
time.sleep(1.0)
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class BasicSocketPairTest(SocketPairTest):
|
class BasicSocketPairTest(SocketPairTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -4052,7 +4023,7 @@ class BasicSocketPairTest(SocketPairTest):
|
||||||
msg = self.cli.recv(1024)
|
msg = self.cli.recv(1024)
|
||||||
self.assertEqual(msg, MSG)
|
self.assertEqual(msg, MSG)
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class NonBlockingTCPTests(ThreadedTCPSocketTest):
|
class NonBlockingTCPTests(ThreadedTCPSocketTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -4180,7 +4151,7 @@ class NonBlockingTCPTests(ThreadedTCPSocketTest):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self.cli.send(MSG)
|
self.cli.send(MSG)
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class FileObjectClassTestCase(SocketConnectedTest):
|
class FileObjectClassTestCase(SocketConnectedTest):
|
||||||
"""Unit tests for the object returned by socket.makefile()
|
"""Unit tests for the object returned by socket.makefile()
|
||||||
|
|
||||||
|
@ -4564,7 +4535,6 @@ class NetworkConnectionNoServer(unittest.TestCase):
|
||||||
socket.create_connection((HOST, 1234))
|
socket.create_connection((HOST, 1234))
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest):
|
class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -4633,7 +4603,7 @@ class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest):
|
||||||
self.addCleanup(self.cli.close)
|
self.addCleanup(self.cli.close)
|
||||||
self.assertEqual(self.cli.gettimeout(), 30)
|
self.assertEqual(self.cli.gettimeout(), 30)
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class NetworkConnectionBehaviourTest(SocketTCPTest, ThreadableTest):
|
class NetworkConnectionBehaviourTest(SocketTCPTest, ThreadableTest):
|
||||||
|
|
||||||
def __init__(self, methodName='runTest'):
|
def __init__(self, methodName='runTest'):
|
||||||
|
@ -4877,7 +4847,7 @@ class TestUnixDomain(unittest.TestCase):
|
||||||
self.addCleanup(support.unlink, path)
|
self.addCleanup(support.unlink, path)
|
||||||
self.assertEqual(self.sock.getsockname(), path)
|
self.assertEqual(self.sock.getsockname(), path)
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class BufferIOTest(SocketConnectedTest):
|
class BufferIOTest(SocketConnectedTest):
|
||||||
"""
|
"""
|
||||||
Test the buffer versions of socket.recv() and socket.send().
|
Test the buffer versions of socket.recv() and socket.send().
|
||||||
|
@ -5050,7 +5020,6 @@ class TIPCThreadableTest(unittest.TestCase, ThreadableTest):
|
||||||
self.cli.close()
|
self.cli.close()
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class ContextManagersTest(ThreadedTCPSocketTest):
|
class ContextManagersTest(ThreadedTCPSocketTest):
|
||||||
|
|
||||||
def _testSocketClass(self):
|
def _testSocketClass(self):
|
||||||
|
@ -5312,7 +5281,6 @@ class TestSocketSharing(SocketTCPTest):
|
||||||
source.close()
|
source.close()
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
class SendfileUsingSendTest(ThreadedTCPSocketTest):
|
class SendfileUsingSendTest(ThreadedTCPSocketTest):
|
||||||
"""
|
"""
|
||||||
Test the send() implementation of socket.sendfile().
|
Test the send() implementation of socket.sendfile().
|
||||||
|
@ -5570,7 +5538,6 @@ class SendfileUsingSendTest(ThreadedTCPSocketTest):
|
||||||
meth, file, count=-1)
|
meth, file, count=-1)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(thread, 'Threading required for this test.')
|
|
||||||
@unittest.skipUnless(hasattr(os, "sendfile"),
|
@unittest.skipUnless(hasattr(os, "sendfile"),
|
||||||
'os.sendfile() required for this test.')
|
'os.sendfile() required for this test.')
|
||||||
class SendfileUsingSendfileTest(SendfileUsingSendTest):
|
class SendfileUsingSendfileTest(SendfileUsingSendTest):
|
||||||
|
|
|
@ -9,15 +9,13 @@ import select
|
||||||
import signal
|
import signal
|
||||||
import socket
|
import socket
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
import socketserver
|
import socketserver
|
||||||
|
|
||||||
import test.support
|
import test.support
|
||||||
from test.support import reap_children, reap_threads, verbose
|
from test.support import reap_children, reap_threads, verbose
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
test.support.requires("network")
|
test.support.requires("network")
|
||||||
|
|
||||||
|
@ -68,7 +66,6 @@ def simple_subprocess(testcase):
|
||||||
testcase.assertEqual(72 << 8, status)
|
testcase.assertEqual(72 << 8, status)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class SocketServerTest(unittest.TestCase):
|
class SocketServerTest(unittest.TestCase):
|
||||||
"""Test all socket servers."""
|
"""Test all socket servers."""
|
||||||
|
|
||||||
|
@ -306,12 +303,10 @@ class ErrorHandlerTest(unittest.TestCase):
|
||||||
BaseErrorTestServer(SystemExit)
|
BaseErrorTestServer(SystemExit)
|
||||||
self.check_result(handled=False)
|
self.check_result(handled=False)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_threading_handled(self):
|
def test_threading_handled(self):
|
||||||
ThreadingErrorTestServer(ValueError)
|
ThreadingErrorTestServer(ValueError)
|
||||||
self.check_result(handled=True)
|
self.check_result(handled=True)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_threading_not_handled(self):
|
def test_threading_not_handled(self):
|
||||||
ThreadingErrorTestServer(SystemExit)
|
ThreadingErrorTestServer(SystemExit)
|
||||||
self.check_result(handled=False)
|
self.check_result(handled=False)
|
||||||
|
@ -396,7 +391,6 @@ class SocketWriterTest(unittest.TestCase):
|
||||||
self.assertIsInstance(server.wfile, io.BufferedIOBase)
|
self.assertIsInstance(server.wfile, io.BufferedIOBase)
|
||||||
self.assertEqual(server.wfile_fileno, server.request_fileno)
|
self.assertEqual(server.wfile_fileno, server.request_fileno)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_write(self):
|
def test_write(self):
|
||||||
# Test that wfile.write() sends data immediately, and that it does
|
# Test that wfile.write() sends data immediately, and that it does
|
||||||
# not truncate sends when interrupted by a Unix signal
|
# not truncate sends when interrupted by a Unix signal
|
||||||
|
|
3276
Lib/test/test_ssl.py
3276
Lib/test/test_ssl.py
File diff suppressed because it is too large
Load Diff
|
@ -14,6 +14,7 @@ import selectors
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import select
|
import select
|
||||||
import shutil
|
import shutil
|
||||||
|
import threading
|
||||||
import gc
|
import gc
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
|
@ -24,11 +25,6 @@ except ImportError:
|
||||||
else:
|
else:
|
||||||
import ctypes.util
|
import ctypes.util
|
||||||
|
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import _testcapi
|
import _testcapi
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -1196,7 +1192,6 @@ class ProcessTestCase(BaseTestCase):
|
||||||
self.assertEqual(stderr, "")
|
self.assertEqual(stderr, "")
|
||||||
self.assertEqual(proc.returncode, 0)
|
self.assertEqual(proc.returncode, 0)
|
||||||
|
|
||||||
@unittest.skipIf(threading is None, "threading required")
|
|
||||||
def test_double_close_on_error(self):
|
def test_double_close_on_error(self):
|
||||||
# Issue #18851
|
# Issue #18851
|
||||||
fds = []
|
fds = []
|
||||||
|
@ -1226,7 +1221,6 @@ class ProcessTestCase(BaseTestCase):
|
||||||
if exc is not None:
|
if exc is not None:
|
||||||
raise exc
|
raise exc
|
||||||
|
|
||||||
@unittest.skipIf(threading is None, "threading required")
|
|
||||||
def test_threadsafe_wait(self):
|
def test_threadsafe_wait(self):
|
||||||
"""Issue21291: Popen.wait() needs to be threadsafe for returncode."""
|
"""Issue21291: Popen.wait() needs to be threadsafe for returncode."""
|
||||||
proc = subprocess.Popen([sys.executable, '-c',
|
proc = subprocess.Popen([sys.executable, '-c',
|
||||||
|
|
|
@ -10,15 +10,12 @@ import codecs
|
||||||
import gc
|
import gc
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import locale
|
import locale
|
||||||
|
import threading
|
||||||
|
|
||||||
# count the number of test runs, used to create unique
|
# count the number of test runs, used to create unique
|
||||||
# strings to intern in test_intern()
|
# strings to intern in test_intern()
|
||||||
numruns = 0
|
numruns = 0
|
||||||
|
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
class SysModuleTest(unittest.TestCase):
|
class SysModuleTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -172,7 +169,6 @@ class SysModuleTest(unittest.TestCase):
|
||||||
sys.setcheckinterval(n)
|
sys.setcheckinterval(n)
|
||||||
self.assertEqual(sys.getcheckinterval(), n)
|
self.assertEqual(sys.getcheckinterval(), n)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
def test_switchinterval(self):
|
def test_switchinterval(self):
|
||||||
self.assertRaises(TypeError, sys.setswitchinterval)
|
self.assertRaises(TypeError, sys.setswitchinterval)
|
||||||
self.assertRaises(TypeError, sys.setswitchinterval, "a")
|
self.assertRaises(TypeError, sys.setswitchinterval, "a")
|
||||||
|
@ -348,21 +344,8 @@ class SysModuleTest(unittest.TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
# sys._current_frames() is a CPython-only gimmick.
|
# sys._current_frames() is a CPython-only gimmick.
|
||||||
def test_current_frames(self):
|
|
||||||
have_threads = True
|
|
||||||
try:
|
|
||||||
import _thread
|
|
||||||
except ImportError:
|
|
||||||
have_threads = False
|
|
||||||
|
|
||||||
if have_threads:
|
|
||||||
self.current_frames_with_threads()
|
|
||||||
else:
|
|
||||||
self.current_frames_without_threads()
|
|
||||||
|
|
||||||
# Test sys._current_frames() in a WITH_THREADS build.
|
|
||||||
@test.support.reap_threads
|
@test.support.reap_threads
|
||||||
def current_frames_with_threads(self):
|
def test_current_frames(self):
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
@ -426,15 +409,6 @@ class SysModuleTest(unittest.TestCase):
|
||||||
leave_g.set()
|
leave_g.set()
|
||||||
t.join()
|
t.join()
|
||||||
|
|
||||||
# Test sys._current_frames() when thread support doesn't exist.
|
|
||||||
def current_frames_without_threads(self):
|
|
||||||
# Not much happens here: there is only one thread, with artificial
|
|
||||||
# "thread id" 0.
|
|
||||||
d = sys._current_frames()
|
|
||||||
self.assertEqual(len(d), 1)
|
|
||||||
self.assertIn(0, d)
|
|
||||||
self.assertTrue(d[0] is sys._getframe())
|
|
||||||
|
|
||||||
def test_attributes(self):
|
def test_attributes(self):
|
||||||
self.assertIsInstance(sys.api_version, int)
|
self.assertIsInstance(sys.api_version, int)
|
||||||
self.assertIsInstance(sys.argv, list)
|
self.assertIsInstance(sys.argv, list)
|
||||||
|
@ -516,8 +490,6 @@ class SysModuleTest(unittest.TestCase):
|
||||||
if not sys.platform.startswith('win'):
|
if not sys.platform.startswith('win'):
|
||||||
self.assertIsInstance(sys.abiflags, str)
|
self.assertIsInstance(sys.abiflags, str)
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(sys, 'thread_info'),
|
|
||||||
'Threading required for this test.')
|
|
||||||
def test_thread_info(self):
|
def test_thread_info(self):
|
||||||
info = sys.thread_info
|
info = sys.thread_info
|
||||||
self.assertEqual(len(info), 3)
|
self.assertEqual(len(info), 3)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import socket
|
import socket
|
||||||
import selectors
|
import selectors
|
||||||
import telnetlib
|
import telnetlib
|
||||||
|
import threading
|
||||||
import contextlib
|
import contextlib
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
import unittest
|
import unittest
|
||||||
threading = support.import_module('threading')
|
|
||||||
|
|
||||||
HOST = support.HOST
|
HOST = support.HOST
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,12 @@ import importlib
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import shutil
|
import shutil
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
from test.support import (
|
from test.support import (
|
||||||
verbose, import_module, run_unittest, TESTFN, reap_threads,
|
verbose, import_module, run_unittest, TESTFN, reap_threads,
|
||||||
forget, unlink, rmtree, start_threads)
|
forget, unlink, rmtree, start_threads)
|
||||||
threading = import_module('threading')
|
|
||||||
|
|
||||||
def task(N, done, done_tasks, errors):
|
def task(N, done, done_tasks, errors):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -19,9 +19,9 @@ FILES_PER_THREAD = 50
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from test.support import start_threads, import_module
|
from test.support import start_threads, import_module
|
||||||
threading = import_module('threading')
|
|
||||||
import unittest
|
import unittest
|
||||||
import io
|
import io
|
||||||
|
import threading
|
||||||
from traceback import print_exc
|
from traceback import print_exc
|
||||||
|
|
||||||
startEvent = threading.Event()
|
startEvent = threading.Event()
|
||||||
|
|
|
@ -9,8 +9,8 @@ from test.support.script_helper import assert_python_ok, assert_python_failure
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
_thread = import_module('_thread')
|
import _thread
|
||||||
threading = import_module('threading')
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import weakref
|
import weakref
|
||||||
|
|
|
@ -5,8 +5,8 @@ import weakref
|
||||||
import gc
|
import gc
|
||||||
|
|
||||||
# Modules under test
|
# Modules under test
|
||||||
_thread = support.import_module('_thread')
|
import _thread
|
||||||
threading = support.import_module('threading')
|
import threading
|
||||||
import _threading_local
|
import _threading_local
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,6 @@ import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
try:
|
try:
|
||||||
import _testcapi
|
import _testcapi
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
|
@ -7,10 +7,7 @@ from unittest.mock import patch
|
||||||
from test.support.script_helper import (assert_python_ok, assert_python_failure,
|
from test.support.script_helper import (assert_python_ok, assert_python_failure,
|
||||||
interpreter_requires_environment)
|
interpreter_requires_environment)
|
||||||
from test import support
|
from test import support
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
try:
|
try:
|
||||||
import _testcapi
|
import _testcapi
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
|
@ -4,13 +4,12 @@ import email
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import http.server
|
import http.server
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
|
|
||||||
threading = support.import_module('threading')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import ssl
|
import ssl
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -276,7 +275,6 @@ class FakeProxyHandler(http.server.BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# Test cases
|
# Test cases
|
||||||
|
|
||||||
@unittest.skipUnless(threading, "Threading required for this test.")
|
|
||||||
class BasicAuthTests(unittest.TestCase):
|
class BasicAuthTests(unittest.TestCase):
|
||||||
USER = "testUser"
|
USER = "testUser"
|
||||||
PASSWD = "testPass"
|
PASSWD = "testPass"
|
||||||
|
@ -317,7 +315,6 @@ class BasicAuthTests(unittest.TestCase):
|
||||||
self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, self.server_url)
|
self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, self.server_url)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, "Threading required for this test.")
|
|
||||||
class ProxyAuthTests(unittest.TestCase):
|
class ProxyAuthTests(unittest.TestCase):
|
||||||
URL = "http://localhost"
|
URL = "http://localhost"
|
||||||
|
|
||||||
|
@ -439,7 +436,6 @@ def GetRequestHandler(responses):
|
||||||
return FakeHTTPRequestHandler
|
return FakeHTTPRequestHandler
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, "Threading required for this test.")
|
|
||||||
class TestUrlopen(unittest.TestCase):
|
class TestUrlopen(unittest.TestCase):
|
||||||
"""Tests urllib.request.urlopen using the network.
|
"""Tests urllib.request.urlopen using the network.
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,10 @@ import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
from test.support import (captured_stdout, captured_stderr,
|
from test.support import (captured_stdout, captured_stderr,
|
||||||
can_symlink, EnvironmentVarGuard, rmtree)
|
can_symlink, EnvironmentVarGuard, rmtree)
|
||||||
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
import venv
|
import venv
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import ctypes
|
import ctypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -420,8 +415,6 @@ class EnsurePipTest(BaseTest):
|
||||||
if not system_site_packages:
|
if not system_site_packages:
|
||||||
self.assert_pip_not_installed()
|
self.assert_pip_not_installed()
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'some dependencies of pip import threading'
|
|
||||||
' module unconditionally')
|
|
||||||
# Issue #26610: pip/pep425tags.py requires ctypes
|
# Issue #26610: pip/pep425tags.py requires ctypes
|
||||||
@unittest.skipUnless(ctypes, 'pip requires ctypes')
|
@unittest.skipUnless(ctypes, 'pip requires ctypes')
|
||||||
def test_with_pip(self):
|
def test_with_pip(self):
|
||||||
|
|
|
@ -6,6 +6,7 @@ import weakref
|
||||||
import operator
|
import operator
|
||||||
import contextlib
|
import contextlib
|
||||||
import copy
|
import copy
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
|
@ -78,7 +79,6 @@ def collect_in_thread(period=0.0001):
|
||||||
"""
|
"""
|
||||||
Ensure GC collections happen in a different thread, at a high frequency.
|
Ensure GC collections happen in a different thread, at a high frequency.
|
||||||
"""
|
"""
|
||||||
threading = support.import_module('threading')
|
|
||||||
please_stop = False
|
please_stop = False
|
||||||
|
|
||||||
def collect():
|
def collect():
|
||||||
|
|
|
@ -10,6 +10,7 @@ import xmlrpc.server
|
||||||
import http.client
|
import http.client
|
||||||
import http, http.server
|
import http, http.server
|
||||||
import socket
|
import socket
|
||||||
|
import threading
|
||||||
import re
|
import re
|
||||||
import io
|
import io
|
||||||
import contextlib
|
import contextlib
|
||||||
|
@ -19,10 +20,6 @@ try:
|
||||||
import gzip
|
import gzip
|
||||||
except ImportError:
|
except ImportError:
|
||||||
gzip = None
|
gzip = None
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
threading = None
|
|
||||||
|
|
||||||
alist = [{'astring': 'foo@bar.baz.spam',
|
alist = [{'astring': 'foo@bar.baz.spam',
|
||||||
'afloat': 7283.43,
|
'afloat': 7283.43,
|
||||||
|
@ -307,7 +304,6 @@ class XMLRPCTestCase(unittest.TestCase):
|
||||||
except OSError:
|
except OSError:
|
||||||
self.assertTrue(has_ssl)
|
self.assertTrue(has_ssl)
|
||||||
|
|
||||||
@unittest.skipUnless(threading, "Threading required for this test.")
|
|
||||||
def test_keepalive_disconnect(self):
|
def test_keepalive_disconnect(self):
|
||||||
class RequestHandler(http.server.BaseHTTPRequestHandler):
|
class RequestHandler(http.server.BaseHTTPRequestHandler):
|
||||||
protocol_version = "HTTP/1.1"
|
protocol_version = "HTTP/1.1"
|
||||||
|
@ -747,7 +743,6 @@ def make_request_and_skipIf(condition, reason):
|
||||||
return make_request_and_skip
|
return make_request_and_skip
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class BaseServerTestCase(unittest.TestCase):
|
class BaseServerTestCase(unittest.TestCase):
|
||||||
requestHandler = None
|
requestHandler = None
|
||||||
request_count = 1
|
request_count = 1
|
||||||
|
@ -1206,7 +1201,6 @@ class FailingMessageClass(http.client.HTTPMessage):
|
||||||
return super().get(key, failobj)
|
return super().get(key, failobj)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
|
||||||
class FailingServerTestCase(unittest.TestCase):
|
class FailingServerTestCase(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.evt = threading.Event()
|
self.evt = threading.Event()
|
||||||
|
|
|
@ -990,38 +990,12 @@ class Thread:
|
||||||
|
|
||||||
def _delete(self):
|
def _delete(self):
|
||||||
"Remove current thread from the dict of currently running threads."
|
"Remove current thread from the dict of currently running threads."
|
||||||
|
with _active_limbo_lock:
|
||||||
# Notes about running with _dummy_thread:
|
del _active[get_ident()]
|
||||||
#
|
# There must not be any python code between the previous line
|
||||||
# Must take care to not raise an exception if _dummy_thread is being
|
# and after the lock is released. Otherwise a tracing function
|
||||||
# used (and thus this module is being used as an instance of
|
# could try to acquire the lock again in the same thread, (in
|
||||||
# dummy_threading). _dummy_thread.get_ident() always returns 1 since
|
# current_thread()), and would block.
|
||||||
# there is only one thread if _dummy_thread is being used. Thus
|
|
||||||
# len(_active) is always <= 1 here, and any Thread instance created
|
|
||||||
# overwrites the (if any) thread currently registered in _active.
|
|
||||||
#
|
|
||||||
# An instance of _MainThread is always created by 'threading'. This
|
|
||||||
# gets overwritten the instant an instance of Thread is created; both
|
|
||||||
# threads return 1 from _dummy_thread.get_ident() and thus have the
|
|
||||||
# same key in the dict. So when the _MainThread instance created by
|
|
||||||
# 'threading' tries to clean itself up when atexit calls this method
|
|
||||||
# it gets a KeyError if another Thread instance was created.
|
|
||||||
#
|
|
||||||
# This all means that KeyError from trying to delete something from
|
|
||||||
# _active if dummy_threading is being used is a red herring. But
|
|
||||||
# since it isn't if dummy_threading is *not* being used then don't
|
|
||||||
# hide the exception.
|
|
||||||
|
|
||||||
try:
|
|
||||||
with _active_limbo_lock:
|
|
||||||
del _active[get_ident()]
|
|
||||||
# There must not be any python code between the previous line
|
|
||||||
# and after the lock is released. Otherwise a tracing function
|
|
||||||
# could try to acquire the lock again in the same thread, (in
|
|
||||||
# current_thread()), and would block.
|
|
||||||
except KeyError:
|
|
||||||
if 'dummy_threading' not in _sys.modules:
|
|
||||||
raise
|
|
||||||
|
|
||||||
def join(self, timeout=None):
|
def join(self, timeout=None):
|
||||||
"""Wait until the thread terminates.
|
"""Wait until the thread terminates.
|
||||||
|
|
20
Lib/trace.py
20
Lib/trace.py
|
@ -61,21 +61,15 @@ import dis
|
||||||
import pickle
|
import pickle
|
||||||
from time import monotonic as _time
|
from time import monotonic as _time
|
||||||
|
|
||||||
try:
|
import threading
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
_settrace = sys.settrace
|
|
||||||
|
|
||||||
def _unsettrace():
|
def _settrace(func):
|
||||||
sys.settrace(None)
|
threading.settrace(func)
|
||||||
else:
|
sys.settrace(func)
|
||||||
def _settrace(func):
|
|
||||||
threading.settrace(func)
|
|
||||||
sys.settrace(func)
|
|
||||||
|
|
||||||
def _unsettrace():
|
def _unsettrace():
|
||||||
sys.settrace(None)
|
sys.settrace(None)
|
||||||
threading.settrace(None)
|
threading.settrace(None)
|
||||||
|
|
||||||
PRAGMA_NOCOVER = "#pragma NO COVER"
|
PRAGMA_NOCOVER = "#pragma NO COVER"
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,7 @@ import stat
|
||||||
import shutil
|
import shutil
|
||||||
import struct
|
import struct
|
||||||
import binascii
|
import binascii
|
||||||
|
import threading
|
||||||
try:
|
|
||||||
import threading
|
|
||||||
except ImportError:
|
|
||||||
import dummy_threading as threading
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import zlib # We may need its compression method
|
import zlib # We may need its compression method
|
||||||
|
|
|
@ -220,7 +220,6 @@ LIBC= @LIBC@
|
||||||
SYSLIBS= $(LIBM) $(LIBC)
|
SYSLIBS= $(LIBM) $(LIBC)
|
||||||
SHLIBS= @SHLIBS@
|
SHLIBS= @SHLIBS@
|
||||||
|
|
||||||
THREADOBJ= @THREADOBJ@
|
|
||||||
DLINCLDIR= @DLINCLDIR@
|
DLINCLDIR= @DLINCLDIR@
|
||||||
DYNLOADFILE= @DYNLOADFILE@
|
DYNLOADFILE= @DYNLOADFILE@
|
||||||
MACHDEP_OBJS= @MACHDEP_OBJS@
|
MACHDEP_OBJS= @MACHDEP_OBJS@
|
||||||
|
@ -354,6 +353,7 @@ PYTHON_OBJS= \
|
||||||
Python/structmember.o \
|
Python/structmember.o \
|
||||||
Python/symtable.o \
|
Python/symtable.o \
|
||||||
Python/sysmodule.o \
|
Python/sysmodule.o \
|
||||||
|
Python/thread.o \
|
||||||
Python/traceback.o \
|
Python/traceback.o \
|
||||||
Python/getopt.o \
|
Python/getopt.o \
|
||||||
Python/pystrcmp.o \
|
Python/pystrcmp.o \
|
||||||
|
@ -365,7 +365,6 @@ PYTHON_OBJS= \
|
||||||
Python/$(DYNLOADFILE) \
|
Python/$(DYNLOADFILE) \
|
||||||
$(LIBOBJS) \
|
$(LIBOBJS) \
|
||||||
$(MACHDEP_OBJS) \
|
$(MACHDEP_OBJS) \
|
||||||
$(THREADOBJ) \
|
|
||||||
$(DTRACE_OBJS)
|
$(DTRACE_OBJS)
|
||||||
|
|
||||||
|
|
||||||
|
@ -655,12 +654,10 @@ oldsharedmods: $(SHAREDMODS)
|
||||||
Makefile Modules/config.c: Makefile.pre \
|
Makefile Modules/config.c: Makefile.pre \
|
||||||
$(srcdir)/Modules/config.c.in \
|
$(srcdir)/Modules/config.c.in \
|
||||||
$(MAKESETUP) \
|
$(MAKESETUP) \
|
||||||
Modules/Setup.config \
|
|
||||||
Modules/Setup \
|
Modules/Setup \
|
||||||
Modules/Setup.local
|
Modules/Setup.local
|
||||||
$(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
|
$(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \
|
||||||
-s Modules \
|
-s Modules \
|
||||||
Modules/Setup.config \
|
|
||||||
Modules/Setup.local \
|
Modules/Setup.local \
|
||||||
Modules/Setup
|
Modules/Setup
|
||||||
@mv config.c Modules
|
@mv config.c Modules
|
||||||
|
@ -1421,7 +1418,6 @@ libainstall: @DEF_MAKE_RULE@ python-config
|
||||||
$(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile
|
$(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile
|
||||||
$(INSTALL_DATA) Modules/Setup $(DESTDIR)$(LIBPL)/Setup
|
$(INSTALL_DATA) Modules/Setup $(DESTDIR)$(LIBPL)/Setup
|
||||||
$(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local
|
$(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local
|
||||||
$(INSTALL_DATA) Modules/Setup.config $(DESTDIR)$(LIBPL)/Setup.config
|
|
||||||
$(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(VERSION).pc
|
$(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(VERSION).pc
|
||||||
$(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup
|
$(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup
|
||||||
$(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh
|
$(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh
|
||||||
|
@ -1642,7 +1638,7 @@ distclean: clobber
|
||||||
if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \
|
if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \
|
||||||
done
|
done
|
||||||
-rm -f core Makefile Makefile.pre config.status \
|
-rm -f core Makefile Makefile.pre config.status \
|
||||||
Modules/Setup Modules/Setup.local Modules/Setup.config \
|
Modules/Setup Modules/Setup.local \
|
||||||
Modules/ld_so_aix Modules/python.exp Misc/python.pc \
|
Modules/ld_so_aix Modules/python.exp Misc/python.pc \
|
||||||
Misc/python-config.sh
|
Misc/python-config.sh
|
||||||
-rm -f python*-gdb.py
|
-rm -f python*-gdb.py
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Remove support for building --without-threads.
|
||||||
|
|
||||||
|
This option is not really useful anymore in the 21st century. Removing lots
|
||||||
|
of conditional paths allows us to simplify the code base, including in
|
||||||
|
difficult to maintain low-level internal code.
|
|
@ -1,10 +0,0 @@
|
||||||
# This file is transmogrified into Setup.config by config.status.
|
|
||||||
|
|
||||||
# The purpose of this file is to conditionally enable certain modules
|
|
||||||
# based on configure-time options.
|
|
||||||
|
|
||||||
# Threading
|
|
||||||
@USE_THREAD_MODULE@_thread _threadmodule.c
|
|
||||||
|
|
||||||
# The rest of the modules previously listed in this file are built
|
|
||||||
# by the setup.py script in Python 2.1 and later.
|
|
|
@ -123,6 +123,7 @@ atexit atexitmodule.c # Register functions to be run at interpreter-shutdow
|
||||||
_signal signalmodule.c
|
_signal signalmodule.c
|
||||||
_stat _stat.c # stat.h interface
|
_stat _stat.c # stat.h interface
|
||||||
time timemodule.c # -lm # time operations and variables
|
time timemodule.c # -lm # time operations and variables
|
||||||
|
_thread _threadmodule.c # low-level threading interface
|
||||||
|
|
||||||
# access to ISO C locale support
|
# access to ISO C locale support
|
||||||
_locale _localemodule.c # -lintl
|
_locale _localemodule.c # -lintl
|
||||||
|
@ -216,8 +217,6 @@ _symtable symtablemodule.c
|
||||||
|
|
||||||
# The crypt module is now disabled by default because it breaks builds
|
# The crypt module is now disabled by default because it breaks builds
|
||||||
# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
|
# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
|
||||||
#
|
|
||||||
# First, look at Setup.config; configure may have set this for you.
|
|
||||||
|
|
||||||
#_crypt _cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
|
#_crypt _cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
|
||||||
|
|
||||||
|
@ -308,8 +307,6 @@ _symtable symtablemodule.c
|
||||||
# Curses support, requiring the System V version of curses, often
|
# Curses support, requiring the System V version of curses, often
|
||||||
# provided by the ncurses library. e.g. on Linux, link with -lncurses
|
# provided by the ncurses library. e.g. on Linux, link with -lncurses
|
||||||
# instead of -lcurses).
|
# instead of -lcurses).
|
||||||
#
|
|
||||||
# First, look at Setup.config; configure may have set this for you.
|
|
||||||
|
|
||||||
#_curses _cursesmodule.c -lcurses -ltermcap
|
#_curses _cursesmodule.c -lcurses -ltermcap
|
||||||
# Wrapper for the panel library that's part of ncurses and SYSV curses.
|
# Wrapper for the panel library that's part of ncurses and SYSV curses.
|
||||||
|
@ -323,18 +320,9 @@ _symtable symtablemodule.c
|
||||||
# implementation independent wrapper for these; dbm/dumb.py provides
|
# implementation independent wrapper for these; dbm/dumb.py provides
|
||||||
# similar functionality (but slower of course) implemented in Python.
|
# similar functionality (but slower of course) implemented in Python.
|
||||||
|
|
||||||
# The standard Unix dbm module has been moved to Setup.config so that
|
|
||||||
# it will be compiled as a shared library by default. Compiling it as
|
|
||||||
# a built-in module causes conflicts with the pybsddb3 module since it
|
|
||||||
# creates a static dependency on an out-of-date version of db.so.
|
|
||||||
#
|
|
||||||
# First, look at Setup.config; configure may have set this for you.
|
|
||||||
|
|
||||||
#_dbm _dbmmodule.c # dbm(3) may require -lndbm or similar
|
#_dbm _dbmmodule.c # dbm(3) may require -lndbm or similar
|
||||||
|
|
||||||
# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
|
# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
|
||||||
#
|
|
||||||
# First, look at Setup.config; configure may have set this for you.
|
|
||||||
|
|
||||||
#_gdbm _gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
|
#_gdbm _gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pystrhex.h"
|
#include "pystrhex.h"
|
||||||
#ifdef WITH_THREAD
|
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../hashlib.h"
|
#include "../hashlib.h"
|
||||||
#include "blake2ns.h"
|
#include "blake2ns.h"
|
||||||
|
@ -41,9 +39,7 @@ typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
blake2b_param param;
|
blake2b_param param;
|
||||||
blake2b_state state;
|
blake2b_state state;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_type_lock lock;
|
PyThread_type_lock lock;
|
||||||
#endif
|
|
||||||
} BLAKE2bObject;
|
} BLAKE2bObject;
|
||||||
|
|
||||||
#include "clinic/blake2b_impl.c.h"
|
#include "clinic/blake2b_impl.c.h"
|
||||||
|
@ -60,11 +56,9 @@ new_BLAKE2bObject(PyTypeObject *type)
|
||||||
{
|
{
|
||||||
BLAKE2bObject *self;
|
BLAKE2bObject *self;
|
||||||
self = (BLAKE2bObject *)type->tp_alloc(type, 0);
|
self = (BLAKE2bObject *)type->tp_alloc(type, 0);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
self->lock = NULL;
|
self->lock = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +286,6 @@ _blake2b_blake2b_update(BLAKE2bObject *self, PyObject *obj)
|
||||||
|
|
||||||
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
|
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
|
if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
|
||||||
self->lock = PyThread_allocate_lock();
|
self->lock = PyThread_allocate_lock();
|
||||||
|
|
||||||
|
@ -305,9 +298,6 @@ _blake2b_blake2b_update(BLAKE2bObject *self, PyObject *obj)
|
||||||
} else {
|
} else {
|
||||||
blake2b_update(&self->state, buf.buf, buf.len);
|
blake2b_update(&self->state, buf.buf, buf.len);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
blake2b_update(&self->state, buf.buf, buf.len);
|
|
||||||
#endif /* !WITH_THREAD */
|
|
||||||
PyBuffer_Release(&buf);
|
PyBuffer_Release(&buf);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -407,12 +397,10 @@ py_blake2b_dealloc(PyObject *self)
|
||||||
/* Try not to leave state in memory. */
|
/* Try not to leave state in memory. */
|
||||||
secure_zero_memory(&obj->param, sizeof(obj->param));
|
secure_zero_memory(&obj->param, sizeof(obj->param));
|
||||||
secure_zero_memory(&obj->state, sizeof(obj->state));
|
secure_zero_memory(&obj->state, sizeof(obj->state));
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (obj->lock) {
|
if (obj->lock) {
|
||||||
PyThread_free_lock(obj->lock);
|
PyThread_free_lock(obj->lock);
|
||||||
obj->lock = NULL;
|
obj->lock = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
PyObject_Del(self);
|
PyObject_Del(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pystrhex.h"
|
#include "pystrhex.h"
|
||||||
#ifdef WITH_THREAD
|
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../hashlib.h"
|
#include "../hashlib.h"
|
||||||
#include "blake2ns.h"
|
#include "blake2ns.h"
|
||||||
|
@ -41,9 +39,7 @@ typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
blake2s_param param;
|
blake2s_param param;
|
||||||
blake2s_state state;
|
blake2s_state state;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_type_lock lock;
|
PyThread_type_lock lock;
|
||||||
#endif
|
|
||||||
} BLAKE2sObject;
|
} BLAKE2sObject;
|
||||||
|
|
||||||
#include "clinic/blake2s_impl.c.h"
|
#include "clinic/blake2s_impl.c.h"
|
||||||
|
@ -60,11 +56,9 @@ new_BLAKE2sObject(PyTypeObject *type)
|
||||||
{
|
{
|
||||||
BLAKE2sObject *self;
|
BLAKE2sObject *self;
|
||||||
self = (BLAKE2sObject *)type->tp_alloc(type, 0);
|
self = (BLAKE2sObject *)type->tp_alloc(type, 0);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
self->lock = NULL;
|
self->lock = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +286,6 @@ _blake2s_blake2s_update(BLAKE2sObject *self, PyObject *obj)
|
||||||
|
|
||||||
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
|
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
|
if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
|
||||||
self->lock = PyThread_allocate_lock();
|
self->lock = PyThread_allocate_lock();
|
||||||
|
|
||||||
|
@ -305,9 +298,6 @@ _blake2s_blake2s_update(BLAKE2sObject *self, PyObject *obj)
|
||||||
} else {
|
} else {
|
||||||
blake2s_update(&self->state, buf.buf, buf.len);
|
blake2s_update(&self->state, buf.buf, buf.len);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
blake2s_update(&self->state, buf.buf, buf.len);
|
|
||||||
#endif /* !WITH_THREAD */
|
|
||||||
PyBuffer_Release(&buf);
|
PyBuffer_Release(&buf);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -407,12 +397,10 @@ py_blake2s_dealloc(PyObject *self)
|
||||||
/* Try not to leave state in memory. */
|
/* Try not to leave state in memory. */
|
||||||
secure_zero_memory(&obj->param, sizeof(obj->param));
|
secure_zero_memory(&obj->param, sizeof(obj->param));
|
||||||
secure_zero_memory(&obj->state, sizeof(obj->state));
|
secure_zero_memory(&obj->state, sizeof(obj->state));
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (obj->lock) {
|
if (obj->lock) {
|
||||||
PyThread_free_lock(obj->lock);
|
PyThread_free_lock(obj->lock);
|
||||||
obj->lock = NULL;
|
obj->lock = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
PyObject_Del(self);
|
PyObject_Del(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <bzlib.h>
|
#include <bzlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -23,7 +21,6 @@
|
||||||
#endif /* ! BZ_CONFIG_ERROR */
|
#endif /* ! BZ_CONFIG_ERROR */
|
||||||
|
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
#define ACQUIRE_LOCK(obj) do { \
|
#define ACQUIRE_LOCK(obj) do { \
|
||||||
if (!PyThread_acquire_lock((obj)->lock, 0)) { \
|
if (!PyThread_acquire_lock((obj)->lock, 0)) { \
|
||||||
Py_BEGIN_ALLOW_THREADS \
|
Py_BEGIN_ALLOW_THREADS \
|
||||||
|
@ -31,19 +28,13 @@
|
||||||
Py_END_ALLOW_THREADS \
|
Py_END_ALLOW_THREADS \
|
||||||
} } while (0)
|
} } while (0)
|
||||||
#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock)
|
#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock)
|
||||||
#else
|
|
||||||
#define ACQUIRE_LOCK(obj)
|
|
||||||
#define RELEASE_LOCK(obj)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
bz_stream bzs;
|
bz_stream bzs;
|
||||||
int flushed;
|
int flushed;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_type_lock lock;
|
PyThread_type_lock lock;
|
||||||
#endif
|
|
||||||
} BZ2Compressor;
|
} BZ2Compressor;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -59,9 +50,7 @@ typedef struct {
|
||||||
separately. Conversion and looping is encapsulated in
|
separately. Conversion and looping is encapsulated in
|
||||||
decompress_buf() */
|
decompress_buf() */
|
||||||
size_t bzs_avail_in_real;
|
size_t bzs_avail_in_real;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_type_lock lock;
|
PyThread_type_lock lock;
|
||||||
#endif
|
|
||||||
} BZ2Decompressor;
|
} BZ2Decompressor;
|
||||||
|
|
||||||
static PyTypeObject BZ2Compressor_Type;
|
static PyTypeObject BZ2Compressor_Type;
|
||||||
|
@ -325,13 +314,11 @@ _bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
self->lock = PyThread_allocate_lock();
|
self->lock = PyThread_allocate_lock();
|
||||||
if (self->lock == NULL) {
|
if (self->lock == NULL) {
|
||||||
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
|
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
self->bzs.opaque = NULL;
|
self->bzs.opaque = NULL;
|
||||||
self->bzs.bzalloc = BZ2_Malloc;
|
self->bzs.bzalloc = BZ2_Malloc;
|
||||||
|
@ -343,10 +330,8 @@ _bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
self->lock = NULL;
|
self->lock = NULL;
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,10 +339,8 @@ static void
|
||||||
BZ2Compressor_dealloc(BZ2Compressor *self)
|
BZ2Compressor_dealloc(BZ2Compressor *self)
|
||||||
{
|
{
|
||||||
BZ2_bzCompressEnd(&self->bzs);
|
BZ2_bzCompressEnd(&self->bzs);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock != NULL)
|
if (self->lock != NULL)
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
#endif
|
|
||||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,13 +634,11 @@ _bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self)
|
||||||
{
|
{
|
||||||
int bzerror;
|
int bzerror;
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
self->lock = PyThread_allocate_lock();
|
self->lock = PyThread_allocate_lock();
|
||||||
if (self->lock == NULL) {
|
if (self->lock == NULL) {
|
||||||
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
|
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
self->needs_input = 1;
|
self->needs_input = 1;
|
||||||
self->bzs_avail_in_real = 0;
|
self->bzs_avail_in_real = 0;
|
||||||
|
@ -675,10 +656,8 @@ _bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
Py_CLEAR(self->unused_data);
|
Py_CLEAR(self->unused_data);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
self->lock = NULL;
|
self->lock = NULL;
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,10 +668,8 @@ BZ2Decompressor_dealloc(BZ2Decompressor *self)
|
||||||
PyMem_Free(self->input_buffer);
|
PyMem_Free(self->input_buffer);
|
||||||
BZ2_bzDecompressEnd(&self->bzs);
|
BZ2_bzDecompressEnd(&self->bzs);
|
||||||
Py_CLEAR(self->unused_data);
|
Py_CLEAR(self->unused_data);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock != NULL)
|
if (self->lock != NULL)
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
#endif
|
|
||||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5410,9 +5410,7 @@ PyInit__ctypes(void)
|
||||||
ob_type is the metatype (the 'type'), defaults to PyType_Type,
|
ob_type is the metatype (the 'type'), defaults to PyType_Type,
|
||||||
tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
|
tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
|
||||||
*/
|
*/
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
#endif
|
|
||||||
m = PyModule_Create(&_ctypesmodule);
|
m = PyModule_Create(&_ctypesmodule);
|
||||||
if (!m)
|
if (!m)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -137,9 +137,7 @@ static void _CallPythonObject(void *mem,
|
||||||
Py_ssize_t nArgs;
|
Py_ssize_t nArgs;
|
||||||
PyObject *error_object = NULL;
|
PyObject *error_object = NULL;
|
||||||
int *space;
|
int *space;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyGILState_STATE state = PyGILState_Ensure();
|
PyGILState_STATE state = PyGILState_Ensure();
|
||||||
#endif
|
|
||||||
|
|
||||||
nArgs = PySequence_Length(converters);
|
nArgs = PySequence_Length(converters);
|
||||||
/* Hm. What to return in case of error?
|
/* Hm. What to return in case of error?
|
||||||
|
@ -281,9 +279,7 @@ if (x == NULL) _PyTraceback_Add(what, "_ctypes/callbacks.c", __LINE__ - 1), PyEr
|
||||||
Py_XDECREF(result);
|
Py_XDECREF(result);
|
||||||
Done:
|
Done:
|
||||||
Py_XDECREF(arglist);
|
Py_XDECREF(arglist);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyGILState_Release(state);
|
PyGILState_Release(state);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void closure_fcn(ffi_cif *cif,
|
static void closure_fcn(ffi_cif *cif,
|
||||||
|
@ -347,7 +343,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
|
||||||
assert(CThunk_CheckExact((PyObject *)p));
|
assert(CThunk_CheckExact((PyObject *)p));
|
||||||
|
|
||||||
p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure),
|
p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure),
|
||||||
&p->pcl_exec);
|
&p->pcl_exec);
|
||||||
if (p->pcl_write == NULL) {
|
if (p->pcl_write == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -397,8 +393,8 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
|
||||||
result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p);
|
result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p);
|
||||||
#else
|
#else
|
||||||
result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
|
result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
|
||||||
p,
|
p,
|
||||||
p->pcl_exec);
|
p->pcl_exec);
|
||||||
#endif
|
#endif
|
||||||
if (result != FFI_OK) {
|
if (result != FFI_OK) {
|
||||||
PyErr_Format(PyExc_RuntimeError,
|
PyErr_Format(PyExc_RuntimeError,
|
||||||
|
@ -422,9 +418,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
|
||||||
static void LoadPython(void)
|
static void LoadPython(void)
|
||||||
{
|
{
|
||||||
if (!Py_IsInitialized()) {
|
if (!Py_IsInitialized()) {
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
#endif
|
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -495,18 +489,12 @@ STDAPI DllGetClassObject(REFCLSID rclsid,
|
||||||
LPVOID *ppv)
|
LPVOID *ppv)
|
||||||
{
|
{
|
||||||
long result;
|
long result;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyGILState_STATE state;
|
PyGILState_STATE state;
|
||||||
#endif
|
|
||||||
|
|
||||||
LoadPython();
|
LoadPython();
|
||||||
#ifdef WITH_THREAD
|
|
||||||
state = PyGILState_Ensure();
|
state = PyGILState_Ensure();
|
||||||
#endif
|
|
||||||
result = Call_GetClassObject(rclsid, riid, ppv);
|
result = Call_GetClassObject(rclsid, riid, ppv);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyGILState_Release(state);
|
PyGILState_Release(state);
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,13 +546,9 @@ long Call_CanUnloadNow(void)
|
||||||
STDAPI DllCanUnloadNow(void)
|
STDAPI DllCanUnloadNow(void)
|
||||||
{
|
{
|
||||||
long result;
|
long result;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyGILState_STATE state = PyGILState_Ensure();
|
PyGILState_STATE state = PyGILState_Ensure();
|
||||||
#endif
|
|
||||||
result = Call_CanUnloadNow();
|
result = Call_CanUnloadNow();
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyGILState_Release(state);
|
PyGILState_Release(state);
|
||||||
#endif
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -745,9 +745,7 @@ static int _call_function_pointer(int flags,
|
||||||
void *resmem,
|
void *resmem,
|
||||||
int argcount)
|
int argcount)
|
||||||
{
|
{
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
|
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
|
||||||
#endif
|
|
||||||
PyObject *error_object = NULL;
|
PyObject *error_object = NULL;
|
||||||
int *space;
|
int *space;
|
||||||
ffi_cif cif;
|
ffi_cif cif;
|
||||||
|
@ -786,10 +784,8 @@ static int _call_function_pointer(int flags,
|
||||||
if (error_object == NULL)
|
if (error_object == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
|
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
|
||||||
Py_UNBLOCK_THREADS
|
Py_UNBLOCK_THREADS
|
||||||
#endif
|
|
||||||
if (flags & FUNCFLAG_USE_ERRNO) {
|
if (flags & FUNCFLAG_USE_ERRNO) {
|
||||||
int temp = space[0];
|
int temp = space[0];
|
||||||
space[0] = errno;
|
space[0] = errno;
|
||||||
|
@ -826,10 +822,8 @@ static int _call_function_pointer(int flags,
|
||||||
space[0] = errno;
|
space[0] = errno;
|
||||||
errno = temp;
|
errno = temp;
|
||||||
}
|
}
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
|
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
|
||||||
Py_BLOCK_THREADS
|
Py_BLOCK_THREADS
|
||||||
#endif
|
|
||||||
Py_XDECREF(error_object);
|
Py_XDECREF(error_object);
|
||||||
#ifdef MS_WIN32
|
#ifdef MS_WIN32
|
||||||
#ifndef DONT_USE_SEH
|
#ifndef DONT_USE_SEH
|
||||||
|
@ -982,9 +976,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
|
||||||
/* We absolutely have to release the GIL during COM method calls,
|
/* We absolutely have to release the GIL during COM method calls,
|
||||||
otherwise we may get a deadlock!
|
otherwise we may get a deadlock!
|
||||||
*/
|
*/
|
||||||
#ifdef WITH_THREAD
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
#endif
|
|
||||||
|
|
||||||
hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei);
|
hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -1008,9 +1000,7 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
|
||||||
pei->lpVtbl->Release(pei);
|
pei->lpVtbl->Release(pei);
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
#ifdef WITH_THREAD
|
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
#endif
|
|
||||||
|
|
||||||
progid = NULL;
|
progid = NULL;
|
||||||
ProgIDFromCLSID(&guid, &progid);
|
ProgIDFromCLSID(&guid, &progid);
|
||||||
|
|
|
@ -53,9 +53,7 @@ typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
PyObject *name; /* name of this hash algorithm */
|
PyObject *name; /* name of this hash algorithm */
|
||||||
EVP_MD_CTX *ctx; /* OpenSSL message digest context */
|
EVP_MD_CTX *ctx; /* OpenSSL message digest context */
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_type_lock lock; /* OpenSSL context lock */
|
PyThread_type_lock lock; /* OpenSSL context lock */
|
||||||
#endif
|
|
||||||
} EVPobject;
|
} EVPobject;
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,9 +120,7 @@ newEVPobject(PyObject *name)
|
||||||
/* save the name for .name to return */
|
/* save the name for .name to return */
|
||||||
Py_INCREF(name);
|
Py_INCREF(name);
|
||||||
retval->name = name;
|
retval->name = name;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
retval->lock = NULL;
|
retval->lock = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -153,10 +149,8 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
|
||||||
static void
|
static void
|
||||||
EVP_dealloc(EVPobject *self)
|
EVP_dealloc(EVPobject *self)
|
||||||
{
|
{
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock != NULL)
|
if (self->lock != NULL)
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
#endif
|
|
||||||
EVP_MD_CTX_free(self->ctx);
|
EVP_MD_CTX_free(self->ctx);
|
||||||
Py_XDECREF(self->name);
|
Py_XDECREF(self->name);
|
||||||
PyObject_Del(self);
|
PyObject_Del(self);
|
||||||
|
@ -267,7 +261,6 @@ EVP_update(EVPobject *self, PyObject *args)
|
||||||
|
|
||||||
GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
|
GET_BUFFER_VIEW_OR_ERROUT(obj, &view);
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
|
if (self->lock == NULL && view.len >= HASHLIB_GIL_MINSIZE) {
|
||||||
self->lock = PyThread_allocate_lock();
|
self->lock = PyThread_allocate_lock();
|
||||||
/* fail? lock = NULL and we fail over to non-threaded code. */
|
/* fail? lock = NULL and we fail over to non-threaded code. */
|
||||||
|
@ -282,9 +275,6 @@ EVP_update(EVPobject *self, PyObject *args)
|
||||||
} else {
|
} else {
|
||||||
EVP_hash(self, view.buf, view.len);
|
EVP_hash(self, view.buf, view.len);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
EVP_hash(self, view.buf, view.len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyBuffer_Release(&view);
|
PyBuffer_Release(&view);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
|
|
@ -230,10 +230,8 @@ typedef struct {
|
||||||
isn't ready for writing. */
|
isn't ready for writing. */
|
||||||
Py_off_t write_end;
|
Py_off_t write_end;
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_type_lock lock;
|
PyThread_type_lock lock;
|
||||||
volatile unsigned long owner;
|
volatile unsigned long owner;
|
||||||
#endif
|
|
||||||
|
|
||||||
Py_ssize_t buffer_size;
|
Py_ssize_t buffer_size;
|
||||||
Py_ssize_t buffer_mask;
|
Py_ssize_t buffer_mask;
|
||||||
|
@ -267,8 +265,6 @@ typedef struct {
|
||||||
|
|
||||||
/* These macros protect the buffered object against concurrent operations. */
|
/* These macros protect the buffered object against concurrent operations. */
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_enter_buffered_busy(buffered *self)
|
_enter_buffered_busy(buffered *self)
|
||||||
{
|
{
|
||||||
|
@ -315,11 +311,6 @@ _enter_buffered_busy(buffered *self)
|
||||||
PyThread_release_lock(self->lock); \
|
PyThread_release_lock(self->lock); \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
#else
|
|
||||||
#define ENTER_BUFFERED(self) 1
|
|
||||||
#define LEAVE_BUFFERED(self)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CHECK_INITIALIZED(self) \
|
#define CHECK_INITIALIZED(self) \
|
||||||
if (self->ok <= 0) { \
|
if (self->ok <= 0) { \
|
||||||
if (self->detached) { \
|
if (self->detached) { \
|
||||||
|
@ -401,12 +392,10 @@ buffered_dealloc(buffered *self)
|
||||||
PyMem_Free(self->buffer);
|
PyMem_Free(self->buffer);
|
||||||
self->buffer = NULL;
|
self->buffer = NULL;
|
||||||
}
|
}
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock) {
|
if (self->lock) {
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
self->lock = NULL;
|
self->lock = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
Py_CLEAR(self->dict);
|
Py_CLEAR(self->dict);
|
||||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
}
|
}
|
||||||
|
@ -753,7 +742,6 @@ _buffered_init(buffered *self)
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock)
|
if (self->lock)
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
self->lock = PyThread_allocate_lock();
|
self->lock = PyThread_allocate_lock();
|
||||||
|
@ -762,7 +750,6 @@ _buffered_init(buffered *self)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
self->owner = 0;
|
self->owner = 0;
|
||||||
#endif
|
|
||||||
/* Find out whether buffer_size is a power of 2 */
|
/* Find out whether buffer_size is a power of 2 */
|
||||||
/* XXX is this optimization useful? */
|
/* XXX is this optimization useful? */
|
||||||
for (n = self->buffer_size - 1; n & 1; n >>= 1)
|
for (n = self->buffer_size - 1; n & 1; n >>= 1)
|
||||||
|
|
|
@ -9,16 +9,13 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
#ifdef WITH_THREAD
|
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <lzma.h>
|
#include <lzma.h>
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
#define ACQUIRE_LOCK(obj) do { \
|
#define ACQUIRE_LOCK(obj) do { \
|
||||||
if (!PyThread_acquire_lock((obj)->lock, 0)) { \
|
if (!PyThread_acquire_lock((obj)->lock, 0)) { \
|
||||||
Py_BEGIN_ALLOW_THREADS \
|
Py_BEGIN_ALLOW_THREADS \
|
||||||
|
@ -26,10 +23,6 @@
|
||||||
Py_END_ALLOW_THREADS \
|
Py_END_ALLOW_THREADS \
|
||||||
} } while (0)
|
} } while (0)
|
||||||
#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock)
|
#define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock)
|
||||||
#else
|
|
||||||
#define ACQUIRE_LOCK(obj)
|
|
||||||
#define RELEASE_LOCK(obj)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Container formats: */
|
/* Container formats: */
|
||||||
|
@ -48,9 +41,7 @@ typedef struct {
|
||||||
lzma_allocator alloc;
|
lzma_allocator alloc;
|
||||||
lzma_stream lzs;
|
lzma_stream lzs;
|
||||||
int flushed;
|
int flushed;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_type_lock lock;
|
PyThread_type_lock lock;
|
||||||
#endif
|
|
||||||
} Compressor;
|
} Compressor;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -63,9 +54,7 @@ typedef struct {
|
||||||
char needs_input;
|
char needs_input;
|
||||||
uint8_t *input_buffer;
|
uint8_t *input_buffer;
|
||||||
size_t input_buffer_size;
|
size_t input_buffer_size;
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_type_lock lock;
|
PyThread_type_lock lock;
|
||||||
#endif
|
|
||||||
} Decompressor;
|
} Decompressor;
|
||||||
|
|
||||||
/* LZMAError class object. */
|
/* LZMAError class object. */
|
||||||
|
@ -757,13 +746,11 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
|
||||||
self->alloc.free = PyLzma_Free;
|
self->alloc.free = PyLzma_Free;
|
||||||
self->lzs.allocator = &self->alloc;
|
self->lzs.allocator = &self->alloc;
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
self->lock = PyThread_allocate_lock();
|
self->lock = PyThread_allocate_lock();
|
||||||
if (self->lock == NULL) {
|
if (self->lock == NULL) {
|
||||||
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
|
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
self->flushed = 0;
|
self->flushed = 0;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
@ -790,10 +777,8 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
self->lock = NULL;
|
self->lock = NULL;
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,10 +786,8 @@ static void
|
||||||
Compressor_dealloc(Compressor *self)
|
Compressor_dealloc(Compressor *self)
|
||||||
{
|
{
|
||||||
lzma_end(&self->lzs);
|
lzma_end(&self->lzs);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock != NULL)
|
if (self->lock != NULL)
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
#endif
|
|
||||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1180,13 +1163,11 @@ _lzma_LZMADecompressor___init___impl(Decompressor *self, int format,
|
||||||
self->lzs.allocator = &self->alloc;
|
self->lzs.allocator = &self->alloc;
|
||||||
self->lzs.next_in = NULL;
|
self->lzs.next_in = NULL;
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
|
||||||
self->lock = PyThread_allocate_lock();
|
self->lock = PyThread_allocate_lock();
|
||||||
if (self->lock == NULL) {
|
if (self->lock == NULL) {
|
||||||
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
|
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
self->check = LZMA_CHECK_UNKNOWN;
|
self->check = LZMA_CHECK_UNKNOWN;
|
||||||
self->needs_input = 1;
|
self->needs_input = 1;
|
||||||
|
@ -1230,10 +1211,8 @@ _lzma_LZMADecompressor___init___impl(Decompressor *self, int format,
|
||||||
|
|
||||||
error:
|
error:
|
||||||
Py_CLEAR(self->unused_data);
|
Py_CLEAR(self->unused_data);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
self->lock = NULL;
|
self->lock = NULL;
|
||||||
#endif
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1245,10 +1224,8 @@ Decompressor_dealloc(Decompressor *self)
|
||||||
|
|
||||||
lzma_end(&self->lzs);
|
lzma_end(&self->lzs);
|
||||||
Py_CLEAR(self->unused_data);
|
Py_CLEAR(self->unused_data);
|
||||||
#ifdef WITH_THREAD
|
|
||||||
if (self->lock != NULL)
|
if (self->lock != NULL)
|
||||||
PyThread_free_lock(self->lock);
|
PyThread_free_lock(self->lock);
|
||||||
#endif
|
|
||||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue